如何删除“可能无法从目标读取位置属性"?CMake 中的错误? [英] How can I remove the "the Location property may not be read from target" error in CMake?

查看:16
本文介绍了如何删除“可能无法从目标读取位置属性"?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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆