Merge branch 'backport-project-vars' into project-vars

This commit is contained in:
Brad King
2024-09-20 10:35:02 -04:00
7 changed files with 67 additions and 12 deletions

View File

@@ -44,6 +44,12 @@ Projects should not rely on ``<PROJECT-NAME>_SOURCE_DIR`` or
``<PROJECT-NAME>_BINARY_DIR`` holding a particular value outside of the scope
of the call to ``project()`` or one of its child scopes.
.. versionchanged:: 3.30.4
If the variables ``<PROJECT-NAME>_SOURCE_DIR``,
``<PROJECT-NAME>_BINARY_DIR``, or ``<PROJECT-NAME>_IS_TOP_LEVEL`` are
already set as non-cache variables when ``project(<PROJECT-NAME> ...)``
is called, the ``project()`` command will overwrite the previous values.
Options
^^^^^^^

View File

@@ -8,6 +8,8 @@
#include <limits>
#include <utility>
#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmExecutionStatus.h"
@@ -56,17 +58,21 @@ bool cmProjectCommand(std::vector<std::string> const& args,
mf.SetProjectName(projectName);
mf.AddCacheDefinition(projectName + "_BINARY_DIR",
mf.GetCurrentBinaryDirectory(),
std::string varName = cmStrCat(projectName, "_BINARY_DIR"_s);
bool nonCacheVarAlreadySet = mf.IsDefinitionSet(varName);
mf.AddCacheDefinition(varName, mf.GetCurrentBinaryDirectory(),
"Value Computed by CMake", cmStateEnums::STATIC);
mf.AddDefinition(projectName + "_BINARY_DIR",
mf.GetCurrentBinaryDirectory());
if (nonCacheVarAlreadySet) {
mf.AddDefinition(varName, mf.GetCurrentBinaryDirectory());
}
mf.AddCacheDefinition(projectName + "_SOURCE_DIR",
mf.GetCurrentSourceDirectory(),
varName = cmStrCat(projectName, "_SOURCE_DIR"_s);
nonCacheVarAlreadySet = mf.IsDefinitionSet(varName);
mf.AddCacheDefinition(varName, mf.GetCurrentSourceDirectory(),
"Value Computed by CMake", cmStateEnums::STATIC);
mf.AddDefinition(projectName + "_SOURCE_DIR",
mf.GetCurrentSourceDirectory());
if (nonCacheVarAlreadySet) {
mf.AddDefinition(varName, mf.GetCurrentSourceDirectory());
}
mf.AddDefinition("PROJECT_BINARY_DIR", mf.GetCurrentBinaryDirectory());
mf.AddDefinition("PROJECT_SOURCE_DIR", mf.GetCurrentSourceDirectory());
@@ -74,11 +80,14 @@ bool cmProjectCommand(std::vector<std::string> const& args,
mf.AddDefinition("PROJECT_NAME", projectName);
mf.AddDefinitionBool("PROJECT_IS_TOP_LEVEL", mf.IsRootMakefile());
mf.AddCacheDefinition(projectName + "_IS_TOP_LEVEL",
mf.IsRootMakefile() ? "ON" : "OFF",
varName = cmStrCat(projectName, "_IS_TOP_LEVEL"_s);
nonCacheVarAlreadySet = mf.IsDefinitionSet(varName);
mf.AddCacheDefinition(varName, mf.IsRootMakefile() ? "ON" : "OFF",
"Value Computed by CMake", cmStateEnums::STATIC);
mf.AddDefinition(projectName + "_IS_TOP_LEVEL",
mf.IsRootMakefile() ? "ON" : "OFF");
if (nonCacheVarAlreadySet) {
mf.AddDefinition(varName, mf.IsRootMakefile() ? "ON" : "OFF");
}
// Set the CMAKE_PROJECT_NAME variable to be the highest-level
// project name in the tree. If there are two project commands

View File

@@ -45,6 +45,7 @@ run_cmake(ProjectIsTopLevel)
run_cmake(ProjectIsTopLevelMultiple)
run_cmake(ProjectIsTopLevelSubdirectory)
run_cmake(ProjectTwice)
run_cmake(SameProjectVarsSubdir)
run_cmake(VersionAndLanguagesEmpty)
run_cmake(VersionEmpty)
run_cmake(VersionInvalid)

View File

@@ -0,0 +1,9 @@
(-- )? SameProjectVarsSubdir_SOURCE_DIR = [^
]+/subdir1
SameProjectVarsSubdir_BINARY_DIR = [^
]+/subdir1
SameProjectVarsSubdir_IS_TOP_LEVEL = OFF
(-- )? sub2proj_SOURCE_DIR = [^
]+/subdir2
sub2proj_BINARY_DIR = [^
]+/subdir2

View File

@@ -0,0 +1,17 @@
add_subdirectory(subdir1)
# Simulate a situation that FetchContent_MakeAvailable() used to be able to
# create, but that should no longer be possible. If depname_SOURCE_DIR and
# depname_BINARY_DIR variables are defined as non-cache variables before the
# project(depname) call, those non-cache variables used to prevent project()
# from setting those variables itself due to CMP0126 (if set to NEW). This only
# showed up if the project(depname) call was not in the dependency's top level
# CMakeLists.txt file, but rather in a subdirectory (googletest is one example
# that used to do this). Since CMake 3.30.3, the dependency's project() call
# should set non-cache variables that will make the variable values visible
# and avoid any masking from variables set before the project() call. We want
# to verify this 3.30.3+ behavior here and in subdir2.
set(sub2proj_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(sub2proj_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(subdir2)

View File

@@ -0,0 +1 @@
project(${RunCMake_TEST} LANGUAGES NONE)

View File

@@ -0,0 +1,12 @@
message(STATUS
" ${RunCMake_TEST}_SOURCE_DIR = ${${RunCMake_TEST}_SOURCE_DIR}\n"
" ${RunCMake_TEST}_BINARY_DIR = ${${RunCMake_TEST}_BINARY_DIR}\n"
" ${RunCMake_TEST}_IS_TOP_LEVEL = ${${RunCMake_TEST}_IS_TOP_LEVEL}"
)
project(sub2proj LANGUAGES NONE)
message(STATUS
" sub2proj_SOURCE_DIR = ${sub2proj_SOURCE_DIR}\n"
" sub2proj_BINARY_DIR = ${sub2proj_BINARY_DIR}"
)