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:
Cristian Le
2023-10-16 16:25:11 +02:00
parent 7144216f45
commit 704acca96b
26 changed files with 133 additions and 45 deletions

View 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.

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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,

View File

@@ -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

View File

@@ -1 +0,0 @@
message(STATUS "Included CMAKE_PROJECT_INCLUDE")

View File

@@ -1 +0,0 @@
message(STATUS "Included CMAKE_PROJECT_INCLUDE_BEFORE")

View File

@@ -0,0 +1 @@
message(STATUS "Included CMAKE_PROJECT_INCLUDE first file")

View File

@@ -0,0 +1 @@
message(STATUS "Included CMAKE_PROJECT_INCLUDE second file")

View File

@@ -0,0 +1 @@
message(STATUS "Included CMAKE_PROJECT_INCLUDE_BEFORE first file")

View File

@@ -0,0 +1 @@
message(STATUS "Included CMAKE_PROJECT_INCLUDE_BEFORE second file")

View File

@@ -1 +0,0 @@
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE")

View File

@@ -1 +0,0 @@
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE")

View File

@@ -0,0 +1 @@
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE first file")

View File

@@ -0,0 +1 @@
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE second file")

View File

@@ -0,0 +1 @@
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE first file")

View File

@@ -0,0 +1 @@
message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE second file")

View 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 ""
)

View 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 ""
)

View 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

View 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

View File

@@ -0,0 +1 @@
add_subdirectory(CodeInjection)

View File

@@ -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)