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.
Then I tried to print the property with message($<TARGET_FILE:abc>)
, but it does not work either. Any ideas?
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 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.
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!
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With