mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
project: Define variables indicating whether project is top level
Define `PROJECT_IS_TOP_LEVEL` and `<PROJECT-NAME>_IS_TOP_LEVEL`. The latter is a STATIC cache entry just like other `<PROJECT-NAME>_*` variables so that it is globally scoped. Issue: #20310 Fixes: #21961
This commit is contained in:
@@ -28,6 +28,11 @@ Also sets the variables:
|
|||||||
:variable:`PROJECT_BINARY_DIR`, :variable:`<PROJECT-NAME>_BINARY_DIR`
|
:variable:`PROJECT_BINARY_DIR`, :variable:`<PROJECT-NAME>_BINARY_DIR`
|
||||||
Absolute path to the binary directory for the project.
|
Absolute path to the binary directory for the project.
|
||||||
|
|
||||||
|
:variable:`PROJECT_IS_TOP_LEVEL`, :variable:`<PROJECT-NAME>_IS_TOP_LEVEL`
|
||||||
|
.. versionadded:: 3.21
|
||||||
|
|
||||||
|
Boolean value indicating whether the project is top-level.
|
||||||
|
|
||||||
Further variables are set by the optional arguments described in the following.
|
Further variables are set by the optional arguments described in the following.
|
||||||
If any of these arguments is not used, then the corresponding variables are
|
If any of these arguments is not used, then the corresponding variables are
|
||||||
set to the empty string.
|
set to the empty string.
|
||||||
|
@@ -130,6 +130,7 @@ Variables that Provide Information
|
|||||||
/variable/PROJECT-NAME_BINARY_DIR
|
/variable/PROJECT-NAME_BINARY_DIR
|
||||||
/variable/PROJECT-NAME_DESCRIPTION
|
/variable/PROJECT-NAME_DESCRIPTION
|
||||||
/variable/PROJECT-NAME_HOMEPAGE_URL
|
/variable/PROJECT-NAME_HOMEPAGE_URL
|
||||||
|
/variable/PROJECT-NAME_IS_TOP_LEVEL
|
||||||
/variable/PROJECT-NAME_SOURCE_DIR
|
/variable/PROJECT-NAME_SOURCE_DIR
|
||||||
/variable/PROJECT-NAME_VERSION
|
/variable/PROJECT-NAME_VERSION
|
||||||
/variable/PROJECT-NAME_VERSION_MAJOR
|
/variable/PROJECT-NAME_VERSION_MAJOR
|
||||||
@@ -139,6 +140,7 @@ Variables that Provide Information
|
|||||||
/variable/PROJECT_BINARY_DIR
|
/variable/PROJECT_BINARY_DIR
|
||||||
/variable/PROJECT_DESCRIPTION
|
/variable/PROJECT_DESCRIPTION
|
||||||
/variable/PROJECT_HOMEPAGE_URL
|
/variable/PROJECT_HOMEPAGE_URL
|
||||||
|
/variable/PROJECT_IS_TOP_LEVEL
|
||||||
/variable/PROJECT_NAME
|
/variable/PROJECT_NAME
|
||||||
/variable/PROJECT_SOURCE_DIR
|
/variable/PROJECT_SOURCE_DIR
|
||||||
/variable/PROJECT_VERSION
|
/variable/PROJECT_VERSION
|
||||||
|
6
Help/release/dev/project-is-top-level.rst
Normal file
6
Help/release/dev/project-is-top-level.rst
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
project-is-top-level
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* :command:`project` now sets variables :variable:`PROJECT_IS_TOP_LEVEL` and
|
||||||
|
:variable:`<PROJECT-NAME>_IS_TOP_LEVEL` to indicate whether it was called
|
||||||
|
in a top level ``CMakeLists.txt`` file.
|
11
Help/variable/PROJECT-NAME_IS_TOP_LEVEL.rst
Normal file
11
Help/variable/PROJECT-NAME_IS_TOP_LEVEL.rst
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<PROJECT-NAME>_IS_TOP_LEVEL
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
.. versionadded:: 3.21
|
||||||
|
|
||||||
|
A boolean variable indicating whether the named project was called in a top
|
||||||
|
level ``CMakeLists.txt`` file.
|
||||||
|
|
||||||
|
To obtain the value from the most recent call to :command:`project` in
|
||||||
|
the current directory scope or above, see the
|
||||||
|
:variable:`PROJECT_IS_TOP_LEVEL` variable.
|
21
Help/variable/PROJECT_IS_TOP_LEVEL.rst
Normal file
21
Help/variable/PROJECT_IS_TOP_LEVEL.rst
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
PROJECT_IS_TOP_LEVEL
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. versionadded:: 3.21
|
||||||
|
|
||||||
|
A boolean variable indicating whether :command:`project` was called in a top
|
||||||
|
level ``CMakeLists.txt`` file.
|
||||||
|
|
||||||
|
Some modules should only be included as part of the top level
|
||||||
|
``CMakeLists.txt`` file to not cause unintended side effects in the build
|
||||||
|
tree, and this variable can be used to conditionally execute such code. For
|
||||||
|
example, consider the :module:`CTest` module, which creates targets and
|
||||||
|
options:
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
project(MyProject)
|
||||||
|
...
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
include(CTest)
|
||||||
|
endif()
|
@@ -59,6 +59,11 @@ bool cmProjectCommand(std::vector<std::string> const& args,
|
|||||||
|
|
||||||
mf.AddDefinition("PROJECT_NAME", projectName);
|
mf.AddDefinition("PROJECT_NAME", projectName);
|
||||||
|
|
||||||
|
mf.AddDefinitionBool("PROJECT_IS_TOP_LEVEL", mf.IsRootMakefile());
|
||||||
|
mf.AddCacheDefinition(projectName + "_IS_TOP_LEVEL",
|
||||||
|
mf.IsRootMakefile() ? "ON" : "OFF",
|
||||||
|
"Value Computed by CMake", cmStateEnums::STATIC);
|
||||||
|
|
||||||
// Set the CMAKE_PROJECT_NAME variable to be the highest-level
|
// Set the CMAKE_PROJECT_NAME variable to be the highest-level
|
||||||
// project name in the tree. If there are two project commands
|
// project name in the tree. If there are two project commands
|
||||||
// in the same CMakeLists.txt file, and it is the top level
|
// in the same CMakeLists.txt file, and it is the top level
|
||||||
|
2
Tests/RunCMake/project/ProjectIsTopLevel-stdout.txt
Normal file
2
Tests/RunCMake/project/ProjectIsTopLevel-stdout.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-- PROJECT_IS_TOP_LEVEL=ON
|
||||||
|
-- ProjectIsTopLevel_IS_TOP_LEVEL=ON
|
9
Tests/RunCMake/project/ProjectIsTopLevel.cmake
Normal file
9
Tests/RunCMake/project/ProjectIsTopLevel.cmake
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# no project() call, includer already calls project(${RunCMake_TEST} NONE)
|
||||||
|
if(NOT DEFINED PROJECT_IS_TOP_LEVEL)
|
||||||
|
message(FATAL_ERROR "PROJECT_IS_TOP_LEVEL is not defined")
|
||||||
|
endif()
|
||||||
|
if(NOT DEFINED "CACHE{${RunCMake_TEST}_IS_TOP_LEVEL}")
|
||||||
|
message(FATAL_ERROR "IsTopLevel_IS_TOP_LEVEL is not defined")
|
||||||
|
endif()
|
||||||
|
message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}")
|
||||||
|
message(STATUS "${RunCMake_TEST}_IS_TOP_LEVEL=${${RunCMake_TEST}_IS_TOP_LEVEL}")
|
@@ -0,0 +1,3 @@
|
|||||||
|
-- PROJECT_IS_TOP_LEVEL=ON
|
||||||
|
-- ProjectIsTopLevelMultiple_IS_TOP_LEVEL=ON
|
||||||
|
-- IsTopLevel_IS_TOP_LEVEL=ON
|
14
Tests/RunCMake/project/ProjectIsTopLevelMultiple.cmake
Normal file
14
Tests/RunCMake/project/ProjectIsTopLevelMultiple.cmake
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# only one project() call, includer already calls project(${RunCMake_TEST} NONE)
|
||||||
|
project(IsTopLevel NONE)
|
||||||
|
if(NOT DEFINED PROJECT_IS_TOP_LEVEL)
|
||||||
|
message(FATAL_ERROR "PROJECT_IS_TOP_LEVEL is not defined")
|
||||||
|
endif()
|
||||||
|
if(NOT DEFINED "CACHE{${RunCMake_TEST}_IS_TOP_LEVEL}")
|
||||||
|
message(FATAL_ERROR "${RunCMake_TEST}_IS_TOP_LEVEL is not defined")
|
||||||
|
endif()
|
||||||
|
if(NOT DEFINED CACHE{IsTopLevel_IS_TOP_LEVEL})
|
||||||
|
message(FATAL_ERROR "IsTopLevel_IS_TOP_LEVEL is not defined")
|
||||||
|
endif()
|
||||||
|
message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}")
|
||||||
|
message(STATUS "${RunCMake_TEST}_IS_TOP_LEVEL=${${RunCMake_TEST}_IS_TOP_LEVEL}")
|
||||||
|
message(STATUS "IsTopLevel_IS_TOP_LEVEL=${IsTopLevel_IS_TOP_LEVEL}")
|
@@ -0,0 +1,6 @@
|
|||||||
|
-- PROJECT_IS_TOP_LEVEL=ON
|
||||||
|
-- PROJECT_IS_TOP_LEVEL=ON
|
||||||
|
-- PROJECT_IS_TOP_LEVEL=OFF
|
||||||
|
-- PROJECT_IS_TOP_LEVEL=ON
|
||||||
|
-- ProjectIsTopLevelSubdirectory_IS_TOP_LEVEL=ON
|
||||||
|
-- NotTopLevel_IS_TOP_LEVEL=OFF
|
@@ -0,0 +1,8 @@
|
|||||||
|
# no project() call, includer already calls project(${RunCMake_TEST} NONE)
|
||||||
|
message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}")
|
||||||
|
|
||||||
|
add_subdirectory(ProjectIsTopLevelSubdirectory)
|
||||||
|
|
||||||
|
message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}")
|
||||||
|
message(STATUS "${RunCMake_TEST}_IS_TOP_LEVEL=${${RunCMake_TEST}_IS_TOP_LEVEL}")
|
||||||
|
message(STATUS "NotTopLevel_IS_TOP_LEVEL=${NotTopLevel_IS_TOP_LEVEL}")
|
@@ -0,0 +1,5 @@
|
|||||||
|
message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}")
|
||||||
|
|
||||||
|
project(NotTopLevel NONE)
|
||||||
|
|
||||||
|
message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}")
|
@@ -15,6 +15,9 @@ run_cmake(ProjectDescriptionNoArg2)
|
|||||||
run_cmake(ProjectHomepage)
|
run_cmake(ProjectHomepage)
|
||||||
run_cmake(ProjectHomepage2)
|
run_cmake(ProjectHomepage2)
|
||||||
run_cmake(ProjectHomepageNoArg)
|
run_cmake(ProjectHomepageNoArg)
|
||||||
|
run_cmake(ProjectIsTopLevel)
|
||||||
|
run_cmake(ProjectIsTopLevelMultiple)
|
||||||
|
run_cmake(ProjectIsTopLevelSubdirectory)
|
||||||
run_cmake(ProjectTwice)
|
run_cmake(ProjectTwice)
|
||||||
run_cmake(VersionAndLanguagesEmpty)
|
run_cmake(VersionAndLanguagesEmpty)
|
||||||
run_cmake(VersionEmpty)
|
run_cmake(VersionEmpty)
|
||||||
|
Reference in New Issue
Block a user