事后如何向custom_target()添加依赖项?



我试图有一个顶级目标,我们称之为每次都经过测试/构建sdk_extraction,并且依赖于一堆生成的文件,这些文件基本上是树中文件的副本或次要转换。

我构建要导出为属性字符串/列表的文件列表,然后在完成所有内容后,获取该列表并循环访问它,为每个列表创建custom_commands,然后在输出文件和sdk_extraction目标之间添加依赖项。

function(finalize_sdk_export destination)
file(REAL_PATH ${destination} destination )
add_custom_target(sdk_target ALL
COMMENT "Exporting SDK"
)
get_property(sdk_source GLOBAL PROPERTY SDK_SOURCE )
string(REPLACE " " ";" sdk_source "${sdk_source}")
foreach (item ${sdk_source})
string(REPLACE ${destination} ${destination}/sdk target "${item}")
add_custom_command(
OUTPUT ${target}
DEPENDS ${item}
COMMAND ${CMAKE_COMMAND} -E copy ${item} ${target}
VERBATIM
)
add_dependencies(sdk_target ${target})
endforeach()
endfunction()

此操作失败并显示错误:

CMake Error at <redacted>/build_scripts/CMakeLists.txt:209 (add_dependencies):
The dependency target
"<redacted>/sdk/CMakeLists.txt"
of target "sdk_target" does not exist.
Call Stack (most recent call first):
<redacted>/CMakeLists.txt:78 (finalize_sdk_export)

这不行吗? 我能够做到这一点:

function(finalize_sdk_export destination)
file(REAL_PATH ${destination} destination )
get_property(sdk_source GLOBAL PROPERTY SDK_SOURCE )
string(REPLACE " " ";" sdk_source "${sdk_source}")
foreach (item ${sdk_source})
string(REPLACE ${destination} ${destination}/sdk target "${item}")
add_custom_command(
OUTPUT ${target}
DEPENDS ${item}
COMMAND ${CMAKE_COMMAND} -E copy ${item} ${target}
VERBATIM
)
list(APPEND sdk_files ${target})
endforeach()
add_custom_target(sdk_target ALL
COMMENT "Exporting SDK"
DEPENDS ${sdk_files}
)
endfunction()

我制作所有custom_command并保留每个输出的列表,然后调用add_custom_target()DEPENDS参数中指定的所有输出。

这目前有效,但我仍然只是在测试,如果我最终在导出中有数百/数千个文件,我不确定它是否会成立。

那么,我应该如何正确地做到这一点呢?

(仅供参考,我放弃了内置的 cmake 安装/导出功能,因为我们真的想控制 CMake 文件的目录结构和外观)

自定义目标所依赖的所有文件都应在add_custom_target()调用的DEPENDS选项中指定。之后无法从文件添加依赖项。

命令add_dependencies只能添加目标之间的依赖关系。

add_dependencies不同,它可以连接在不同目录中创建的目标DEPENDS子句中生成的所有文件都应由add_custom_command仅在同一目录中创建。也就是说,它通常不是 除非计算所有依赖文件,否则推迟创建目标的问题。

实际上,您可以通过使用生成器表达式并为自定义目标定义属性来执行此操作:

define_property(TARGET
PROPERTY "SDK_EXTRACT_GENERATED"
)
add_custom_target(
sdk_target ALL
DEPENDS $<TARGET_PROPERTY:sdk_extraction,SDK_EXTRACT_GENERATED>
)

然后,要添加生成的文件,请执行以下操作:

add_custom_command(
OUTPUT sdk_extraction
DEPENDS ${item}
COMMAND ${CMAKE_COMMAND} -E copy ${item} sdk_extraction
VERBATIM
)
set_property(TARGET ${target}
APPEND PROPERTY SDK_EXTRACT_GENERATED ${item}
)

这是有效的,因为生成器表达式是在构建生成步骤期间计算的,该步骤在配置步骤之后运行。

这意味着,由于 SDK_EXTRACT_GENERATED 属性是在配置时填充的,因此在运行生成步骤后,生成器表达式将扩展到文件的完整列表。

请注意,这是针对文件级依赖项的,目标级别依赖项应通过通常的add_dependencies()调用添加。

最新更新