微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

CMake:set_target_properties 失败,目标由生成器表达式定义

如何解决CMake:set_target_properties 失败,目标由生成器表达式定义

我在使用 cmake 生成器表达式 TARGET_NAME_IF_EXISTS 时遇到问题。有了这个CMakeLists.txt

cmake_minimum_required(VERSION 3.13.0)
option(SLIB_BUILD_STATIC "" ON)
project(slib VERSION 1.0)

add_library(slibObjects OBJECT main.c)
add_library(slib SHARED $<TARGET_OBJECTS:slibObjects>)

if (SLIB_BUILD_STATIC)                  # Can this if() be replaced with a GenExp?
  add_library(slibStatic STATIC $<TARGET_OBJECTS:slibObjects>)
endif()

set_target_properties(
    slib
    $<TARGET_NAME_IF_EXISTS:slibStatic> # This GenExp doesn't get reduced
  PROPERTIES
    VERSION ${SLIB_VERSION}
    SOVERSION ${SLIB_VERSION_MAJOR}
)

我明白

CMake Error at CMakeLists.txt:12 (set_target_properties):
  set_target_properties Can not find target to add properties to:
  $<TARGET_NAME_IF_EXISTS:slibStatic>

我预计 set_target_properties 会减少到其中之一,具体取决于是否设置了 SLIB_BUILD_STATIC

set_target_properties( slib slibStatic PROPERTIES ...)
set_target_properties( slib PROPERTIES ...)

我做错了什么?

解决方法

生成器表达式不能替代 if 命令

生成器表达式仅可用于某些属性和某些变量,因此可以在配置阶段结束时将它们评估为值,这取决于构建类型.使用普通的 if 无法实现这种行为,因为多配置 CMake 生成器(如 Visual Studio)读取一次 CMakeLists.txt 却创建了多个配置。

生成器表达式也可用于设置这些属性和变量的命令

生成器表达式的每种可能用法都在文档中明确说明,用于支持它们的命令/属性/变量。

命令 set_target_properties 的文档没有描述生成器表达式的用法,因此该命令根本不支持它们。

实际上,可以将生成器表达式作为属性的传递给该命令。在这种情况下,该命令只会将该值分配给相应的属性。配置后对属性求值时生成器表达式是否解析取决于属性。

但是目标的名称和属性的名称都不能是生成器表达式。

要为目标有条件地设置属性,请使用普通的 if

# Unconditionally set properties for 'slib' target.
set_target_properties(
    slib
  PROPERTIES
    VERSION ${SLIB_VERSION}
    SOVERSION ${SLIB_VERSION_MAJOR}
)
# Set properties for 'slibStatic' target only if this target exist.
if (TARGET slibStatic)
  set_target_properties(
      slibStatic
    PROPERTIES
      VERSION ${SLIB_VERSION}
      SOVERSION ${SLIB_VERSION_MAJOR}
  )
endif()

为了避免属性赋值的复制粘贴,您可以创建一个包含目标列表的变量,然后使用此变量:

# Variable which contain list of affected targets.
set(targets_for_version_set slib)
# Add target 'slibStatic' to the list only if the target exist

if (TARGET slibStatic)
  list(APPEND targets_for_version_set slibStatic)
endif()
# Now assign properties for all variables in the list
set_target_properties(
    ${targets_for_version_set}
  PROPERTIES
    VERSION ${SLIB_VERSION}
    SOVERSION ${SLIB_VERSION_MAJOR}
)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?