How can I remove the “the Location property may not be read from target” error in CMake?

后端 未结 1 630
后悔当初
后悔当初 2021-01-11 16:20

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

相关标签:
1条回答
  • 2021-01-11 16:47

    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()
    
    0 讨论(0)
提交回复
热议问题