فهرست منبع

ExternalProject: Add `INSTALL_BYPRODUCTS` option

Add an `INSTALL_BYPRODUCTS` option to `ExternalProject_Add` that can
be used to declare that files are `BYPRODUCTS` of the ExternalProject
install step.

This is often required by the Ninja generator to explicitly declare
dependencies. Previously, many users used `BUILD_BYPRODUCTS`, even if
their files were created by the install step, not the build step.

This commit essentially just copies the code for `BUILD_BYPRODUCTS`.

Fixes: #24120
Fixes: #23056
Alois Klink 3 سال پیش
والد
کامیت
8c6b2928f4

+ 1 - 0
Auxiliary/vim/syntax/cmake.vim

@@ -2013,6 +2013,7 @@ syn keyword cmakeKWExternalProject contained
             \ IGNORED
             \ INACTIVITY_TIMEOUT
             \ INDEPENDENT_STEP_TARGETS
+            \ INSTALL_BYPRODUCTS
             \ INSTALL_COMMAND
             \ INSTALL_DIR
             \ JOB_POOLS

+ 6 - 0
Help/release/dev/ExternalProject-INSTALL_BYPRODUCTS.rst

@@ -0,0 +1,6 @@
+ExternalProject-INSTALL_BYPRODUCTS
+----------------------------------
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add` command
+  gained an ``INSTALL_BYPRODUCTS`` option to specify files generated by the
+  "install" step.

+ 18 - 0
Modules/ExternalProject.cmake

@@ -664,6 +664,17 @@ External Project Definition
       supported). Passing an empty string as the ``<cmd>`` makes the install
       step do nothing.
 
+    ``INSTALL_BYPRODUCTS <file>...``
+      .. versionadded:: 3.26
+
+      Specifies files that will be generated by the install command but which
+      might or might not have their modification time updated by subsequent
+      installs. This may also be required to explicitly declare dependencies
+      when using the :generator:`Ninja` generator.
+      These ultimately get passed through as ``BYPRODUCTS`` to the
+      install step's own underlying call to :command:`add_custom_command`, which
+      has additional documentation.
+
     .. 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
@@ -3852,6 +3863,11 @@ function(_ep_add_install_command name)
     set(always 0)
   endif()
 
+  get_property(install_byproducts
+    TARGET ${name}
+    PROPERTY _EP_INSTALL_BYPRODUCTS
+  )
+
   set(__cmdQuoted)
   foreach(__item IN LISTS cmd)
     string(APPEND __cmdQuoted " [==[${__item}]==]")
@@ -3860,6 +3876,7 @@ function(_ep_add_install_command name)
     ExternalProject_Add_Step(${name} install
       INDEPENDENT FALSE
       COMMAND ${__cmdQuoted}
+      BYPRODUCTS \${install_byproducts}
       WORKING_DIRECTORY \${binary_dir}
       DEPENDEES build
       ALWAYS \${always}
@@ -4087,6 +4104,7 @@ function(ExternalProject_Add name)
     # Install step options
     #
     INSTALL_COMMAND
+    INSTALL_BYPRODUCTS
     #
     # Test step options
     #

+ 29 - 0
Tests/CustomCommandByproducts/CMakeLists.txt

@@ -149,6 +149,29 @@ set_property(TARGET ExternalLibraryWithSubstitution PROPERTY IMPORTED_LOCATION
   ${binary_dir}${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX})
 add_dependencies(ExternalLibraryWithSubstitution ExtTargetSubst)
 
+# Generate the library file of an imported target as an install byproduct
+# of an external project. The byproduct uses <INSTALL_DIR> that is substituted
+# by the real install path
+if(_isMultiConfig)
+  set(cfg /${CMAKE_CFG_INTDIR})
+else()
+  set(cfg)
+endif()
+include(ExternalProject)
+ExternalProject_Add(ExtTargetInstallSubst
+  SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/External"
+  DOWNLOAD_COMMAND ""
+  INSTALL_COMMAND
+    "${CMAKE_COMMAND}" -E copy_directory "<BINARY_DIR>${cfg}" "<INSTALL_DIR>${cfg}"
+  BUILD_BYPRODUCTS "<BINARY_DIR>${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX}"
+  INSTALL_BYPRODUCTS "<INSTALL_DIR>${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX}"
+  )
+ExternalProject_Get_Property(ExtTargetInstallSubst install_dir)
+add_library(ExternalLibraryWithInstallDirSubstitution STATIC IMPORTED)
+set_property(TARGET ExternalLibraryWithInstallDirSubstitution PROPERTY IMPORTED_LOCATION
+  ${install_dir}${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX})
+add_dependencies(ExternalLibraryWithInstallDirSubstitution ExtTargetInstallSubst)
+
 # Add an executable consuming all the byproducts.
 add_executable(CustomCommandByproducts
   CustomCommandByproducts.c
@@ -175,6 +198,12 @@ target_link_libraries(ExternalLibraryByproducts ExternalLibrary)
 add_executable(ExternalLibraryByproducts_WithSubstitution ExternalLibraryByproducts.c)
 target_link_libraries(ExternalLibraryByproducts_WithSubstitution ExternalLibraryWithSubstitution)
 
+add_executable(ExternalLibraryByproducts_WithInstallDirSubstitution ExternalLibraryByproducts.c)
+target_link_libraries(
+  ExternalLibraryByproducts_WithInstallDirSubstitution
+  ExternalLibraryWithInstallDirSubstitution
+)
+
 if(CMAKE_GENERATOR STREQUAL "Ninja")
   add_custom_target(CheckNinja ALL
     COMMENT "Checking build.ninja"