如何删除“可能无法从目标读取位置属性"?CMake 中的错误? [英] How can I remove the "the Location property may not be read from target" error in CMake?
问题描述
我现在正在尝试在 这篇文章中运行 CMake 脚本.使用此脚本,CMake 将打印目标的所有属性.但是,当它尝试检索目标的 LOCATION
属性时,观察到以下错误:
I am now trying run a CMake script in this post. With this script, CMake will print all the properties of a target. However, when it tries to retrieve the LOCATION
property of the target, the following error is observed:
The LOCATION property may not be read from target "abc". Use the target
name directly with add_custom_command, or use the generator expression
$<TARGET_FILE>, as appropriate.
然后我尝试使用 message($<TARGET_FILE:abc>)
打印属性,但它也不起作用.有任何想法吗?
Then I tried to print the property with message($<TARGET_FILE:abc>)
, but it does not work either. Any ideas?
推荐答案
为了扩展@Florian 的评论,默认读取目标的LOCATION
属性是一个错误在今天的 CMake 版本中.CMake Policy 0026 的文档清楚地描述了为什么 是这样的:
To expand on @Florian's comment, reading the LOCATION
property of a target is an error by default in today's CMake versions. The documentation for CMake Policy 0026 clearly describes why this is the case:
CMake 2.8.12 及更低版本允许读取 LOCATION
目标属性(和特定于配置的变体)以确定构建目标的最终位置.这依赖于所有必要信息在配置时可用的假设,以确定目标的最终位置和文件名.然而,这个属性直到生成时才完全确定.
CMake 2.8.12 and lower allowed reading the
LOCATION
target property (and configuration-specific variants) to determine the eventual location of build targets. This relies on the assumption that all necessary information is available at configure-time to determine the final location and filename of the target. However, this property is not fully determined until later at generate-time.
阅读LOCATION
属性后,可以稍后使用生成器表达式更改它.CMake 允许您禁用此策略,方法是将其设置为 OLD
行为 明确地:
After reading the LOCATION
property, it can later be changed using generator expressions. CMake allows you to disable this policy, by setting it to the OLD
behavior explicitly:
cmake_policy(SET CMP0026 OLD)
对结果持保留态度,因为它可能会改变!
Just take the result with a grain of salt, as it may change!
如果您要更改策略(而不是简单地从属性列表中删除 LOCATION
),最好单独使用 OLD
CMake 策略.当我们使用完 OLD
行为后,我们可以 POP
CMake 策略之外的旧策略 stack 以恢复使用 NEW
行为.这是您提到的示例,经过修改以演示政策更改的用法:
If you're going to change the policy (instead of simply removing LOCATION
from the list of properties), it is best to use OLD
CMake policies in isolation. When we're done using the OLD
behavior, we can POP
the old policy off the CMake policy stack to resume using the NEW
behavior. Here's the example you referred to, modified to demonstrate usage of the policy change:
function(echo_target tgt)
if(NOT TARGET ${tgt})
message("There is no target named '${tgt}'")
return()
endif()
set(props
DEBUG_OUTPUT_NAME
DEBUG_POSTFIX
RELEASE_OUTPUT_NAME
...
LINK_SEARCH_START_STATIC
LOCATION
LOCATION_DEBUG
...
WIN32_EXECUTABLE
XCODE_ATTRIBUTE_WHATEVER
)
message(STATUS "======================== ${tgt} ========================")
# Push the current (NEW) CMake policy onto the stack, and apply the OLD policy.
cmake_policy(PUSH)
cmake_policy(SET CMP0026 OLD)
foreach(p ${props})
# v for value, d for defined, s for set
get_property(v TARGET ${tgt} PROPERTY ${p})
get_property(d TARGET ${tgt} PROPERTY ${p} DEFINED)
get_property(s TARGET ${tgt} PROPERTY ${p} SET)
# only produce output for values that are set
if(s)
message(STATUS "tgt='${tgt}' p='${p}'")
message(STATUS " value='${v}'")
message(STATUS " defined='${d}'")
message(STATUS " set='${s}'")
message(STATUS "")
endif()
endforeach()
# Pop the previous policy from the stack to re-apply the NEW behavior.
cmake_policy(POP)
message(STATUS "")
endfunction()
这篇关于如何删除“可能无法从目标读取位置属性"?CMake 中的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!