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
This commit is contained in:
Alois Klink
2022-11-03 15:40:30 +00:00
parent 6d6baffb85
commit 8c6b2928f4
4 changed files with 54 additions and 0 deletions

View File

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

View File

@@ -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.

View File

@@ -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
#

View File

@@ -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"