Explorar o código

CMAKE_PROJECT_INCLUDE: Allow to run module files

Signed-off-by: Cristian Le <[email protected]>
Cristian Le %!s(int64=2) %!d(string=hai) anos
pai
achega
b37b912e8f

+ 3 - 1
Help/release/dev/project-include-multiple.rst

@@ -6,4 +6,6 @@ project-include-multiple
   :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`, and
   :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`, and
   :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` variables learned
   :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` variables learned
   to support a :ref:`semicolon-separated list <CMake Language Lists>` of
   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.

+ 2 - 1
Help/variable/CMAKE_PROJECT_INCLUDE.rst

@@ -11,7 +11,8 @@ for a more detailed discussion of files potentially included during a
 
 
 .. versionadded:: 3.29
 .. versionadded:: 3.29
   This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
   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`,
 See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
 :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
 :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,

+ 2 - 1
Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst

@@ -11,7 +11,8 @@ for a more detailed discussion of files potentially included during a
 
 
 .. versionadded:: 3.29
 .. versionadded:: 3.29
   This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
   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`,
 See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
 :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
 :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,

+ 2 - 1
Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst

@@ -9,7 +9,8 @@ discussion of files potentially included during a :command:`project` call.
 
 
 .. versionadded:: 3.29
 .. versionadded:: 3.29
   This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
   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`,
 See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
 :variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
 :variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,

+ 2 - 1
Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst

@@ -11,7 +11,8 @@ discussion of files potentially included during a :command:`project` call.
 
 
 .. versionadded:: 3.29
 .. versionadded:: 3.29
   This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
   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`,
 See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
 :variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
 :variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,

+ 4 - 0
Help/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.rst

@@ -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
 See :ref:`Code Injection` for a more detailed discussion of files potentially
 included during a :command:`project` call.
 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
 This variable is intended for specifying files that perform one-time setup
 for the build. It provides an injection point for things like configuring
 for the build. It provides an injection point for things like configuring
 package managers, adding logic the user shares between projects (e.g. defining
 package managers, adding logic the user shares between projects (e.g. defining

+ 16 - 1
Source/cmGlobalGenerator.cxx

@@ -694,7 +694,22 @@ void cmGlobalGenerator::EnableLanguage(
     std::string includes =
     std::string includes =
       mf->GetSafeDefinition("CMAKE_PROJECT_TOP_LEVEL_INCLUDES");
       mf->GetSafeDefinition("CMAKE_PROJECT_TOP_LEVEL_INCLUDES");
     cmList includesList{ 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(
       std::string absSetupFile = cmSystemTools::CollapseFullPath(
         setupFile, mf->GetCurrentSourceDirectory());
         setupFile, mf->GetCurrentSourceDirectory());
       if (!cmSystemTools::FileExists(absSetupFile)) {
       if (!cmSystemTools::FileExists(absSetupFile)) {

+ 15 - 1
Source/cmProjectCommand.cxx

@@ -375,7 +375,21 @@ static bool IncludeByVariable(cmExecutionStatus& status,
   cmList includeFiles{ *include };
   cmList includeFiles{ *include };
 
 
   bool failed = false;
   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(
     std::string includeFile = cmSystemTools::CollapseFullPath(
       filePath, mf.GetCurrentSourceDirectory());
       filePath, mf.GetCurrentSourceDirectory());
     if (!cmSystemTools::FileExists(includeFile)) {
     if (!cmSystemTools::FileExists(includeFile)) {

+ 28 - 0
Tests/RunCMake/project/CodeInjection/initial_cache_3.cmake

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

+ 16 - 0
Tests/RunCMake/project/CodeInjection3-stdout.txt

@@ -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 - 0
Tests/RunCMake/project/CodeInjection3.cmake

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

+ 4 - 0
Tests/RunCMake/project/RunCMakeTest.cmake

@@ -12,6 +12,10 @@ run_cmake_with_options(CodeInjection1
 run_cmake_with_options(CodeInjection2
 run_cmake_with_options(CodeInjection2
         -C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache_2.cmake"
         -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)
 if(CMake_TEST_RESOURCES)
   run_cmake(ExplicitRC)
   run_cmake(ExplicitRC)