CMake:如何获取安装规则的目标位置

Joh*_*nck 6 cmake

我有一个CMakeLists.txt可以做到这一点:

get_target_property(myloc mytarget LOCATION)
Run Code Online (Sandbox Code Playgroud)

它曾经可以正常工作,但是不建议使用CMake 3.0 LOCATION(请参阅https://cmake.org/cmake/help/v3.0/policy/CMP0026.html)。所以我尝试使用生成器表达式:

set(myloc $<TARGET_FILE:mytarget>)
Run Code Online (Sandbox Code Playgroud)

这似乎是可行的,除了生成器表达式不是在任何地方都被求值,它们似乎仅在设置其他目标的属性时起作用,并且在“生成”步骤而不是之前的“配置”步骤中得到解析。问题是,我需要知道install()规则中的目标位置,如下所示(实际用途并不重要,strip但这无关紧要):

install(CODE "execute_process(COMMAND strip ${myloc})")
Run Code Online (Sandbox Code Playgroud)

使用时可以很好地工作,LOCATION但是现在已经过时了,我想不通正确的方法。问题的根源似乎install()是在目标路径未知时在“配置”步骤中调用的。

如何在调用之前弥合这一差距,并像以前一样发现目标输出路径install()

Tsy*_*rev 5

理想情况下,这可以通过生成器表达式来完成:

install(CODE "execute_process(COMMAND strip $<TARGET_FILE:mytarget>)")
Run Code Online (Sandbox Code Playgroud)

不幸的是,仅在 CMake 3.14 中添加了对命令的CODESCRIPT模式中的生成器表达式的支持(请参阅该版本中的安装命令文档)。install

在 CMake 3.14 之前,您只能使用单配置生成器(例如使用 Makefile,但不能使用 Visual Studio)。

在这种情况下,您可以按照Th.Thielemann 的答案中的建议禁用 CMP0026 警告并阅读 LOCATION 属性。

或者您可以使用install(SCRIPT)命令流程,其中脚本是使用file(GENERATE)命令准备的,该命令类似于configure_file但适用于生成器表达式:

file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mytarget_strip.cmake
     CONTENT "execute_process(COMMAND strip $<TARGET_FILE:mytarget>)")

install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/mytarget_strip.cmake)
Run Code Online (Sandbox Code Playgroud)

请注意,该方法file(GENERATE)仍然不适用于多配置生成器:CMake 要求OUTPUT子句的文件名在配置之间是唯一的。人们可以“修复”这个问题

file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mytarget_strip.cmake_$<CONFIG>
     CONTENT "execute_process(COMMAND strip $<TARGET_FILE:mytarget>)")

install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/mytarget_strip.cmake_${CMAKE_BUILD_TYPE})
Run Code Online (Sandbox Code Playgroud)

但这仍然不起作用:在多配置生成器中CMAKE_BUILD_TYPE被评估为空字符串。

${CMAKE_BUILD_TYPE}$<CONFIG>ininstall(SCRIPT)命令替换仅在 CMake 3.14 及更高版本中有效,但在这些版本中file(GENERATE)不需要整个命令,可以只使用第一个片段。)