瀏覽代碼

ExternalProject: Optionally integrate 'make' job server with INSTALL_COMMAND

Add an `INSTALL_JOB_SERVER_AWARE` option to `ExternalProject_Add`.
When using an explicit `INSTALL_COMMAND`, the generated commands
won't use `$(MAKE)` thus failing to connect to the outer make's
job server.  Add an option enable explicit job server integration.

This is the install step's equivalent to the build step's
`BUILD_JOB_SERVER_AWARE` option added by commit bc43398e72
(ExternalProject: Enable Make Job Server with Explicit Build Command,
2023-08-09, v3.28.0-rc1~217^2).  It is useful when the external
project's installation is driven by its build system.  Note that with
Makefile generators, our default install command does use `$(MAKE)` to
connect to the outer make's job server.

Issue: #26398
Brad King 11 月之前
父節點
當前提交
1bdaad7573

+ 7 - 0
Help/release/dev/ExternalProject-install-jobserver.rst

@@ -0,0 +1,7 @@
+ExternalProject-install-jobserver
+---------------------------------
+
+* The :module:`ExternalProject` module's :command:`ExternalProject_Add`
+  command gained an ``INSTALL_JOB_SERVER_AWARE`` option to enable
+  integration of the GNU Make job server when using an explicit
+  ``INSTALL_COMMAND`` with :ref:`Makefile Generators`.

+ 19 - 0
Modules/ExternalProject.cmake

@@ -749,6 +749,14 @@ step. This can be overridden with custom install commands if required.
   install step's own underlying call to :command:`add_custom_command`, which
   has additional documentation.
 
+``INSTALL_JOB_SERVER_AWARE <bool>``
+  .. versionadded:: 3.32
+
+  Specifies that the install step is aware of the GNU Make job server.
+  See the :command:`add_custom_command` documentation of its
+  ``JOB_SERVER_AWARE`` option for details.  This option is relevant
+  only when an explicit ``INSTALL_COMMAND`` is specified.
+
 .. note::
   If the :envvar:`CMAKE_INSTALL_MODE` environment variable is set when the
   main project is built, it will only have an effect if the following
@@ -2819,6 +2827,16 @@ function(_ep_add_install_command name)
     PROPERTY _EP_INSTALL_BYPRODUCTS
   )
 
+  get_property(install_job_server_aware
+    TARGET ${name}
+    PROPERTY _EP_INSTALL_JOB_SERVER_AWARE
+  )
+  if(install_job_server_aware)
+    set(maybe_JOB_SERVER_AWARE "JOB_SERVER_AWARE 1")
+  else()
+    set(maybe_JOB_SERVER_AWARE "")
+  endif()
+
   set(__cmdQuoted)
   foreach(__item IN LISTS cmd)
     string(APPEND __cmdQuoted " [==[${__item}]==]")
@@ -2831,6 +2849,7 @@ function(_ep_add_install_command name)
       WORKING_DIRECTORY \${binary_dir}
       DEPENDEES build
       ALWAYS \${always}
+      ${maybe_JOB_SERVER_AWARE}
       ${log}
       ${uses_terminal}
     )"

+ 1 - 0
Modules/ExternalProject/shared_internal_commands.cmake

@@ -1934,6 +1934,7 @@ macro(_ep_get_add_keywords out_var)
     #
     INSTALL_COMMAND
     INSTALL_BYPRODUCTS
+    INSTALL_JOB_SERVER_AWARE
     #
     # Test step options
     #

+ 1 - 0
Tests/RunCMake/ExternalProject/GNUMakeJobServerAware-check.cmake

@@ -12,5 +12,6 @@ function(check target regex)
 endfunction()
 
 check("/CMakeFiles/Foo.dir/build.make" [[\+cd (/d )?"?.*"? && "?.*"? --build "?.*"?]])
+check("/CMakeFiles/Foo.dir/build.make" [[\+cd (/d )?"?.*"? && "?.*"? --install "?.*"?]])
 check("/CMakeFiles/Foo.dir/build.make" [[\+cd (/d )?"?.*"? && "?.*"? -E touch "?.*"?]])
 check("/CMakeFiles/Foo.dir/build.make" [[\+"?.*"? -E true]])

+ 3 - 1
Tests/RunCMake/ExternalProject/GNUMakeJobServerAware.cmake

@@ -1,9 +1,11 @@
 include(ExternalProject)
 ExternalProject_Add(Foo
   SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Foo
+  CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
   BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR>
   BUILD_JOB_SERVER_AWARE 1
-  INSTALL_COMMAND ""
+  INSTALL_COMMAND ${CMAKE_COMMAND} --install <BINARY_DIR>
+  INSTALL_JOB_SERVER_AWARE 1
 )
 
 # Add a second step to test JOB_SERVER_AWARE