是否可以使用 CMake 相对于
add_custom_command
复制由 $<TARGET_FILE_DIR:${Target}>
生成的文件?
我的用例具体是编译的脚本文件,必须位于特定文件夹中
Resources/Script
才能使应用程序正常运行。
所以我有
add_custom_command( OUTPUT ${CompiledFile} COMMAND ${ScriptCompiler} DEPENDS ${ScriptFile} )
add_library( CompiledScripts ${CompiledFile} )
add_executable( Main main.cpp )
现在我尝试了各种工具来将
${CompiledFile}
变成 $<TARGET_FILE_DIR:${Target}>/Resources/Script
,我发现的最常见的建议是:
add_custom_target
,有两个问题TARGET_FILE_DIR
添加了依赖项,这意味着可执行文件不能依赖于自定义目标,这意味着对脚本的更改不会触发已编译文件的副本,这意味着复制是手动操作。其次,自定义目标总是被认为是过时的,因此很难避免不需要的副本。add_custom_command( TARGET POST_BUILD )
也有类似的问题,它不知道对脚本所做的任何更改,并且会制作不需要的副本我找到的解决方案如下:
像往常一样定义您的
CompiledScripts
目标,定义自定义命令并将其输出列为源。
每次构建
add_custom_command( TARGET CompiledScripts POSTBUILD COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/modified.cpp )
时,使用 .cpp
修改 CompiledScripts
文件。
创建一个以
modified.cpp
作为源的库,并为其指定 add_custom_command( TARGET POST_BUILD )
以将文件复制到您需要的位置。这会在 CompiledScripts
和此复制目标之间创建隐式/隐藏依赖关系,导致 POST_BUILD
在重建 CompiledScripts
时运行。不幸的是,我还没有找到更好的解决方案。
然后您可以使用
add_dependency
创建以下链 CompiledScript
=> CopyTarget
=> Main
。 ( A=>B, B 取决于 A )
这样做的好处是,仅当文件被实际修改时才会进行复制,此外,您可以从其他目标修改
modified.cpp
以强制重新复制文件。
正如 @Tsyvarev 所指出的,使用
TARGET_FILE_DIR
作为目标需要 CMAKE 3.19 或使用 CMP0112。