CMAKE_PROJECT_INCLUDE: Allow to run module files

Signed-off-by: Cristian Le <cristian.le@mpsd.mpg.de>
This commit is contained in:
Cristian Le
2023-10-16 21:16:51 +02:00
parent a3fbc255ff
commit b37b912e8f
12 changed files with 95 additions and 7 deletions

View File

@@ -6,4 +6,6 @@ project-include-multiple
: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.
CMake language files to be included sequentially. These variables can also
reference module names to be found in :variable:`CMAKE_MODULE_PATH` or
builtin to CMake.

View File

@@ -11,7 +11,8 @@ for a more detailed discussion of files potentially included during a
.. versionadded:: 3.29
This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
of CMake language files to be included sequentially.
of CMake language files to be included sequentially. It can also now refer to
module names to be found in :variable:`CMAKE_MODULE_PATH` or builtin to CMake.
See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,

View File

@@ -11,7 +11,8 @@ for a more detailed discussion of files potentially included during a
.. versionadded:: 3.29
This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
of CMake language files to be included sequentially.
of CMake language files to be included sequentially. It can also now refer to
module names to be found in :variable:`CMAKE_MODULE_PATH` or builtin to CMake.
See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,

View File

@@ -9,7 +9,8 @@ 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.
of CMake language files to be included sequentially. It can also now refer to
module names to be found in :variable:`CMAKE_MODULE_PATH` or builtin to CMake.
See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
:variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,

View File

@@ -11,7 +11,8 @@ 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.
of CMake language files to be included sequentially. It can also now refer to
module names to be found in :variable:`CMAKE_MODULE_PATH` or builtin to CMake.
See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
:variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,

View File

@@ -12,6 +12,10 @@ including things like :variable:`CMAKE_<LANG>_COMPILER`, might not be set.
See :ref:`Code Injection` for a more detailed discussion of files potentially
included during a :command:`project` call.
.. versionadded:: 3.29
This variable can also now refer to module names to be found in
:variable:`CMAKE_MODULE_PATH` or builtin to CMake.
This variable is intended for specifying files that perform one-time setup
for the build. It provides an injection point for things like configuring
package managers, adding logic the user shares between projects (e.g. defining

View File

@@ -694,7 +694,22 @@ void cmGlobalGenerator::EnableLanguage(
std::string includes =
mf->GetSafeDefinition("CMAKE_PROJECT_TOP_LEVEL_INCLUDES");
cmList includesList{ includes };
for (std::string const& setupFile : includesList) {
for (std::string setupFile : includesList) {
// Any relative path without a .cmake extension is checked for valid
// cmake modules. This logic should be consistent with CMake's include()
// command. Otherwise default to checking relative path w.r.t. source
// directory
if (!cmSystemTools::FileIsFullPath(setupFile) &&
!cmHasLiteralSuffix(setupFile, ".cmake")) {
std::string mfile = mf->GetModulesFile(cmStrCat(setupFile, ".cmake"));
if (mfile.empty()) {
cmSystemTools::Error(cmStrCat(
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES module:\n ", setupFile));
mf->GetState()->SetInTopLevelIncludes(false);
return;
}
setupFile = mfile;
}
std::string absSetupFile = cmSystemTools::CollapseFullPath(
setupFile, mf->GetCurrentSourceDirectory());
if (!cmSystemTools::FileExists(absSetupFile)) {

View File

@@ -375,7 +375,21 @@ static bool IncludeByVariable(cmExecutionStatus& status,
cmList includeFiles{ *include };
bool failed = false;
for (auto const& filePath : includeFiles) {
for (auto filePath : includeFiles) {
// Any relative path without a .cmake extension is checked for valid cmake
// modules. This logic should be consistent with CMake's include() command.
// Otherwise default to checking relative path w.r.t. source directory
if (!cmSystemTools::FileIsFullPath(filePath) &&
!cmHasLiteralSuffix(filePath, ".cmake")) {
std::string mfile = mf.GetModulesFile(cmStrCat(filePath, ".cmake"));
if (mfile.empty()) {
status.SetError(
cmStrCat("could not find requested module:\n ", filePath));
failed = true;
continue;
}
filePath = mfile;
}
std::string includeFile = cmSystemTools::CollapseFullPath(
filePath, mf.GetCurrentSourceDirectory());
if (!cmSystemTools::FileExists(includeFile)) {

View File

@@ -0,0 +1,28 @@
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}" CACHE STRING "")
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_project_includes_2"
CACHE STRING ""
)
set(CMAKE_PROJECT_INCLUDE_BEFORE
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_before_1.cmake"
"cmake_project_includes_before_2"
CACHE STRING ""
)
set(CMAKE_PROJECT_SubProj_INCLUDE
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_1.cmake"
"cmake_project_subproj_includes_2"
CACHE STRING ""
)
set(CMAKE_PROJECT_SubProj_INCLUDE_BEFORE
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_before_1.cmake"
"cmake_project_subproj_includes_before_2"
CACHE STRING ""
)
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
"${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_1.cmake"
"cmake_project_top_level_includes_2"
CACHE STRING ""
)

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

@@ -12,6 +12,10 @@ run_cmake_with_options(CodeInjection1
run_cmake_with_options(CodeInjection2
-C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache_2.cmake"
)
# This checks that module names are also allowed.
run_cmake_with_options(CodeInjection3
-C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache_3.cmake"
)
if(CMake_TEST_RESOURCES)
run_cmake(ExplicitRC)