Browse Source

FetchContent: Add support for EXCLUDE_FROM_ALL

Fixes: #20167
Steven Stallion 2 years ago
parent
commit
5f77807f1c

+ 7 - 0
Help/release/dev/FetchContent-exclude-from-all.rst

@@ -0,0 +1,7 @@
+FetchContent-exclude-from-all
+-----------------------------
+
+* The :module:`FetchContent` module's :command:`FetchContent_Declare` command
+  gained an ``EXCLUDE_FROM_ALL`` option, which propagates through to the
+  :command:`add_subdirectory` call made by
+  :command:`FetchContent_MakeAvailable` for the dependency.

+ 30 - 7
Modules/FetchContent.cmake

@@ -111,6 +111,7 @@ Commands
     FetchContent_Declare(
       <name>
       <contentOptions>...
+      [EXCLUDE_FROM_ALL]
       [SYSTEM]
       [OVERRIDE_FIND_PACKAGE |
        FIND_PACKAGE_ARGS args...]
@@ -240,6 +241,15 @@ Commands
       See the :prop_tgt:`SYSTEM` target property documentation for a more
       detailed discussion of the effects.
 
+  .. versionadded:: 3.28
+
+    ``EXCLUDE_FROM_ALL``
+      If the ``EXCLUDE_FROM_ALL`` argument is provided, then targets in the
+      subdirectory added by :command:`FetchContent_MakeAvailable` will not be
+      included in the ``ALL`` target by default, and may be excluded from IDE
+      project files. See the `:command:`add_subdirectory` `EXCLUDE_FROM_ALL``
+      argument documentation for a more detailed discussion of the effects.
+
 .. command:: FetchContent_MakeAvailable
 
   .. versionadded:: 3.14
@@ -358,6 +368,11 @@ Commands
       :command:`FetchContent_Declare`, the ``SYSTEM`` keyword will be
       added to the :command:`add_subdirectory` command as well.
 
+    .. versionadded:: 3.28
+      If the ``EXCLUDE_FROM_ALL`` keyword was included in the call to
+      :command:`FetchContent_Declare`, the ``EXCLUDE_FROM_ALL`` keyword will
+      be added to the :command:`add_subdirectory` command as well.
+
   Projects should aim to declare the details of all dependencies they might
   use before they call ``FetchContent_MakeAvailable()`` for any of them.
   This ensures that if any of the dependencies are also sub-dependencies of
@@ -1466,8 +1481,10 @@ function(__FetchContent_directPopulate contentName)
 
   set(options
       QUIET
-      # SYSTEM has no meaning for ExternalProject, it is only used by us in
-      # FetchContent_MakeAvailable(). We need to parse and discard it here.
+      # EXCLUDE_FROM_ALL and SYSTEM have no meaning for ExternalProject, they
+      # are only used by us in FetchContent_MakeAvailable(). We need to parse
+      # and discard them here.
+      EXCLUDE_FROM_ALL
       SYSTEM
   )
   set(oneValueArgs
@@ -2030,22 +2047,28 @@ 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 "SYSTEM" "SOURCE_SUBDIR" "" ${__cmake_contentDetails})
+      cmake_parse_arguments(__cmake_arg "EXCLUDE_FROM_ALL;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)
-        if (__cmake_arg_SYSTEM)
-          add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR} SYSTEM)
-        else()
-          add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR})
+        set(__cmake_add_subdirectory_args ${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR})
+        if(__cmake_arg_EXCLUDE_FROM_ALL)
+          list(APPEND __cmake_add_subdirectory_args EXCLUDE_FROM_ALL)
+        endif()
+        if(__cmake_arg_SYSTEM)
+          list(APPEND __cmake_add_subdirectory_args SYSTEM)
         endif()
+        add_subdirectory(${__cmake_add_subdirectory_args})
       endif()
 
       unset(__cmake_srcdir)
       unset(__cmake_contentDetails)
+      unset(__cmake_arg_EXCLUDE_FROM_ALL)
+      unset(__cmake_arg_SYSTEM)
       unset(__cmake_arg_SOURCE_SUBDIR)
+      unset(__cmake_add_subdirectory_args)
     endif()
   endforeach()
 

+ 11 - 0
Tests/RunCMake/FetchContent/ExcludeFromAll.cmake

@@ -0,0 +1,11 @@
+enable_language(C)
+
+include(FetchContent)
+
+FetchContent_Declare(
+  ExcludeFromAll
+  SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/ExcludeFromAll
+  EXCLUDE_FROM_ALL
+)
+
+FetchContent_MakeAvailable(ExcludeFromAll)

+ 1 - 0
Tests/RunCMake/FetchContent/ExcludeFromAll/CMakeLists.txt

@@ -0,0 +1 @@
+add_library(broken STATIC error.c)

+ 1 - 0
Tests/RunCMake/FetchContent/ExcludeFromAll/error.c

@@ -0,0 +1 @@
+#error "This should not be compiled"

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

@@ -64,3 +64,15 @@ run_cmake_command(ScriptMode
     -DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}
     -P ${CMAKE_CURRENT_LIST_DIR}/ScriptMode.cmake
 )
+
+function(run_FetchContent_ExcludeFromAll)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ExcludeFromAll-build)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(ExcludeFromAll)
+
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(ExcludeFromAll-build ${CMAKE_COMMAND} --build .)
+endfunction()
+run_FetchContent_ExcludeFromAll()