瀏覽代碼

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 1 年之前
父節點
當前提交
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
   install step's own underlying call to :command:`add_custom_command`, which
   has additional documentation.
   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::
 .. note::
   If the :envvar:`CMAKE_INSTALL_MODE` environment variable is set when the
   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
   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
     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)
   set(__cmdQuoted)
   foreach(__item IN LISTS cmd)
   foreach(__item IN LISTS cmd)
     string(APPEND __cmdQuoted " [==[${__item}]==]")
     string(APPEND __cmdQuoted " [==[${__item}]==]")
@@ -2831,6 +2849,7 @@ function(_ep_add_install_command name)
       WORKING_DIRECTORY \${binary_dir}
       WORKING_DIRECTORY \${binary_dir}
       DEPENDEES build
       DEPENDEES build
       ALWAYS \${always}
       ALWAYS \${always}
+      ${maybe_JOB_SERVER_AWARE}
       ${log}
       ${log}
       ${uses_terminal}
       ${uses_terminal}
     )"
     )"

+ 1 - 0
Modules/ExternalProject/shared_internal_commands.cmake

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

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

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

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

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