通常需要确保CMake构建项目在编译后最终位于某个位置,并且该add_custom_command(..POST_BUILD...)
命令是实现该目标的通用设计模式:
add_custom_command(
TARGET mytarget
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:mytarget> ${CMAKE_BINARY_DIR}/final_destination
)
Run Code Online (Sandbox Code Playgroud)
令人遗憾的是,当所讨论的目标位于相对于包含add_custom_command
调用的文件的子目录中时,该文件是通过add_subdirectory()
命令递归编译的。尝试这样做会导致以下错误消息:
CMake Warning (dev) at CMakeLists.txt:4 (add_custom_command):
Policy CMP0040 is not set: The target in the TARGET signature of
add_custom_command() must exist. Run "cmake --help-policy CMP0040" for
policy details. Use the cmake_policy command to set the policy and
suppress this warning.
TARGET 'mytarget' was not created in this directory.
This warning is for project developers. Use -Wno-dev to suppress it.
Run Code Online (Sandbox Code Playgroud)
在许多情况下,有一个简单的解决方法:只需确保该add_custom_command()
调用发生在子目录的CMakeLists.txt
文件中,并且一切正常。
但是,这并不总是可能的!子目录可以是我们无法控制的外部依赖项的CMake项目。例如,将CMake递归编译与Git子模块结合在一起是很常见的,在这种情况下,无法永久存储子项目的构建系统的修改。
然后,我的问题归结为以下几点:CMake是否提供另一种机制来创建目标,该目标将在重建子项目的目标时自动触发,并可用于将最终的可执行文件或共享库复制到其他位置?
我的目标是自动进行此操作,而无需与另一个目标专门调用“ make” /“ ninja”。此外,仅应在确实有必要时执行复制(根据cmake文档,某些add_custom_ *命令不会跟踪它们是否真正需要运行,并保守地认为目标始终是过时的)。
只需使用add_custom_command
and 的常见组合add_custom_target
,当第一个为第二个生成文件时:
# Because OUTPUT option may not use generator expressions,
# extract name of file from target's properties.
get_target_property(mytarget_basename mytarget OUTPUT_NAME)
get_target_property(mytarget_suffix mytarget SUFFIX)
set(mytarget_filename ${mytarget_basename}${mytarget_suffix})
# make copied file be dependent from one which is build.
# Note, that DEPENDS here creates dependencies both from the target
# and from the file it creates.
add_custom_command(OUTPUT
${CMAKE_BINARY_DIR}/final_destination/${mytarget_filename}
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:mytarget>
${CMAKE_BINARY_DIR}/final_destination
DEPENDS mytarget
)
# Create target which consume the command via DEPENDS.
add_custom_target(copy_files ALL
DEPENDS ${CMAKE_BINARY_DIR}/final_destination/${mytarget_filename}
)
Run Code Online (Sandbox Code Playgroud)
与使用 POST_BUILD 相比,此代码使用了额外的目标。但是你别无选择:add_custom_command
不能附加到在其他目录中创建的目标。
通常,不是将可执行文件/库复制到其他二进制目录中,而是通过CMAKE_<TYPE>_OUTPUT_DIRECTORY
变量指定此目录更简单。
归档时间: |
|
查看次数: |
3006 次 |
最近记录: |