在 CMake 中将 'install' 目标添加到 'all'

Add 'install' target to 'all' in CMake

我有一个具有以下目录树的 CMake 项目:

build/
assets/
dest/
<other files>

dest 是所有已安装文件应该去的目录:

  1. 可执行文件,通过简单的make进入dest/,这是由CMAKE_RUNTIME_OUTPUT_DIRECTORY

  2. 控制的
  3. 资产,位于 assets/,在 make install 后转到 dest/

但我不想发出 make install 来复制所有文件做 dest/ 目录:我想要一个简单的 make 来做这个。

从这个意义上讲,如何将 install 目标添加到默认目标 (all)?或者,有没有更好的方法来解决这个问题?

使用 CMake 的正常方法是在项目外部创建一个构建目录,并将所有编译的二进制文件放在那里。当您完成开发并想要将一些二进制文件安装到您的系统中时,您可以调用 make install。通过这种方式,您可以使项目源文件夹免受所有编译器生成的内容的影响。

示例文件目录结构:

my_project/
my_project_build/

从 my_project_build 你调用 cmake ../my_project 来生成构建文件。调用 make 构建它,所有二进制文件都将在 my_project_build.

这将在构建 <target_name>(可能是 all)后执行 install 目标:

add_custom_command(
    TARGET <target_name>
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target install
    )

我已经通过使用以下宏为指定目标生成数据依赖规则解决了这个问题。这些规则只需要 make 而不是 make install.

宏将源代码树中的任意文件映射到 "staging" 树中,其中每个树结构可能不同,您可以选择重命名文件。暂存数据保持最新,因此如果您在源代码树中更改它,那么下次您 make.

时它会更新
# Macro used to create dependencies for staging data files (e.g. config files, assets) and keeping them up-to-date.
# The given "source" file is copied (and possibly renamed) to "staged" for the given "target".
#
# It works by creating a rule that creates "staged" by copying "source", then creating a target that depends upon "staged",
# then making the given "target" depend upon the new target. Or in makefile speak:
#
#   staged:  source
#       cp source staged
#
#   targetData1:  staged
#
#   target:  <existing dependencies...> targetData1
#       <existing commands...>
#
# The intermediate rule is used for parallel build robustness.  For details, see:
# http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:add_custom_command
#
# Example:
#   target = myExeTarget
#   source = "${CMAKE_CURRENT_SOURCE_DIR}/../../data/images/bush1.png"
#   staged = "${STAGING_DATA_DIR}/images/bush1.png"
macro(add_data_dependency target source staged)
    add_custom_command(
        OUTPUT "${staged}"
        COMMAND ${CMAKE_COMMAND} -E copy_if_different "${source}" "${staged}"    # Dir(s) will be created if needed.
        DEPENDS "${source}"
    )

    if (NOT DEFINED add_data_dependency_counter)
        #message(status "Setting tmp counter......")
        set(add_data_dependency_counter "0")
    endif()

    math(EXPR add_data_dependency_counter "${add_data_dependency_counter} + 1")
    #message(status "tmp counter is ${add_data_dependency_counter}......")

    set(customTarget "${target}Data${add_data_dependency_counter}")

    add_custom_target(${customTarget} DEPENDS "${staged}")
    add_dependencies(${target} ${customTarget})
endmacro()

在您的情况下,用法类似于:

add_data_dependency(myTarget "${CMAKE_CURRENT_SOURCE_DIR}/assets/file1.ext" "${CMAKE_CURRENT_SOURCE_DIR}/dest/file1.ext")
add_data_dependency(myTarget "${CMAKE_CURRENT_SOURCE_DIR}/assets/file2.ext" "${CMAKE_CURRENT_SOURCE_DIR}/dest/file2.ext")
add_data_dependency(myTarget "${CMAKE_CURRENT_SOURCE_DIR}/assets/rename_me.ext" "${CMAKE_CURRENT_SOURCE_DIR}/dest/renamed.ext")
:
:

然后每当您 make,如果文件丢失或过期(假设 myTargetall 的一部分),文件将被复制。

使用以下不会导致递归。需要 CMake >= 3.15.

add_custom_command(
    TARGET ${MY_TARGET} POST_BUILD
    COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --config $<CONFIG>
)

额外:您可能希望提供默认(本地)安装路径,这样就不会在 Windows.

上失败
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    set(CMAKE_INSTALL_PREFIX "install" CACHE PATH "Default install path." FORCE)
endif()