我现在正在尝试在this post中运行CMake脚本。使用此脚本,CMake将打印目标的所有属性。但是,当它尝试检索目标的LOCATION
属性时,会观察到以下错误:
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>)
打印该属性,但是它也不起作用。有任何想法吗?
为了扩展@Florian的注释,在当今的CMake版本中,默认情况下,读取目标的LOCATION
属性是error。 CMake Policy 0026的文档清楚地描述了为什么是这种情况:
CMake 2.8.12和更低版本允许读取
LOCATION
目标属性(以及特定于配置的变体)以确定构建目标的最终位置。这基于这样的假设,即在配置时所有必需的信息都可用以确定目标的最终位置和文件名。但是,直到稍后在生成时才完全确定此属性。
读取LOCATION
属性后,以后可以使用生成器表达式对其进行更改。通过将CMake设置为OLD
行为explicitly,您可以禁用此策略:
cmake_policy(SET CMP0026 OLD)
只需加上一粒盐,结果可能会改变!
如果要更改策略(而不是简单地从属性列表中删除LOCATION
),最好单独使用OLD
CMake策略。使用OLD
行为完成后,我们可以将[CM0]策略POP
上的旧策略stack恢复为使用NEW
行为。这是您引用的example,经过修改以演示策略更改的用法:
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()