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

10

我有一个CMakeLists.txt文件,它做了这个:

get_target_property(myloc mytarget LOCATION)

它以前运行得很好,但是CMake 3.0放弃了使用LOCATION(请参见https://cmake.org/cmake/help/v3.0/policy/CMP0026.html)。 因此,我尝试使用生成器表达式:

set(myloc $<TARGET_FILE:mytarget>)

看起来这样应该可以工作,但生成器表达式并不是在所有地方都被评估,它们只在设置其他目标的属性时才起作用,并且在“生成”步骤而不是更早的“配置”步骤中解决。问题是,在 install() 规则中,我需要知道目标位置,就像这样(真正的用途不是 strip,但无关紧要):

install(CODE "execute_process(COMMAND strip ${myloc})")

使用 LOCATION 时,这个很好用,但现在已被弃用,而我无法找到正确的方法来解决这个问题。问题的根源似乎是在进行“配置”步骤时调用了 install(),而此时目标路径未知。

那么,在调用 install() 之前,我该如何弥补这个差距,并发现目标输出路径,就像以前做的那样?

2个回答

5
理想情况下,可以通过生成器表达式实现:
install(CODE "execute_process(COMMAND strip $<TARGET_FILE:mytarget>)")

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

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

在这种情况下,您可以像Th.Thielemann's答案所建议的那样禁用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)

请注意,使用 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})

但这仍然行不通:在多配置生成器中,CMAKE_BUILD_TYPE会被评估为空字符串。

(用install(SCRIPT)命令中的${CMAKE_BUILD_TYPE}替换为$<CONFIG>仅适用于CMake 3.14及以后版本,但在这些版本中,整个file(GENERATE)都不需要,可以直接使用第一个代码片段。)


1
你可以尝试使用/重新启用< v3.0的行为。
cmake_policy(SET CMP0026 OLD)

请参见 cmake-policies

1
我不想简单地禁用警告,我希望有一种不依赖于废弃行为的解决方案。 - John Zwinck
据我所知,这不仅会禁用警告,而且还会启用旧的行为。 - Th. Thielemann
旧行为始终被启用,但已弃用,并且文档(https://cmake.org/cmake/help/v3.6/policy/CMP0026.html)指出: “注意一个策略的旧行为在定义上是不赞成使用的,并且可能在将来的CMake版本中被删除。”因此,我想知道正确的解决方案是什么。 - John Zwinck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接