mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-09 15:20:56 -06:00
CMAKE_PROJECT_INCLUDE: Add support for including multiple files
Fixes: #25341 Signed-off-by: Cristian Le <cristian.le@mpsd.mpg.de>
This commit is contained in:
9
Help/release/dev/project-include-multiple.rst
Normal file
9
Help/release/dev/project-include-multiple.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
project-include-multiple
|
||||
------------------------
|
||||
|
||||
* The :variable:`CMAKE_PROJECT_INCLUDE`,
|
||||
:variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
|
||||
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`, and
|
||||
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` variables learned
|
||||
to support a :ref:`semicolon-separated list <CMake Language Lists>` of
|
||||
CMake language files to be included sequentially.
|
||||
@@ -3,12 +3,16 @@ CMAKE_PROJECT_INCLUDE
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
A CMake language file or module to be included as the last step of all
|
||||
A CMake language file to be included as the last step of all
|
||||
:command:`project` command calls. This is intended for injecting custom code
|
||||
into project builds without modifying their source. See :ref:`Code Injection`
|
||||
for a more detailed discussion of files potentially included during a
|
||||
:command:`project` call.
|
||||
|
||||
.. versionadded:: 3.29
|
||||
This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
|
||||
of CMake language files to be included sequentially.
|
||||
|
||||
See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
|
||||
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
|
||||
:variable:`CMAKE_PROJECT_INCLUDE_BEFORE`, and
|
||||
|
||||
@@ -3,12 +3,16 @@ CMAKE_PROJECT_INCLUDE_BEFORE
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
A CMake language file or module to be included as the first step of all
|
||||
A CMake language file to be included as the first step of all
|
||||
:command:`project` command calls. This is intended for injecting custom code
|
||||
into project builds without modifying their source. See :ref:`Code Injection`
|
||||
for a more detailed discussion of files potentially included during a
|
||||
:command:`project` call.
|
||||
|
||||
.. versionadded:: 3.29
|
||||
This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
|
||||
of CMake language files to be included sequentially.
|
||||
|
||||
See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
|
||||
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
|
||||
:variable:`CMAKE_PROJECT_INCLUDE`, and
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE
|
||||
------------------------------------
|
||||
|
||||
A CMake language file or module to be included as the last step of any
|
||||
A CMake language file to be included as the last step of any
|
||||
:command:`project` command calls that specify ``<PROJECT-NAME>`` as the project
|
||||
name. This is intended for injecting custom code into project builds without
|
||||
modifying their source. See :ref:`Code Injection` for a more detailed
|
||||
discussion of files potentially included during a :command:`project` call.
|
||||
|
||||
.. versionadded:: 3.29
|
||||
This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
|
||||
of CMake language files to be included sequentially.
|
||||
|
||||
See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
|
||||
:variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
|
||||
and :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variables.
|
||||
|
||||
@@ -3,12 +3,16 @@ CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE
|
||||
|
||||
.. versionadded:: 3.17
|
||||
|
||||
A CMake language file or module to be included as the first step of any
|
||||
A CMake language file to be included as the first step of any
|
||||
:command:`project` command calls that specify ``<PROJECT-NAME>`` as the project
|
||||
name. This is intended for injecting custom code into project builds without
|
||||
modifying their source. See :ref:`Code Injection` for a more detailed
|
||||
discussion of files potentially included during a :command:`project` call.
|
||||
|
||||
.. versionadded:: 3.29
|
||||
This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
|
||||
of CMake language files to be included sequentially.
|
||||
|
||||
See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
|
||||
:variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
|
||||
and :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variables.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmList.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmPolicies.h"
|
||||
@@ -371,29 +372,41 @@ static bool IncludeByVariable(cmExecutionStatus& status,
|
||||
if (!include) {
|
||||
return true;
|
||||
}
|
||||
cmList includeFiles{ *include };
|
||||
|
||||
std::string includeFile =
|
||||
cmSystemTools::CollapseFullPath(*include, mf.GetCurrentSourceDirectory());
|
||||
if (!cmSystemTools::FileExists(includeFile)) {
|
||||
status.SetError(cmStrCat("could not find requested file:\n ", *include));
|
||||
return false;
|
||||
}
|
||||
if (cmSystemTools::FileIsDirectory(includeFile)) {
|
||||
status.SetError(cmStrCat("requested file is a directory:\n ", *include));
|
||||
return false;
|
||||
}
|
||||
bool failed = false;
|
||||
for (auto const& filePath : includeFiles) {
|
||||
std::string includeFile = cmSystemTools::CollapseFullPath(
|
||||
filePath, mf.GetCurrentSourceDirectory());
|
||||
if (!cmSystemTools::FileExists(includeFile)) {
|
||||
status.SetError(
|
||||
cmStrCat("could not find requested file:\n ", filePath));
|
||||
failed = true;
|
||||
continue;
|
||||
}
|
||||
if (cmSystemTools::FileIsDirectory(includeFile)) {
|
||||
status.SetError(
|
||||
cmStrCat("requested file is a directory:\n ", filePath));
|
||||
failed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool readit = mf.ReadDependentFile(*include);
|
||||
if (readit) {
|
||||
return true;
|
||||
}
|
||||
const bool readit = mf.ReadDependentFile(filePath);
|
||||
if (readit) {
|
||||
// If the included file ran successfully, continue to the next file
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cmSystemTools::GetFatalErrorOccurred()) {
|
||||
return true;
|
||||
}
|
||||
if (cmSystemTools::GetFatalErrorOccurred()) {
|
||||
failed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
status.SetError(cmStrCat("could not load requested file:\n ", *include));
|
||||
return false;
|
||||
status.SetError(cmStrCat("could not load requested file:\n ", filePath));
|
||||
failed = true;
|
||||
}
|
||||
// At this point all files were processed
|
||||
return !failed;
|
||||
}
|
||||
|
||||
static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name,
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE
|
||||
(-- )?Included CMAKE_TOOLCHAIN_FILE
|
||||
.*Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES first file
|
||||
(-- )?Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES second file
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE
|
||||
(-- )?Calling sub-project
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE
|
||||
(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE
|
||||
(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE
|
||||
@@ -1 +0,0 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_INCLUDE")
|
||||
@@ -1 +0,0 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_INCLUDE_BEFORE")
|
||||
@@ -0,0 +1 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_INCLUDE first file")
|
||||
@@ -0,0 +1 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_INCLUDE second file")
|
||||
@@ -0,0 +1 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_INCLUDE_BEFORE first file")
|
||||
@@ -0,0 +1 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_INCLUDE_BEFORE second file")
|
||||
@@ -1 +0,0 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE")
|
||||
@@ -1 +0,0 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE")
|
||||
@@ -0,0 +1 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE first file")
|
||||
@@ -0,0 +1 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE second file")
|
||||
@@ -0,0 +1 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE first file")
|
||||
@@ -0,0 +1 @@
|
||||
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE second file")
|
||||
@@ -1,10 +1,9 @@
|
||||
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/passthrough_toolchain_file.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_include.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_INCLUDE_BEFORE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_include_before.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_SubProj_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_include.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_SubProj_INCLUDE_BEFORE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_include_before.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_1.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_INCLUDE_BEFORE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_before_1.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_SubProj_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_1.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_SubProj_INCLUDE_BEFORE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_before_1.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_1.cmake"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_2.cmake"
|
||||
CACHE STRING ""
|
||||
CACHE FILEPATH ""
|
||||
)
|
||||
27
Tests/RunCMake/project/CodeInjection/initial_cache_2.cmake
Normal file
27
Tests/RunCMake/project/CodeInjection/initial_cache_2.cmake
Normal file
@@ -0,0 +1,27 @@
|
||||
set(CMAKE_TOOLCHAIN_FILE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/passthrough_toolchain_file.cmake" CACHE FILEPATH "")
|
||||
set(CMAKE_PROJECT_INCLUDE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_1.cmake"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_2.cmake"
|
||||
CACHE STRING ""
|
||||
)
|
||||
set(CMAKE_PROJECT_INCLUDE_BEFORE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_before_1.cmake"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_before_2.cmake"
|
||||
CACHE STRING ""
|
||||
)
|
||||
set(CMAKE_PROJECT_SubProj_INCLUDE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_1.cmake"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_2.cmake"
|
||||
CACHE STRING ""
|
||||
)
|
||||
set(CMAKE_PROJECT_SubProj_INCLUDE_BEFORE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_before_1.cmake"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_before_2.cmake"
|
||||
CACHE STRING ""
|
||||
)
|
||||
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_1.cmake"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_2.cmake"
|
||||
CACHE STRING ""
|
||||
)
|
||||
9
Tests/RunCMake/project/CodeInjection1-stdout.txt
Normal file
9
Tests/RunCMake/project/CodeInjection1-stdout.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
|
||||
(-- )?Included CMAKE_TOOLCHAIN_FILE
|
||||
.*Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES first file
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE first file
|
||||
(-- )?Calling sub-project
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
|
||||
(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE first file
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE first file
|
||||
(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE first file
|
||||
16
Tests/RunCMake/project/CodeInjection2-stdout.txt
Normal file
16
Tests/RunCMake/project/CodeInjection2-stdout.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE second file
|
||||
(-- )?Included CMAKE_TOOLCHAIN_FILE
|
||||
.*Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES first file
|
||||
(-- )?Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES second file
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE first file
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE second file
|
||||
(-- )?Calling sub-project
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE second file
|
||||
(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE first file
|
||||
(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE second file
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE first file
|
||||
(-- )?Included CMAKE_PROJECT_INCLUDE second file
|
||||
(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE first file
|
||||
(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE second file
|
||||
1
Tests/RunCMake/project/CodeInjection2.cmake
Normal file
1
Tests/RunCMake/project/CodeInjection2.cmake
Normal file
@@ -0,0 +1 @@
|
||||
add_subdirectory(CodeInjection)
|
||||
@@ -5,8 +5,12 @@ include(RunCMake)
|
||||
# which tests some of the individual variables one at a time.
|
||||
# Here, we are focused on testing that the variables are all injected
|
||||
# at the expected points in the expected order.
|
||||
run_cmake_with_options(CodeInjection
|
||||
-C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache.cmake"
|
||||
run_cmake_with_options(CodeInjection1
|
||||
-C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache_1.cmake"
|
||||
)
|
||||
# This checks that List variables are allowed.
|
||||
run_cmake_with_options(CodeInjection2
|
||||
-C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache_2.cmake"
|
||||
)
|
||||
|
||||
if(CMake_TEST_RESOURCES)
|
||||
|
||||
Reference in New Issue
Block a user