CMake:set_target_properties 因生成器表达式定义的目标而失败
CMake: set_target_properties fails with target defined by generator expression
我在使用 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
但会创建多个配置。
生成器表达式也可用于设置这些属性和变量的命令。
生成器表达式的每种可能用法都在文档中明确说明,command/property/variable支持它们。
命令 set_target_properties 的文档没有描述生成器表达式的用法,因此该命令根本不支持它们。
实际上,可以将生成器表达式作为 属性 的 值 传递给该命令。在那种情况下,该命令只会将该值分配给相应的 属性。配置后计算属性时是否解析生成器表达式取决于属性。
但是 target 的名称和 属性 的名称都不能是生成器表达式。
对于目标的有条件设置属性,使用普通 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}
)
我在使用 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
但会创建多个配置。
生成器表达式也可用于设置这些属性和变量的命令。
生成器表达式的每种可能用法都在文档中明确说明,command/property/variable支持它们。
命令 set_target_properties 的文档没有描述生成器表达式的用法,因此该命令根本不支持它们。
实际上,可以将生成器表达式作为 属性 的 值 传递给该命令。在那种情况下,该命令只会将该值分配给相应的 属性。配置后计算属性时是否解析生成器表达式取决于属性。
但是 target 的名称和 属性 的名称都不能是生成器表达式。
对于目标的有条件设置属性,使用普通 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}
)