Bladeren bron

add_subdirectory: Add SYSTEM option

Fixes: #22401
Signed-off-by: Da Quexian <[email protected]>
Da Quexian 3 jaren geleden
bovenliggende
commit
2eb30a7036
42 gewijzigde bestanden met toevoegingen van 199 en 18 verwijderingen
  1. 8 1
      Help/command/add_subdirectory.rst
  2. 1 0
      Help/manual/cmake-properties.7.rst
  3. 10 0
      Help/prop_dir/SYSTEM.rst
  4. 15 9
      Help/prop_tgt/SYSTEM.rst
  5. 10 0
      Help/release/dev/system.rst
  6. 17 2
      Modules/FetchContent.cmake
  7. 11 1
      Source/cmAddSubDirectoryCommand.cxx
  8. 5 1
      Source/cmMakefile.cxx
  9. 1 1
      Source/cmMakefile.h
  10. 2 2
      Source/cmSubdirCommand.cxx
  11. 1 1
      Source/cmTarget.cxx
  12. 2 0
      Tests/RunCMake/FetchContent/IncludesNonSystem/CMakeLists.txt
  13. 0 0
      Tests/RunCMake/FetchContent/IncludesNonSystem/bar.cpp
  14. 0 0
      Tests/RunCMake/FetchContent/IncludesNonSystem/foo.cpp
  15. 20 0
      Tests/RunCMake/FetchContent/IncludesSystem/CMakeLists.txt
  16. 6 0
      Tests/RunCMake/FetchContent/IncludesSystem/SubSub1/CMakeLists.txt
  17. 0 0
      Tests/RunCMake/FetchContent/IncludesSystem/SubSub1/bar.cpp
  18. 0 0
      Tests/RunCMake/FetchContent/IncludesSystem/SubSub1/foo.cpp
  19. 0 0
      Tests/RunCMake/FetchContent/IncludesSystem/SubSub1/zot.cpp
  20. 6 0
      Tests/RunCMake/FetchContent/IncludesSystem/SubSub2/CMakeLists.txt
  21. 0 0
      Tests/RunCMake/FetchContent/IncludesSystem/SubSub2/bar.cpp
  22. 0 0
      Tests/RunCMake/FetchContent/IncludesSystem/SubSub2/foo.cpp
  23. 0 0
      Tests/RunCMake/FetchContent/IncludesSystem/SubSub2/zot.cpp
  24. 0 0
      Tests/RunCMake/FetchContent/IncludesSystem/bar.cpp
  25. 0 0
      Tests/RunCMake/FetchContent/IncludesSystem/foo.cpp
  26. 0 0
      Tests/RunCMake/FetchContent/IncludesSystem/zot.cpp
  27. 1 0
      Tests/RunCMake/FetchContent/RunCMakeTest.cmake
  28. 37 0
      Tests/RunCMake/FetchContent/System.cmake
  29. 1 0
      Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake
  30. 22 0
      Tests/RunCMake/add_subdirectory/System.cmake
  31. 11 0
      Tests/RunCMake/add_subdirectory/System/CMakeLists.txt
  32. 6 0
      Tests/RunCMake/add_subdirectory/System/SubSub1/CMakeLists.txt
  33. 0 0
      Tests/RunCMake/add_subdirectory/System/SubSub1/bar.cpp
  34. 0 0
      Tests/RunCMake/add_subdirectory/System/SubSub1/foo.cpp
  35. 0 0
      Tests/RunCMake/add_subdirectory/System/SubSub1/zot.cpp
  36. 6 0
      Tests/RunCMake/add_subdirectory/System/SubSub2/CMakeLists.txt
  37. 0 0
      Tests/RunCMake/add_subdirectory/System/SubSub2/bar.cpp
  38. 0 0
      Tests/RunCMake/add_subdirectory/System/SubSub2/foo.cpp
  39. 0 0
      Tests/RunCMake/add_subdirectory/System/SubSub2/zot.cpp
  40. 0 0
      Tests/RunCMake/add_subdirectory/System/bar.cpp
  41. 0 0
      Tests/RunCMake/add_subdirectory/System/foo.cpp
  42. 0 0
      Tests/RunCMake/add_subdirectory/System/zot.cpp

+ 8 - 1
Help/command/add_subdirectory.rst

@@ -5,7 +5,7 @@ Add a subdirectory to the build.
 
 .. code-block:: cmake
 
-  add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
+  add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL] [SYSTEM])
 
 Adds a subdirectory to the build.  The source_dir specifies the
 directory in which the source CMakeLists.txt and code files are
@@ -33,3 +33,10 @@ dependencies supersede this exclusion.  If a target built by the
 parent project depends on a target in the subdirectory, the dependee
 target will be included in the parent project build system to satisfy
 the dependency.
+
+If the ``SYSTEM`` argument is provided, the :prop_dir:`SYSTEM` directory
+property of the subdirectory will be set to true.  This property is
+used to initialize the :prop_tgt:`SYSTEM` property of each target
+created in that subdirectory. The include directories of targets with
+:prop_tgt:`SYSTEM` set to true will be treated as ``SYSTEM`` when
+compiling consumers.

+ 1 - 0
Help/manual/cmake-properties.7.rst

@@ -90,6 +90,7 @@ Properties on Directories
    /prop_dir/RULE_LAUNCH_LINK
    /prop_dir/SOURCE_DIR
    /prop_dir/SUBDIRECTORIES
+   /prop_dir/SYSTEM
    /prop_dir/TESTS
    /prop_dir/TEST_INCLUDE_FILES
    /prop_dir/VARIABLES

+ 10 - 0
Help/prop_dir/SYSTEM.rst

@@ -0,0 +1,10 @@
+SYSTEM
+------
+
+.. versionadded:: 3.25
+
+This directory property is used to initialize the :prop_tgt:`SYSTEM`
+target property for targets created in that directory. It is set to
+true by :command:`add_subdirectory` and
+:command:`FetchContent_Declare` when the ``SYSTEM`` option is given
+as an argument to those commands.

+ 15 - 9
Help/prop_tgt/SYSTEM.rst

@@ -3,14 +3,20 @@ SYSTEM
 
 .. versionadded:: 3.25
 
-Specifies that a target is a ``SYSTEM`` library.  This has the following effects:
+Specifies that a target is a ``SYSTEM`` library.  This has the following
+effects:
 
-* Entries of :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` are treated as ``SYSTEM``
-  include directories when compiling consumers.
-  Entries of :prop_tgt:`INTERFACE_SYSTEM_INCLUDE_DIRECTORIES` are not affected,
-  and will always be treated as ``SYSTEM`` include directories.
+* Entries of :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` are treated as
+  ``SYSTEM`` include directories when compiling consumers.
+  Entries of :prop_tgt:`INTERFACE_SYSTEM_INCLUDE_DIRECTORIES` are not
+  affected, and will always be treated as ``SYSTEM`` include directories.
 
-For imported targets, this property has a default value `ON`, which means that their
-`INTERFACE_INCLUDE_DIRECTORIES` are treated as ``SYSTEM`` by default. If their
-`SYSTEM` property is `OFF`, then their `INTERFACE_INCLUDE_DIRECTORIES` will not be
-treated as ``SYSTEM``, regardless of the value of `IMPORTED_NO_SYSTEM` property.
+For imported targets, this property defaults to true, which means
+that their :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` are treated
+as ``SYSTEM`` by default. If their ``SYSTEM`` property is false,
+then their :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` will not be
+treated as ``SYSTEM``, regardless of the value of the
+:prop_tgt:`IMPORTED_NO_SYSTEM` property.
+
+This target property is initialized from the :prop_dir:`SYSTEM`
+directory property when the target is created.

+ 10 - 0
Help/release/dev/system.rst

@@ -6,6 +6,16 @@ system
   its include directories are automatically ``SYSTEM`` when
   compiling consumers).
 
+* The :prop_dir:`SYSTEM` directory property was added to initialize the
+  :prop_tgt:`SYSTEM` target property for targets created in that directory.
+
+* The :command:`add_subdirectory` command gained a ``SYSTEM`` option
+  to enable the :prop_dir:`SYSTEM` directory property in the subdirectory.
+
+* The :module:`FetchContent` module :command:`FetchContent_Declare`
+  command gained a ``SYSTEM`` option to enable the :prop_dir:`SYSTEM`
+  directory property in the subdirectory.
+
 * The :prop_tgt:`EXPORT_NO_SYSTEM` target property was added to
   specify that :command:`install(EXPORT)` and :command:`export`
   commands will generate a imported target with

+ 17 - 2
Modules/FetchContent.cmake

@@ -111,6 +111,7 @@ Commands
     FetchContent_Declare(
       <name>
       <contentOptions>...
+      [SYSTEM]
       [OVERRIDE_FIND_PACKAGE |
        FIND_PACKAGE_ARGS args...]
     )
@@ -229,6 +230,16 @@ Commands
       to intercept any direct call to :command:`find_package`, except if that
       call contains the ``BYPASS_PROVIDER`` option.
 
+  .. versionadded:: 3.25
+
+    ``SYSTEM``
+      If the ``SYSTEM`` argument is provided, targets created by
+      the dependency will have their :prop_tgt:`SYSTEM` property
+      set to true when populated by :command:`FetchContent_MakeAvailable`.
+      The entries in their  :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
+      will be treated as ``SYSTEM`` include directories when
+      compiling consumers.
+
 .. command:: FetchContent_MakeAvailable
 
   .. versionadded:: 3.14
@@ -1931,13 +1942,17 @@ macro(FetchContent_MakeAvailable)
       if("${__cmake_contentDetails}" STREQUAL "")
         message(FATAL_ERROR "No details have been set for content: ${__cmake_contentName}")
       endif()
-      cmake_parse_arguments(__cmake_arg "" "SOURCE_SUBDIR" "" ${__cmake_contentDetails})
+      cmake_parse_arguments(__cmake_arg "SYSTEM" "SOURCE_SUBDIR" "" ${__cmake_contentDetails})
       if(NOT "${__cmake_arg_SOURCE_SUBDIR}" STREQUAL "")
         string(APPEND __cmake_srcdir "/${__cmake_arg_SOURCE_SUBDIR}")
       endif()
 
       if(EXISTS ${__cmake_srcdir}/CMakeLists.txt)
-        add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR})
+        if (__cmake_arg_SYSTEM)
+          add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR} SYSTEM)
+        else()
+          add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR})
+        endif()
       endif()
 
       unset(__cmake_srcdir)

+ 11 - 1
Source/cmAddSubDirectoryCommand.cxx

@@ -26,6 +26,7 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
   std::string binArg;
 
   bool excludeFromAll = false;
+  bool system = false;
 
   // process the rest of the arguments looking for optional args
   for (std::string const& arg : cmMakeRange(args).advance(1)) {
@@ -33,6 +34,10 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
       excludeFromAll = true;
       continue;
     }
+    if (arg == "SYSTEM") {
+      system = true;
+      continue;
+    }
     if (binArg.empty()) {
       binArg = arg;
     } else {
@@ -40,6 +45,11 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
       return false;
     }
   }
+  // "SYSTEM" directory property should also affects targets in nested
+  // subdirectories.
+  if (mf.GetPropertyAsBool("SYSTEM")) {
+    system = true;
+  }
 
   // Compute the full path to the specified source directory.
   // Interpret a relative path with respect to the current source directory.
@@ -102,7 +112,7 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
   binPath = cmSystemTools::CollapseFullPath(binPath);
 
   // Add the subdirectory using the computed full paths.
-  mf.AddSubDirectory(srcPath, binPath, excludeFromAll, true);
+  mf.AddSubDirectory(srcPath, binPath, excludeFromAll, true, system);
 
   return true;
 }

+ 5 - 1
Source/cmMakefile.cxx

@@ -1759,7 +1759,8 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf)
 
 void cmMakefile::AddSubDirectory(const std::string& srcPath,
                                  const std::string& binPath,
-                                 bool excludeFromAll, bool immediate)
+                                 bool excludeFromAll, bool immediate,
+                                 bool system)
 {
   if (this->DeferRunning) {
     this->IssueMessage(
@@ -1789,6 +1790,9 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
   if (excludeFromAll) {
     subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
   }
+  if (system) {
+    subMf->SetProperty("SYSTEM", "TRUE");
+  }
 
   if (immediate) {
     this->ConfigureSubDirectory(subMf);

+ 1 - 1
Source/cmMakefile.h

@@ -270,7 +270,7 @@ public:
    */
   void AddSubDirectory(const std::string& fullSrcDir,
                        const std::string& fullBinDir, bool excludeFromAll,
-                       bool immediate);
+                       bool immediate, bool system);
 
   void Configure();
 

+ 2 - 2
Source/cmSubdirCommand.cxx

@@ -32,7 +32,7 @@ bool cmSubdirCommand(std::vector<std::string> const& args,
     std::string srcPath = mf.GetCurrentSourceDirectory() + "/" + i;
     if (cmSystemTools::FileIsDirectory(srcPath)) {
       std::string binPath = mf.GetCurrentBinaryDirectory() + "/" + i;
-      mf.AddSubDirectory(srcPath, binPath, excludeFromAll, false);
+      mf.AddSubDirectory(srcPath, binPath, excludeFromAll, false, false);
     }
     // otherwise it is a full path
     else if (cmSystemTools::FileIsDirectory(i)) {
@@ -40,7 +40,7 @@ bool cmSubdirCommand(std::vector<std::string> const& args,
       // element from the source path and use that
       std::string binPath = mf.GetCurrentBinaryDirectory() + "/" +
         cmSystemTools::GetFilenameName(i);
-      mf.AddSubDirectory(i, binPath, excludeFromAll, false);
+      mf.AddSubDirectory(i, binPath, excludeFromAll, false, false);
     } else {
       status.SetError(cmStrCat("Incorrect SUBDIRS command. Directory: ", i,
                                " does not exist."));

+ 1 - 1
Source/cmTarget.cxx

@@ -776,7 +776,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     }
   }
 
-  if (this->IsImported()) {
+  if (this->IsImported() || mf->GetPropertyAsBool("SYSTEM")) {
     this->SetProperty("SYSTEM", "ON");
   }
 

+ 2 - 0
Tests/RunCMake/FetchContent/IncludesNonSystem/CMakeLists.txt

@@ -0,0 +1,2 @@
+add_library(barnonsys STATIC bar.cpp)
+add_executable(foononsys foo.cpp)

+ 0 - 0
Tests/RunCMake/FetchContent/IncludesNonSystem/bar.cpp


+ 0 - 0
Tests/RunCMake/FetchContent/IncludesNonSystem/foo.cpp


+ 20 - 0
Tests/RunCMake/FetchContent/IncludesSystem/CMakeLists.txt

@@ -0,0 +1,20 @@
+project(SystemSub NONE)
+
+FetchContent_Declare(
+  SubSub1
+  SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/SubSub1
+  SYSTEM
+)
+FetchContent_Declare(
+  SubSub2
+  SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/SubSub2
+)
+
+FetchContent_MakeAvailable(SubSub1 SubSub2)
+
+add_library(bar STATIC bar.cpp)
+
+add_library(foo STATIC foo.cpp)
+set_target_properties(foo PROPERTIES SYSTEM OFF)
+
+add_executable(zot zot.cpp)

+ 6 - 0
Tests/RunCMake/FetchContent/IncludesSystem/SubSub1/CMakeLists.txt

@@ -0,0 +1,6 @@
+add_library(subsub1bar STATIC bar.cpp)
+
+add_library(subsub1foo STATIC foo.cpp)
+set_target_properties(subsub1foo PROPERTIES SYSTEM OFF)
+
+add_executable(subsub1zot zot.cpp)

+ 0 - 0
Tests/RunCMake/FetchContent/IncludesSystem/SubSub1/bar.cpp


+ 0 - 0
Tests/RunCMake/FetchContent/IncludesSystem/SubSub1/foo.cpp


+ 0 - 0
Tests/RunCMake/FetchContent/IncludesSystem/SubSub1/zot.cpp


+ 6 - 0
Tests/RunCMake/FetchContent/IncludesSystem/SubSub2/CMakeLists.txt

@@ -0,0 +1,6 @@
+add_library(subsub2bar STATIC bar.cpp)
+
+add_library(subsub2foo STATIC foo.cpp)
+set_target_properties(subsub2foo PROPERTIES SYSTEM OFF)
+
+add_executable(subsub2zot zot.cpp)

+ 0 - 0
Tests/RunCMake/FetchContent/IncludesSystem/SubSub2/bar.cpp


+ 0 - 0
Tests/RunCMake/FetchContent/IncludesSystem/SubSub2/foo.cpp


+ 0 - 0
Tests/RunCMake/FetchContent/IncludesSystem/SubSub2/zot.cpp


+ 0 - 0
Tests/RunCMake/FetchContent/IncludesSystem/bar.cpp


+ 0 - 0
Tests/RunCMake/FetchContent/IncludesSystem/foo.cpp


+ 0 - 0
Tests/RunCMake/FetchContent/IncludesSystem/zot.cpp


+ 1 - 0
Tests/RunCMake/FetchContent/RunCMakeTest.cmake

@@ -8,6 +8,7 @@ run_cmake(FirstDetailsWin)
 run_cmake(DownloadTwice)
 run_cmake(DownloadFile)
 run_cmake(SameGenerator)
+run_cmake(System)
 run_cmake(VarDefinitions)
 run_cmake(VarPassthroughs)
 run_cmake(GetProperties)

+ 37 - 0
Tests/RunCMake/FetchContent/System.cmake

@@ -0,0 +1,37 @@
+enable_language(CXX)
+
+include(FetchContent)
+
+FetchContent_Declare(
+  IncludesSystem
+  SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/IncludesSystem
+  SYSTEM
+)
+FetchContent_MakeAvailable(IncludesSystem)
+
+FetchContent_Declare(
+  IncludesNonSystem
+  SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/IncludesNonSystem
+)
+FetchContent_MakeAvailable(IncludesNonSystem)
+
+function(check_target_system target expected_value)
+  get_target_property(var ${target} SYSTEM)
+  if ((var AND NOT expected_value) OR (NOT var AND expected_value))
+    message(SEND_ERROR "\
+The 'SYSTEM' property of ${target} should be ${expected_value}, \
+but got ${var}")
+  endif()
+endfunction()
+
+check_target_system(foo OFF)
+check_target_system(bar ON)
+check_target_system(zot ON)
+check_target_system(subsub1foo OFF)
+check_target_system(subsub1bar ON)
+check_target_system(subsub1zot ON)
+check_target_system(subsub2foo OFF)
+check_target_system(subsub2bar ON)
+check_target_system(subsub2zot ON)
+check_target_system(foononsys OFF)
+check_target_system(barnonsys OFF)

+ 1 - 0
Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake

@@ -3,6 +3,7 @@ include(RunCMake)
 run_cmake(DoesNotExist)
 run_cmake(Missing)
 run_cmake(Function)
+run_cmake(System)
 
 macro(run_cmake_install case)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)

+ 22 - 0
Tests/RunCMake/add_subdirectory/System.cmake

@@ -0,0 +1,22 @@
+enable_language(CXX)
+
+add_subdirectory(System SYSTEM)
+
+function(check_target_system target expected_value)
+  get_target_property(var ${target} SYSTEM)
+  if ((var AND NOT expected_value) OR (NOT var AND expected_value))
+    message(SEND_ERROR "\
+The 'SYSTEM' property of ${target} should be ${expected_value}, \
+but got ${var}")
+  endif()
+endfunction()
+
+check_target_system(foo OFF)
+check_target_system(bar ON)
+check_target_system(zot ON)
+check_target_system(subsub1foo OFF)
+check_target_system(subsub1bar ON)
+check_target_system(subsub1zot ON)
+check_target_system(subsub2foo OFF)
+check_target_system(subsub2bar ON)
+check_target_system(subsub2zot ON)

+ 11 - 0
Tests/RunCMake/add_subdirectory/System/CMakeLists.txt

@@ -0,0 +1,11 @@
+project(SystemSub NONE)
+
+add_subdirectory(SubSub1 SYSTEM)
+add_subdirectory(SubSub2)
+
+add_library(bar STATIC bar.cpp)
+
+add_library(foo STATIC foo.cpp)
+set_target_properties(foo PROPERTIES SYSTEM OFF)
+
+add_executable(zot zot.cpp)

+ 6 - 0
Tests/RunCMake/add_subdirectory/System/SubSub1/CMakeLists.txt

@@ -0,0 +1,6 @@
+add_library(subsub1bar STATIC bar.cpp)
+
+add_library(subsub1foo STATIC foo.cpp)
+set_target_properties(subsub1foo PROPERTIES SYSTEM OFF)
+
+add_executable(subsub1zot zot.cpp)

+ 0 - 0
Tests/RunCMake/add_subdirectory/System/SubSub1/bar.cpp


+ 0 - 0
Tests/RunCMake/add_subdirectory/System/SubSub1/foo.cpp


+ 0 - 0
Tests/RunCMake/add_subdirectory/System/SubSub1/zot.cpp


+ 6 - 0
Tests/RunCMake/add_subdirectory/System/SubSub2/CMakeLists.txt

@@ -0,0 +1,6 @@
+add_library(subsub2bar STATIC bar.cpp)
+
+add_library(subsub2foo STATIC foo.cpp)
+set_target_properties(subsub2foo PROPERTIES SYSTEM OFF)
+
+add_executable(subsub2zot zot.cpp)

+ 0 - 0
Tests/RunCMake/add_subdirectory/System/SubSub2/bar.cpp


+ 0 - 0
Tests/RunCMake/add_subdirectory/System/SubSub2/foo.cpp


+ 0 - 0
Tests/RunCMake/add_subdirectory/System/SubSub2/zot.cpp


+ 0 - 0
Tests/RunCMake/add_subdirectory/System/bar.cpp


+ 0 - 0
Tests/RunCMake/add_subdirectory/System/foo.cpp


+ 0 - 0
Tests/RunCMake/add_subdirectory/System/zot.cpp