cmake-generator-expressions(7)

简介

生成器表达式在构建系统生成期间进行求值,以生成特定于每个构建配置的信息。它们的格式为 $<...>。例如

target_include_directories(tgt PRIVATE /opt/include/$<CXX_COMPILER_ID>)

这将扩展为 /opt/include/GNU/opt/include/Clang 等,具体取决于使用的 C++ 编译器。

生成器表达式允许在许多目标属性的上下文中使用,例如 LINK_LIBRARIESINCLUDE_DIRECTORIESCOMPILE_DEFINITIONS 等。它们也可以在使用命令填充这些属性时使用,例如 target_link_libraries()target_include_directories()target_compile_definitions() 等。它们支持条件链接、编译时使用的条件定义、条件包含目录等。条件可以基于构建配置、目标属性、平台信息或任何其他可查询信息。

生成器表达式可以嵌套

target_compile_definitions(tgt PRIVATE
  $<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,4.2.0>:OLD_COMPILER>
)

以上将扩展为 OLD_COMPILER,如果 CMAKE_CXX_COMPILER_VERSION 小于 4.2.0。

空格和引号

生成器表达式通常在命令参数之后解析。如果生成器表达式包含空格、换行符、分号或其他可能被解释为命令参数分隔符的字符,则在传递给命令时,整个表达式应括在引号中。否则可能会导致表达式被拆分,并且可能不再被识别为生成器表达式。

当使用 add_custom_command()add_custom_target() 时,使用 VERBATIMCOMMAND_EXPAND_LISTS 选项以获得强大的参数拆分和引号功能。

# WRONG: Embedded space will be treated as an argument separator.
# This ends up not being seen as a generator expression at all.
add_custom_target(run_some_tool
  COMMAND some_tool -I$<JOIN:$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>, -I>
  VERBATIM
)
# Better, but still not robust. Quotes prevent the space from splitting the
# expression. However, the tool will receive the expanded value as a single
# argument.
add_custom_target(run_some_tool
  COMMAND some_tool "-I$<JOIN:$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>, -I>"
  VERBATIM
)
# Nearly correct. Using a semicolon to separate arguments and adding the
# COMMAND_EXPAND_LISTS option means that paths with spaces will be handled
# correctly. Quoting the whole expression ensures it is seen as a generator
# expression. But if the target property is empty, we will get a bare -I
# with nothing after it.
add_custom_target(run_some_tool
  COMMAND some_tool "-I$<JOIN:$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>,;-I>"
  COMMAND_EXPAND_LISTS
  VERBATIM
)

使用变量构建更复杂的生成器表达式也是减少错误并提高可读性的好方法。以上示例可以进一步改进,如下所示

# The $<BOOL:...> check prevents adding anything if the property is empty,
# assuming the property value cannot be one of CMake's false constants.
set(prop "$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>")
add_custom_target(run_some_tool
  COMMAND some_tool "$<$<BOOL:${prop}>:-I$<JOIN:${prop},;-I>>"
  COMMAND_EXPAND_LISTS
  VERBATIM
)

最后,以上示例可以使用另一种生成器表达式以更简单、更健壮的方式表达

add_custom_target(run_some_tool
  COMMAND some_tool "$<LIST:TRANSFORM,$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>,PREPEND,-I>"
  COMMAND_EXPAND_LISTS
  VERBATIM
)

一个常见的错误是尝试使用缩进将生成器表达式拆分到多行

# WRONG: New lines and spaces all treated as argument separators, so the
# generator expression is split and not recognized correctly.
target_compile_definitions(tgt PRIVATE
  $<$<AND:
      $<CXX_COMPILER_ID:GNU>,
      $<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,5>
    >:HAVE_5_OR_LATER>
)

同样,使用具有精心选择的名称的辅助变量来构建可读的表达式

set(is_gnu "$<CXX_COMPILER_ID:GNU>")
set(v5_or_later "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,5>")
set(meet_requirements "$<AND:${is_gnu},${v5_or_later}>")
target_compile_definitions(tgt PRIVATE
  "$<${meet_requirements}:HAVE_5_OR_LATER>"
)

调试

由于生成器表达式在构建系统的生成期间进行求值,而不是在处理 CMakeLists.txt 文件期间进行求值,因此无法使用 message() 命令检查其结果。一种可能的生成调试消息的方法是添加一个自定义目标

add_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo "$<...>")

运行 cmake 后,您可以构建 genexdebug 目标以打印 $<...> 表达式的结果(即运行命令 cmake --build ... --target genexdebug)。

另一种方法是使用 file(GENERATE) 将调试消息写入文件

file(GENERATE OUTPUT filename CONTENT "$<...>")

生成器表达式参考

注意

本参考与大多数 CMake 文档不同,因为它省略了诸如 conditionstringtarget 等占位符周围的尖括号 <...>。这样做是为了防止这些占位符被误解为生成器表达式。

条件表达式

生成器表达式的一类基本类别与条件逻辑相关。支持两种形式的条件生成器表达式

$<condition:true_string>

如果 condition1,则求值为 true_string;如果 condition 求值为 0,则求值为一个空字符串。对于 condition 的任何其他值,都会导致错误。

$<IF:condition,true_string,false_string>

版本 3.8 中新增。

如果 condition1,则求值为 true_string;如果 condition0,则求值为 false_string。对于 condition 的任何其他值,都会导致错误。

版本 3.28 中新增: 此生成器表达式会进行短路求值,以便当 condition1 时,false_string 中的生成器表达式不会求值;当 condition 为 0 时,true_string 中的生成器表达式不会求值。

通常,condition 本身就是一个生成器表达式。例如,以下表达式在使用 Debug 配置时扩展为 DEBUG_MODE,对于所有其他配置则扩展为空字符串

$<$<CONFIG:Debug>:DEBUG_MODE>

可以使用 $<BOOL:...> 生成器表达式来处理非布尔类型的 condition 值(除了 10 之外)

$<BOOL:string>

string转换为01。如果以下任何情况为真,则评估结果为0

  • string为空,

  • string不区分大小写地等于0FALSEOFFNNOIGNORENOTFOUND,或者

  • string以后缀-NOTFOUND结尾(区分大小写)。

否则评估结果为1

condition由CMake变量提供时,通常使用$<BOOL:...>生成器表达式

$<$<BOOL:${HAVE_SOME_FEATURE}>:-DENABLE_SOME_FEATURE>

逻辑运算符

支持常见的布尔逻辑运算符

$<AND:conditions>

其中conditions是一个用逗号分隔的布尔表达式列表,所有这些表达式都必须评估为10。如果所有条件都为1,则整个表达式评估结果为1。如果任何条件为0,则整个表达式评估结果为0

$<OR:conditions>

其中conditions是一个用逗号分隔的布尔表达式列表,所有这些表达式都必须评估为10。如果至少一个conditions1,则整个表达式评估结果为1。如果所有conditions都评估为0,则整个表达式评估结果为0

$<NOT:condition>

condition必须为01。如果condition1,则表达式的结果为0,否则为1

版本 3.28 中新增: 逻辑运算符短路,这样一旦可以确定返回值,参数列表中的生成器表达式将不会被评估。

主要比较表达式

CMake支持各种比较生成器表达式。本节介绍主要且最广泛使用的比较类型。其他更具体的比较类型将在下面单独的部分中进行介绍。

字符串比较

$<STREQUAL:string1,string2>

如果string1string2相等,则为1,否则为0。比较区分大小写。对于不区分大小写的比较,请与字符串转换生成器表达式结合使用。例如,如果${foo}BARBarbar等中的任何一个,则以下表达式评估结果为1

$<STREQUAL:$<UPPER_CASE:${foo}>,BAR>
$<EQUAL:value1,value2>

如果value1value2在数值上相等,则为1,否则为0

版本比较

$<VERSION_LESS:v1,v2>

如果v1的版本小于v2,则为1,否则为0

$<VERSION_GREATER:v1,v2>

如果v1的版本大于v2,则为1,否则为0

$<VERSION_EQUAL:v1,v2>

如果v1的版本与v2相同,则为1,否则为0

$<VERSION_LESS_EQUAL:v1,v2>

版本 3.7 中新增。

如果v1的版本小于或等于v2,则为1,否则为0

$<VERSION_GREATER_EQUAL:v1,v2>

版本 3.7 中新增。

如果v1的版本大于或等于v2,则为1,否则为0

字符串转换

$<LOWER_CASE:string>

string的内容转换为小写。

$<UPPER_CASE:string>

string的内容转换为大写。

$<MAKE_C_IDENTIFIER:...>

...的内容转换为C标识符。转换遵循与string(MAKE_C_IDENTIFIER)相同的行为。

列表表达式

本节中的大多数表达式都与list()命令密切相关,提供了相同的功能,但以生成器表达式的形式。

在以下每个与列表相关的生成器表达式中,如果该生成器表达式期望在list之后提供某些内容,则list中不能包含任何逗号。例如,表达式$<LIST:FIND,list,value>要求在list之后提供一个value。由于使用逗号分隔listvalue,因此list本身不能包含逗号。此限制不适用于list()命令,它仅特定于列表处理生成器表达式。

列表比较

$<IN_LIST:string,list>

版本 3.12 中新增。

如果 string 是用分号分隔的 list 中的一个项目,则返回 1,否则返回 0。它使用区分大小写的比较。

列表查询

$<LIST:LENGTH,list>

版本 3.27 中新增。

list 中项目的数量。

$<LIST:GET,list,index,...>

版本 3.27 中新增。

扩展到由 list 中的索引指定的项目列表。

$<LIST:SUBLIST,list,begin,length>

版本 3.27 中新增。

给定 list 的子列表。如果 length 为 0,则返回空列表。如果 length 为 -1 或列表小于 begin + length,则返回从 begin 开始的列表的剩余项目。

$<LIST:FIND,list,value>

版本 3.27 中新增。

list 中第一个具有指定 value 的项目的索引,如果 list 中不存在 value,则返回 -1。

列表转换

$<LIST:JOIN,list,glue>

版本 3.27 中新增。

list 转换为单个字符串,并在每个项目之间插入 glue 字符串的内容。从概念上讲,这与 $<JOIN:list,glue> 的操作相同,但两者在处理空项目方面具有不同的行为。$<LIST:JOIN,list,glue> 保留所有空项目,而 $<JOIN:list,glue> 从列表中删除所有空项目。

$<LIST:APPEND,list,item,...>

版本 3.27 中新增。

将每个 item 附加到 list 后。多个项目应以逗号分隔。

$<LIST:PREPEND,list,item,...>

版本 3.27 中新增。

将每个 item 插入到 list 的开头。如果有多个项目,则应以逗号分隔,并且前置项目的顺序将被保留。

$<LIST:INSERT,list,index,item,...>

版本 3.27 中新增。

item(或多个项目)插入到指定 index 位置的 list 中。多个项目应以逗号分隔。

指定超出范围的 index 是错误的。有效的索引为 0 到 N,其中 N 是列表的长度,包含 N 本身。空列表的长度为 0。

$<LIST:POP_BACK,list>

版本 3.27 中新增。

删除最后一个项目的 list

$<LIST:POP_FRONT,list>

版本 3.27 中新增。

删除第一个项目的 list

$<LIST:REMOVE_ITEM,list,value,...>

版本 3.27 中新增。

删除所有给定 value(或值)实例的 list。如果给出多个值,则应以逗号分隔。

$<LIST:REMOVE_AT,list,index,...>

版本 3.27 中新增。

删除每个给定 index 位置的项目的 list

$<LIST:REMOVE_DUPLICATES,list>

版本 3.27 中新增。

删除所有重复项目的 list。项目的相对顺序保持不变,但如果遇到重复项,则只保留第一个实例。结果与 $<REMOVE_DUPLICATES:list> 相同。

$<LIST:FILTER,list,INCLUDE|EXCLUDE,regex>

版本 3.27 中新增。

来自 list 的项目列表,这些项目匹配 (INCLUDE) 或不匹配 (EXCLUDE) 正则表达式 regex。结果与 $<FILTER:list,INCLUDE|EXCLUDE,regex> 相同。

$<LIST:TRANSFORM,list,ACTION[,SELECTOR]>

版本 3.27 中新增。

通过对所有项目或通过指定 SELECTOR 对选定的列表项目应用 ACTION 来转换 list

注意

TRANSFORM 子命令不会更改列表中项目的数量。如果指定了 SELECTOR,则只会更改某些项目,其他项目将保持与转换前相同。

ACTION 指定要应用于列表项目的动作。这些动作的语义与 list(TRANSFORM) 命令完全相同。ACTION 必须是以下之一

APPENDPREPEND

将指定的值附加或前置到列表的每个项目。

$<LIST:TRANSFORM,list,(APPEND|PREPEND),value[,SELECTOR]>
TOLOWERTOUPPER

将列表的每个项目转换为小写或大写字符。

$<LIST:TRANSFORM,list,(TOLOWER|TOUPPER)[,SELECTOR]>
STRIP

从列表的每个项目的开头和结尾删除空格。

$<LIST:TRANSFORM,list,STRIP[,SELECTOR]>
REPLACE

尽可能多次匹配正则表达式,并为列表的每个项目的匹配项替换替换表达式。

$<LIST:TRANSFORM,list,REPLACE,regular_expression,replace_expression[,SELECTOR]>

SELECTOR 确定将转换列表中的哪些项目。一次只能指定一种类型的选择器。给出时,SELECTOR 必须是以下之一

AT

指定索引列表。

$<LIST:TRANSFORM,list,ACTION,AT,index[,index...]>
FOR

指定一个范围,可以选择使用增量遍历该范围。

$<LIST:TRANSFORM,list,ACTION,FOR,start,stop[,step]>
REGEX

指定正则表达式。只有匹配正则表达式的项目才会被转换。

$<LIST:TRANSFORM,list,ACTION,REGEX,regular_expression>
$<JOIN:list,glue>

glue 字符串的内容连接 list,并在每个项目之间插入。从概念上讲,这与 $<LIST:JOIN,list,glue> 的操作相同,但两者在处理空项目方面具有不同的行为。$<LIST:JOIN,list,glue> 保留所有空项目,而 $<JOIN,list,glue> 从列表中删除所有空项目。

$<REMOVE_DUPLICATES:list>

版本 3.15 中新增。

删除给定 list 中的重复项目。项目的相对顺序保持不变,如果遇到重复项,则只保留第一个实例。结果与 $<LIST:REMOVE_DUPLICATES,list> 相同。

$<FILTER:list,INCLUDE|EXCLUDE,regex>

版本 3.15 中新增。

包含或删除与正则表达式 regex 匹配的 list 中的项目。结果与 $<LIST:FILTER,list,INCLUDE|EXCLUDE,regex> 相同。

列表排序

$<LIST:REVERSE,list>

版本 3.27 中新增。

项目顺序相反的 list

$<LIST:SORT,list[,(COMPARE:option|CASE:option|ORDER:option)]...>

版本 3.27 中新增。

根据指定的选项对 list 进行排序。

使用一个 COMPARE 选项来选择排序的比较方法

STRING

按字母顺序对字符串列表进行排序。如果未给出 COMPARE 选项,则这是默认行为。

FILE_BASENAME

按其基本名称对文件路径列表进行排序。

NATURAL

使用自然顺序对字符串列表进行排序(参见 strverscmp(3) 的手册页),以便将连续的数字作为整数进行比较。例如,如果选择了 NATURAL 比较,则以下列表 10.0 1.1 2.1 8.0 2.0 3.1 将排序为 1.1 2.0 2.1 3.1 8.0 10.0,而使用 STRING 比较则将排序为 1.1 10.0 2.0 2.1 3.1 8.0

使用其中一个 CASE 选项来选择区分大小写或不区分大小写的排序模式

区分大小写 (SENSITIVE)

列表项将以区分大小写的方式排序。如果未提供 CASE 选项,则这是默认行为。

不区分大小写 (INSENSITIVE)

列表项将以不区分大小写的方式排序。仅大小写不同的项目的顺序未指定。

要控制排序顺序,可以提供其中一个 ORDER 选项

升序 (ASCENDING)

按升序对列表进行排序。如果未提供 ORDER 选项,则这是默认行为。

降序 (DESCENDING)

按降序对列表进行排序。

选项可以以任何顺序指定,但多次指定同一选项是错误的。

$<LIST:SORT,list,CASE:SENSITIVE,COMPARE:STRING,ORDER:DESCENDING>

路径表达式

本节中的大多数表达式与 cmake_path() 命令密切相关,提供了相同的功能,但以生成器表达式的形式。

对于本节中的所有生成器表达式,路径都应采用 cmake 样式的格式。 $<PATH:CMAKE_PATH> 生成器表达式可用于将本地路径转换为 cmake 样式的路径。

路径比较

$<PATH_EQUAL:path1,path2>

版本 3.24 中新增。

比较两个路径的词法表示。对任何路径都不执行规范化。如果路径相等,则返回 1,否则返回 0

有关更多详细信息,请参阅 cmake_path(COMPARE)

路径查询

这些表达式提供了等效于 cmake_path() 命令的 Query 选项的生成时功能。所有路径都应采用 cmake 样式的格式。

$<PATH:HAS_*,path>

版本 3.24 中新增。

如果存在特定路径组件,则以下操作返回 1,否则返回 0。有关每个路径组件的含义,请参阅 路径结构和术语

$<PATH:HAS_ROOT_NAME,path>
$<PATH:HAS_ROOT_DIRECTORY,path>
$<PATH:HAS_ROOT_PATH,path>
$<PATH:HAS_FILENAME,path>
$<PATH:HAS_EXTENSION,path>
$<PATH:HAS_STEM,path>
$<PATH:HAS_RELATIVE_PART,path>
$<PATH:HAS_PARENT_PATH,path>

请注意以下特殊情况

  • 对于 HAS_ROOT_PATH,只有当 root-nameroot-directory 中至少有一个非空时,才会返回真值。

  • 对于 HAS_PARENT_PATH,根目录也被认为具有父级,该父级将是其自身。结果为真,除非路径仅由一个 文件名 组成。

$<PATH:IS_ABSOLUTE,path>

版本 3.24 中新增。

如果路径是 绝对路径,则返回 1,否则返回 0

$<PATH:IS_RELATIVE,path>

版本 3.24 中新增。

这将返回 IS_ABSOLUTE 的相反值。

$<PATH:IS_PREFIX[,NORMALIZE],path,input>

版本 3.24 中新增。

如果 pathinput 的前缀,则返回 1,否则返回 0

当指定 NORMALIZE 选项时,在检查之前会对 pathinput 进行 规范化

路径分解

这些表达式提供了等效于 cmake_path() 命令的 Decomposition 选项的生成时功能。所有路径都应采用 cmake 样式的格式。

$<PATH:GET_*,...>

版本 3.24 中新增。

以下操作从路径中检索不同的组件或组件组。有关每个路径组件的含义,请参阅 路径结构和术语

版本 3.27 中已更改: 所有操作现在都接受路径列表作为参数。当指定路径列表时,操作将应用于每个路径。

$<PATH:GET_ROOT_NAME,path...>
$<PATH:GET_ROOT_DIRECTORY,path...>
$<PATH:GET_ROOT_PATH,path...>
$<PATH:GET_FILENAME,path...>
$<PATH:GET_EXTENSION[,LAST_ONLY],path...>
$<PATH:GET_STEM[,LAST_ONLY],path...>
$<PATH:GET_RELATIVE_PART,path...>
$<PATH:GET_PARENT_PATH,path...>

如果路径中不存在请求的组件,则返回空字符串。

路径转换

这些表达式提供了等效于 cmake_path() 命令的 修改生成 选项的生成时功能。所有路径都应采用 cmake 样式的格式。

版本 3.27 中已更改: 所有操作现在都接受路径列表作为参数。当指定路径列表时,操作将应用于每个路径。

$<PATH:CMAKE_PATH[,NORMALIZE],path...>

版本 3.24 中新增。

返回 path。如果 path 是本地路径,则将其转换为使用正斜杠 (/) 的 cmake 样式路径。在 Windows 上,会考虑长文件名标记。

当指定 NORMALIZE 选项时,转换后会对路径进行 规范化

$<PATH:APPEND,path...,input,...>

版本 3.24 中新增。

返回所有 input 参数,这些参数使用 / 作为 directory-separator 附加到 path。根据 input,可能会丢弃 path 的值。

有关更多详细信息,请参阅 cmake_path(APPEND)

$<PATH:REMOVE_FILENAME,path...>

版本 3.24 中新增。

返回 path,其中已删除文件名组件(由 $<PATH:GET_FILENAME> 返回)。删除后,如果存在,则保留任何尾随的 directory-separator

有关更多详细信息,请参阅 cmake_path(REMOVE_FILENAME)

$<PATH:REPLACE_FILENAME,path...,input>

版本 3.24 中新增。

返回 path,其中文件名组件已替换为 input。如果 path 没有文件名组件(即 $<PATH:HAS_FILENAME> 返回 0),则 path 保持不变。

有关更多详细信息,请参阅 cmake_path(REPLACE_FILENAME)

$<PATH:REMOVE_EXTENSION[,LAST_ONLY],path...>

版本 3.24 中新增。

返回 path,其中已删除 扩展名(如果有)。

有关更多详细信息,请参阅 cmake_path(REMOVE_EXTENSION)

$<PATH:REPLACE_EXTENSION[,LAST_ONLY],path...,input>

版本 3.24 中新增。

返回 path,其中 扩展名 已替换为 input(如果有)。

有关更多详细信息,请参阅 cmake_path(REPLACE_EXTENSION)

$<PATH:NORMAL_PATH,path...>

版本 3.24 中新增。

返回根据 规范化 中描述的步骤规范化的 path

$<PATH:RELATIVE_PATH,path...,base_directory>

版本 3.24 中新增。

返回 path,已修改为使其相对于 base_directory 参数。

有关更多详细信息,请参阅 cmake_path(RELATIVE_PATH)

$<PATH:ABSOLUTE_PATH[,NORMALIZE],path...,base_directory>

版本 3.24 中新增。

path 作为绝对路径返回。如果 path 是相对路径($<PATH:IS_RELATIVE> 返回 1),则会相对于由 base_directory 参数指定的给定基目录对其进行计算。

当指定 NORMALIZE 选项时,路径计算后会对路径进行 规范化

有关更多详细信息,请参阅 cmake_path(ABSOLUTE_PATH)

Shell 路径

$<SHELL_PATH:...>

版本 3.4 中新增。

... 的内容转换为 shell 路径样式。例如,在 Windows shell 中,斜杠将转换为反斜杠,而在 MSYS shell 中,驱动器号将转换为 posix 路径。... 必须是绝对路径。

版本 3.14 中新增: ... 可以是 用分号分隔的路径列表,在这种情况下,每个路径都会被单独转换,并使用 shell 路径分隔符 (: 在 POSIX 上和 ; 在 Windows 上) 生成结果列表。请确保在 CMake 源代码中用双引号括起包含此生成器表达式的参数,以防止 ; 分割参数。

配置表达式

$<CONFIG>

配置名称。使用此表达式代替已弃用的 CONFIGURATION 生成器表达式。

$<CONFIG:cfgs>

如果配置是逗号分隔列表 cfgs 中的任何一个条目,则为 1,否则为 0。这是一个不区分大小写的比较。当此表达式在导入目标的属性上进行评估时,MAP_IMPORTED_CONFIG_<CONFIG> 中的映射也会被考虑在内。

版本 3.19 中已更改: 可以为 cfgs 指定多个配置。CMake 3.18 及更早版本仅接受单个配置。

$<OUTPUT_CONFIG:...>

版本 3.20 中新增。

仅在 add_custom_command()add_custom_target() 中作为参数的最外层生成器表达式有效。使用 Ninja Multi-Config 生成器时,... 中的生成器表达式将使用自定义命令的“输出配置”进行评估。对于其他生成器,... 的内容将正常评估。

$<COMMAND_CONFIG:...>

版本 3.20 中新增。

仅在 add_custom_command()add_custom_target() 中作为参数的最外层生成器表达式有效。使用 Ninja Multi-Config 生成器时,... 中的生成器表达式将使用自定义命令的“命令配置”进行评估。对于其他生成器,... 的内容将正常评估。

工具链和语言表达式

平台

$<PLATFORM_ID>

当前系统的 CMake 平台 ID。另请参阅 CMAKE_SYSTEM_NAME 变量。

$<PLATFORM_ID:platform_ids>

如果 CMake 的平台 ID 与逗号分隔列表 platform_ids 中的任何一个条目匹配,则为 1,否则为 0。另请参阅 CMAKE_SYSTEM_NAME 变量。

编译器版本

另请参阅 CMAKE_<LANG>_COMPILER_VERSION 变量,它与本小节中的表达式密切相关。

$<C_COMPILER_VERSION>

使用的 C 编译器的版本。

$<C_COMPILER_VERSION:version>

如果 C 编译器的版本与 version 匹配,则为 1,否则为 0

$<CXX_COMPILER_VERSION>

使用的 CXX 编译器的版本。

$<CXX_COMPILER_VERSION:version>

如果 C++ 编译器的版本与 version 匹配,则为 1,否则为 0

$<CUDA_COMPILER_VERSION>

版本 3.15 中新增。

使用的 CUDA 编译器的版本。

$<CUDA_COMPILER_VERSION:version>

版本 3.15 中新增。

如果 C++ 编译器的版本与 version 匹配,则为 1,否则为 0

$<OBJC_COMPILER_VERSION>

版本 3.16 中新增。

使用的 Objective-C 编译器的版本。

$<OBJC_COMPILER_VERSION:version>

版本 3.16 中新增。

如果 Objective-C 编译器的版本与 version 匹配,则为 1,否则为 0

$<OBJCXX_COMPILER_VERSION>

版本 3.16 中新增。

使用的 Objective-C++ 编译器的版本。

$<OBJCXX_COMPILER_VERSION:version>

版本 3.16 中新增。

如果 Objective-C++ 编译器的版本与 version 匹配,则为 1,否则为 0

$<Fortran_COMPILER_VERSION>

使用的 Fortran 编译器的版本。

$<Fortran_COMPILER_VERSION:version>

如果 Fortran 编译器的版本与 version 匹配,则为 1,否则为 0

$<HIP_COMPILER_VERSION>

版本 3.21 中新增。

使用的 HIP 编译器的版本。

$<HIP_COMPILER_VERSION:version>

版本 3.21 中新增。

如果 HIP 编译器的版本与 version 匹配,则为 1,否则为 0

$<ISPC_COMPILER_VERSION>

版本 3.19 中新增。

使用的 ISPC 编译器的版本。

$<ISPC_COMPILER_VERSION:version>

版本 3.19 中新增。

如果 ISPC 编译器的版本与 version 匹配,则为 1,否则为 0

编译器语言、ID 和前端变体

另请参阅 CMAKE_<LANG>_COMPILER_IDCMAKE_<LANG>_COMPILER_FRONTEND_VARIANT 变量,它们与本小节中的大多数表达式密切相关。

$<C_COMPILER_ID>

使用的 C 编译器的 CMake 编译器 ID。

$<C_COMPILER_ID:compiler_ids>

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 C 编译器的编译器 ID 与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

3.15 版本中的更改: 可以指定多个 compiler_ids。CMake 3.14 及更早版本仅接受单个编译器 ID。

$<CXX_COMPILER_ID>

使用的 C++ 编译器的 CMake 编译器 ID。

$<CXX_COMPILER_ID:compiler_ids>

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 C++ 编译器的编译器 ID 与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

3.15 版本中的更改: 可以指定多个 compiler_ids。CMake 3.14 及更早版本仅接受单个编译器 ID。

$<CUDA_COMPILER_ID>

版本 3.15 中新增。

使用的 CUDA 编译器的 CMake 编译器 ID。

$<CUDA_COMPILER_ID:compiler_ids>

版本 3.15 中新增。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 CUDA 编译器的编译器 ID 与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<OBJC_COMPILER_ID>

版本 3.16 中新增。

使用的 Objective-C 编译器的 CMake 编译器 ID。

$<OBJC_COMPILER_ID:compiler_ids>

版本 3.16 中新增。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 Objective-C 编译器的编译器 ID 与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<OBJCXX_COMPILER_ID>

版本 3.16 中新增。

使用的 Objective-C++ 编译器的 CMake 编译器 ID。

$<OBJCXX_COMPILER_ID:compiler_ids>

版本 3.16 中新增。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 Objective-C++ 编译器的编译器 ID 与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<Fortran_COMPILER_ID>

使用的 Fortran 编译器的 CMake 编译器 ID。

$<Fortran_COMPILER_ID:compiler_ids>

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 Fortran 编译器的编译器 ID 与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

3.15 版本中的更改: 可以指定多个 compiler_ids。CMake 3.14 及更早版本仅接受单个编译器 ID。

$<HIP_COMPILER_ID>

版本 3.21 中新增。

使用的 HIP 编译器的 CMake 编译器 ID。

$<HIP_COMPILER_ID:compiler_ids>

版本 3.21 中新增。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 HIP 编译器的编译器 ID 与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<ISPC_COMPILER_ID>

版本 3.19 中新增。

使用的 ISPC 编译器的 CMake 编译器 ID。

$<ISPC_COMPILER_ID:compiler_ids>

版本 3.19 中新增。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 ISPC 编译器的编译器 ID 与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<C_COMPILER_FRONTEND_VARIANT>

3.30 版本中添加。

使用的 C 编译器的 CMake 编译器前端变体。

$<C_COMPILER_FRONTEND_VARIANT:compiler_ids>

3.30 版本中添加。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 C 编译器的编译器前端变体与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<CXX_COMPILER_FRONTEND_VARIANT>

3.30 版本中添加。

使用的 C++ 编译器的 CMake 编译器前端变体。

$<CXX_COMPILER_FRONTEND_VARIANT:compiler_ids>

3.30 版本中添加。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 C++ 编译器的编译器前端变体与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<CUDA_COMPILER_FRONTEND_VARIANT>

3.30 版本中添加。

使用的 CUDA 编译器的 CMake 编译器 ID。

$<CUDA_COMPILER_FRONTEND_VARIANT:compiler_ids>

3.30 版本中添加。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 CUDA 编译器的编译器前端变体与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<OBJC_COMPILER_FRONTEND_VARIANT>

3.30 版本中添加。

使用的 Objective-C 编译器的 CMake 编译器前端变体。

$<OBJC_COMPILER_FRONTEND_VARIANT:compiler_ids>

3.30 版本中添加。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 Objective-C 编译器的编译器前端变体与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<OBJCXX_COMPILER_FRONTEND_VARIANT>

3.30 版本中添加。

使用的 Objective-C++ 编译器的 CMake 编译器前端变体。

$<OBJCXX_COMPILER_FRONTEND_VARIANT:compiler_ids>

3.30 版本中添加。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 Objective-C++ 编译器的编译器前端变体与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<Fortran_COMPILER_FRONTEND_VARIANT>

3.30 版本中添加。

使用的 Fortran 编译器的 CMake 编译器 ID。

$<Fortran_COMPILER_FRONTEND_VARIANT:compiler_ids>

3.30 版本中添加。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 Fortran 编译器的编译器前端变体与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<HIP_COMPILER_FRONTEND_VARIANT>

3.30 版本中添加。

使用的 HIP 编译器的 CMake 编译器 ID。

$<HIP_COMPILER_FRONTEND_VARIANT:compiler_ids>

3.30 版本中添加。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 HIP 编译器的编译器前端变体与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<ISPC_COMPILER_FRONTEND_VARIANT>

3.30 版本中添加。

使用的 ISPC 编译器的 CMake 编译器 ID。

$<ISPC_COMPILER_FRONTEND_VARIANT:compiler_ids>

3.30 版本中添加。

其中 compiler_ids 是一个逗号分隔的列表。如果 CMake 的 ISPC 编译器的编译器前端变体与 compiler_ids 中的任何一个条目匹配,则为 1,否则为 0

$<COMPILE_LANGUAGE>

3.3 版本中添加。

评估编译选项时源文件的编译语言。有关此生成器表达式的可移植性的说明,请参见 相关的布尔表达式 $<COMPILE_LANGUAGE:language>

$<COMPILE_LANGUAGE:languages>

3.3 版本中添加。

3.15 版本中的更改: 可以为 languages 指定多种语言。CMake 3.14 及更早版本仅接受一种语言。

当编译单元使用的语言与 languages 中的任何一个逗号分隔的条目匹配时,则为 1,否则为 0。此表达式可用于为特定语言的源文件指定编译选项、编译定义和包含目录。例如

add_executable(myapp main.cpp foo.c bar.cpp zot.cu)
target_compile_options(myapp
  PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
)
target_compile_definitions(myapp
  PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
          $<$<COMPILE_LANGUAGE:CUDA>:COMPILING_CUDA>
)
target_include_directories(myapp
  PRIVATE $<$<COMPILE_LANGUAGE:CXX,CUDA>:/opt/foo/headers>
)

这指定仅对 C++ 使用 -fno-exceptions 编译选项、COMPILING_CXX 编译定义和 cxx_headers 包含目录(省略了编译器 ID 检查)。它还为 CUDA 指定了 COMPILING_CUDA 编译定义。

请注意,对于 Visual Studio 生成器Xcode,无法分别为 CCXX 语言表示目标范围的编译定义或包含目录。此外,对于 Visual Studio 生成器,无法分别为 CCXX 语言表示目标范围的标志。在这些生成器下,如果存在任何 C++ 源文件,则 C 和 C++ 源文件的表达式将使用 CXX 进行评估,否则将使用 C 进行评估。一种解决方法是为每种源文件语言创建单独的库。

add_library(myapp_c foo.c)
add_library(myapp_cxx bar.cpp)
target_compile_options(myapp_cxx PUBLIC -fno-exceptions)
add_executable(myapp main.cpp)
target_link_libraries(myapp myapp_c myapp_cxx)
$<COMPILE_LANG_AND_ID:language,compiler_ids>

版本 3.15 中新增。

1 当编译单元使用的语言与 language 匹配,并且 CMake 的 language 编译器的编译器 ID 与 compiler_ids 中的任何一个逗号分隔的条目匹配时,否则为 0。此表达式是 $<COMPILE_LANGUAGE:language>$<LANG_COMPILER_ID:compiler_ids> 组合的简写形式。此表达式可用于为目标中特定语言和编译器组合的源文件指定编译选项、编译定义和包含目录。例如

add_executable(myapp main.cpp foo.c bar.cpp zot.cu)
target_compile_definitions(myapp
  PRIVATE $<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:COMPILING_CXX_WITH_CLANG>
          $<$<COMPILE_LANG_AND_ID:CXX,Intel>:COMPILING_CXX_WITH_INTEL>
          $<$<COMPILE_LANG_AND_ID:C,Clang>:COMPILING_C_WITH_CLANG>
)

这指定了基于编译器 ID 和编译语言使用不同的编译定义。当 Clang 是 CXX 编译器时,此示例将具有 COMPILING_CXX_WITH_CLANG 编译定义,而当 Intel 是 CXX 编译器时,将具有 COMPILING_CXX_WITH_INTEL 编译定义。同样,当 C 编译器是 Clang 时,它将仅看到 COMPILING_C_WITH_CLANG 定义。

如果没有 COMPILE_LANG_AND_ID 生成器表达式,则相同逻辑将表示为

target_compile_definitions(myapp
  PRIVATE $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:AppleClang,Clang>>:COMPILING_CXX_WITH_CLANG>
          $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:Intel>>:COMPILING_CXX_WITH_INTEL>
          $<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:Clang>>:COMPILING_C_WITH_CLANG>
)

编译特性

$<COMPILE_FEATURES:features>

版本 3.1 中新增。

其中 features 是一个逗号分隔的列表。如果所有 features 都可用于“head”目标,则评估结果为 1,否则为 0。如果在评估目标的链接实现时使用此表达式,并且任何依赖项传递地增加了“head”目标所需的 C_STANDARDCXX_STANDARD,则会报告错误。有关编译特性的信息以及受支持编译器的列表,请参阅 cmake-compile-features(7) 手册。

编译上下文

$<COMPILE_ONLY:...>

版本 3.27 中新增。

收集 传递编译属性 时,... 的内容,否则为空字符串。这旨在用于 INTERFACE_LINK_LIBRARIESLINK_LIBRARIES 目标属性中,通常通过 target_link_libraries() 命令填充。提供编译使用需求,而没有任何链接需求。

用例包括仅限头文件的用法,其中所有用法都已知没有链接需求(例如,全部-inline 或 C++ 模板库)。

请注意,正确评估此表达式需要将策略 CMP0099 设置为 NEW

链接器语言和 ID

版本 3.18 中新增。

评估链接选项时目标的链接语言。有关此生成器表达式的可移植性的说明,请参阅 相关的布尔表达式 $<LINK_LANGUAGE:languages>

注意

链接库属性不支持此生成器表达式,以避免由于这些属性的双重评估而导致的副作用。

版本 3.18 中新增。

当链接步骤使用的语言与 language 匹配,并且语言链接器的 CMake 编译器 ID 与 compiler_ids 中的任何一个逗号分隔的条目匹配时,为 1,否则为 0。此表达式是 $<LINK_LANGUAGE:language>$<LANG_COMPILER_ID:compiler_ids> 组合的简写形式。此表达式可用于为目标中特定语言和链接器组合指定链接库、链接选项、链接目录和链接依赖项。例如

add_library(libC_Clang ...)
add_library(libCXX_Clang ...)
add_library(libC_Intel ...)
add_library(libCXX_Intel ...)

add_executable(myapp main.c)
if (CXX_CONFIG)
  target_sources(myapp PRIVATE file.cxx)
endif()
target_link_libraries(myapp
  PRIVATE $<$<LINK_LANG_AND_ID:CXX,Clang,AppleClang>:libCXX_Clang>
          $<$<LINK_LANG_AND_ID:C,Clang,AppleClang>:libC_Clang>
          $<$<LINK_LANG_AND_ID:CXX,Intel>:libCXX_Intel>
          $<$<LINK_LANG_AND_ID:C,Intel>:libC_Intel>)

这指定了基于编译器 ID 和链接语言使用不同的链接库。当 ClangAppleClangCXX 链接器时,此示例将具有目标 libCXX_Clang 作为链接依赖项,而当 IntelCXX 链接器时,将具有 libCXX_Intel 作为链接依赖项。同样,当 C 链接器是 ClangAppleClang 时,目标 libC_Clang 将被添加为链接依赖项,而当 IntelC 链接器时,目标 libC_Intel 将被添加为链接依赖项。

请参阅 $<LINK_LANGUAGE:language> 相关的说明,了解有关此生成器表达式的使用限制。

依赖于目标的表达式

目标元数据

这些表达式查找有关目标的信息。

$<TARGET_EXISTS:tgt>

版本 3.12 中新增。

如果 tgt 作为 CMake 目标存在,则为 1,否则为 0

$<TARGET_NAME_IF_EXISTS:tgt>

版本 3.12 中新增。

如果目标存在,则为目标名称 tgt,否则为空字符串。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_NAME:tgt>

按原样编写目标名称 tgt。这表示 tgt 是较大表达式中目标的名称,如果将目标导出到多个依赖导出集,则需要此操作。tgt 文本必须是目标的字面名称;它不能包含生成器表达式。目标不必存在。

$<TARGET_POLICY:policy>

如果在创建“头部”目标时 policyNEW,则为 1,否则为 0。如果未设置 policy,则会发出该策略的警告消息。此生成器表达式仅适用于部分策略。

目标属性

这些表达式查找 目标属性 的值。

$<TARGET_PROPERTY:tgt,prop>

目标 tgt 上属性 prop 的值,如果属性未设置,则为空。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

版本 3.26 中更改: 在评估 目标使用需求(通常在 INTERFACE_* 目标属性中)期间遇到时,tgt 名称的查找发生在指定需求的目标的目录中,而不是评估表达式的目标的目录中。

版本 3.31 中更改: 传递接口属性的生成器表达式,例如 $<TARGET_PROPERTY:target,INTERFACE_*>,现在可以正确处理嵌套生成器表达式中的重复评估。以前,由于传递闭包的优化,这些重复评估会返回空值。此更改确保非联合操作的一致评估。

$<TARGET_PROPERTY:prop>

评估表达式的目标的属性 prop 的值,如果属性未设置,则为空。请注意,对于 目标使用需求 中的生成器表达式,这是使用目标,而不是指定需求的目标。

这些表达式对某些属性具有特殊的评估规则

目标构建规范属性

这些评估为 分号分隔列表,表示目标本身上的值与目标的 LINK_LIBRARIES 命名的目标上的相应 目标使用需求 的值的并集。

LINK_LIBRARIES本身的评估不是传递性的。

目标使用需求属性

这些属性评估为一个用分号分隔的列表,表示目标本身的值与目标的INTERFACE_LINK_LIBRARIES指定的其他目标上相同属性的值的并集。

INTERFACE_LINK_LIBRARIES本身的评估不是传递性的。

自定义传递属性

3.30 版本中添加。

这些属性在评估期间按如下方式处理:

如果一个PROP同时由TRANSITIVE_COMPILE_PROPERTIESTRANSITIVE_LINK_PROPERTIES命名,则后者优先。

兼容接口属性

这些属性评估为一个单一值,该值组合自目标本身、目标的LINK_LIBRARIES指定的其他目标,以及链接目标的INTERFACE_LINK_LIBRARIES的传递闭包。来自多个目标的兼容接口属性的值根据定义它的COMPATIBLE_INTERFACE_*属性所需的兼容性类型进行组合。

目标构件

这些表达式查找与给定目标tgt关联的构件信息。除非另有说明,否则这可以是任何运行时构件,即

在下文中,“tgt 文件名”指的是 tgt 二进制文件的名称。这必须与“目标名称”区分开来,目标名称仅仅是字符串 tgt

$<TARGET_FILE:tgt>

tgt 二进制文件的完整路径。

请注意,除非该表达式用于 add_custom_command()add_custom_target(),否则 tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_FILE_BASE_NAME:tgt>

版本 3.15 中新增。

tgt 的基本名称,即 $<TARGET_FILE_NAME:tgt> 去除前缀和后缀后的名称。例如,如果 tgt 文件名为 libbase.so,则基本名称为 base

另请参阅 OUTPUT_NAMEARCHIVE_OUTPUT_NAMELIBRARY_OUTPUT_NAMERUNTIME_OUTPUT_NAME 目标属性及其配置特定的变体 OUTPUT_NAME_<CONFIG>ARCHIVE_OUTPUT_NAME_<CONFIG>LIBRARY_OUTPUT_NAME_<CONFIG>RUNTIME_OUTPUT_NAME_<CONFIG>

<CONFIG>_POSTFIXDEBUG_POSTFIX 目标属性也可以考虑在内。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_FILE_PREFIX:tgt>

版本 3.15 中新增。

tgt 文件名前缀(例如 lib)。

另请参阅 PREFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_FILE_SUFFIX:tgt>

版本 3.15 中新增。

tgt 文件名后缀(扩展名,例如 .so.exe)。

另请参阅 SUFFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_FILE_NAME:tgt>

tgt 文件名。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项(参见策略 CMP0112)。

$<TARGET_FILE_DIR:tgt>

tgt 二进制文件所在的目录。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项(参见策略 CMP0112)。

$<TARGET_IMPORT_FILE:tgt>

版本 3.27 中新增。

链接器导入文件的完整路径。在 DLL 平台上,它将是 .lib 文件。对于 AIX 上的可执行文件和 macOS 上的共享库,它可以分别是 .imp.tbd 导入文件,具体取决于 ENABLE_EXPORTS 属性的值。

当目标没有关联的导入文件时,此表达式扩展为空字符串。

$<TARGET_IMPORT_FILE_BASE_NAME:tgt>

版本 3.27 中新增。

目标 tgt 的链接器导入文件的基本名称,去除前缀和后缀。例如,如果目标文件名是 libbase.tbd,则基本名称是 base

另请参阅 OUTPUT_NAMEARCHIVE_OUTPUT_NAME 目标属性及其配置特定的变体 OUTPUT_NAME_<CONFIG>ARCHIVE_OUTPUT_NAME_<CONFIG>

<CONFIG>_POSTFIXDEBUG_POSTFIX 目标属性也可以考虑在内。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_IMPORT_FILE_PREFIX:tgt>

版本 3.27 中新增。

目标 tgt 的导入文件前缀。

另请参阅 IMPORT_PREFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_IMPORT_FILE_SUFFIX:tgt>

版本 3.27 中新增。

目标 tgt 的导入文件后缀。

后缀对应于文件扩展名(例如 .lib.tbd)。

另请参阅 IMPORT_SUFFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_IMPORT_FILE_NAME:tgt>

版本 3.27 中新增。

目标 tgt 的导入文件名。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_IMPORT_FILE_DIR:tgt>

版本 3.27 中新增。

目标 tgt 的导入文件的目录。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_FILE:tgt>

链接到 tgt 目标时使用的文件。这通常是 tgt 表示的库(.a.lib.so),但在 DLL 平台上的共享库中,它将是与 DLL 关联的 .lib 导入库。

版本 3.27 中新增: 在 macOS 上,它可能是与共享库关联的 .tbd 导入文件,具体取决于 ENABLE_EXPORTS 属性的值。

此生成器表达式等效于 $<TARGET_LINKER_LIBRARY_FILE>$<TARGET_LINKER_IMPORT_FILE> 生成器表达式,具体取决于目标和平台的特性。

$<TARGET_LINKER_FILE_BASE_NAME:tgt>

版本 3.15 中新增。

用于链接目标 tgt 的文件的基名称,即 $<TARGET_LINKER_FILE_NAME:tgt> 去掉前缀和后缀。例如,如果目标文件名是 libbase.a,则基名称为 base

另请参阅 OUTPUT_NAMEARCHIVE_OUTPUT_NAMELIBRARY_OUTPUT_NAME 目标属性及其特定于配置的变体 OUTPUT_NAME_<CONFIG>ARCHIVE_OUTPUT_NAME_<CONFIG>LIBRARY_OUTPUT_NAME_<CONFIG>

还可以考虑 <CONFIG>_POSTFIXDEBUG_POSTFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_FILE_PREFIX:tgt>

版本 3.15 中新增。

用于链接目标 tgt 的文件的前缀。

另请参阅 PREFIXIMPORT_PREFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_FILE_SUFFIX:tgt>

版本 3.15 中新增。

用于链接的文件的后缀,其中 tgt 是目标的名称。

后缀对应于文件扩展名(例如“.so”或“.lib”)。

另请参阅 SUFFIXIMPORT_SUFFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_FILE_NAME:tgt>

用于链接目标 tgt 的文件的名称。

请注意,tgt 不会作为此表达式求值的目标的依赖项添加(请参阅策略 CMP0112)。

$<TARGET_LINKER_FILE_DIR:tgt>

用于链接目标 tgt 的文件的目录。

请注意,tgt 不会作为此表达式求值的目标的依赖项添加(请参阅策略 CMP0112)。

$<TARGET_LINKER_LIBRARY_FILE:tgt>

版本 3.27 中新增。

当链接到 tgt 目标时使用库本身,而不是导入文件时使用的文件。这通常是 tgt 表示的库(.a.so.dylib)。因此,在 DLL 平台上,它将为空字符串。

$<TARGET_LINKER_LIBRARY_FILE_BASE_NAME:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的库文件的基名称,即 $<TARGET_LINKER_LIBRARY_FILE_NAME:tgt> 去掉前缀和后缀。例如,如果目标文件名是 libbase.a,则基名称为 base

另请参阅 OUTPUT_NAMEARCHIVE_OUTPUT_NAMELIBRARY_OUTPUT_NAME 目标属性及其特定于配置的变体 OUTPUT_NAME_<CONFIG>ARCHIVE_OUTPUT_NAME_<CONFIG>LIBRARY_OUTPUT_NAME_<CONFIG>

还可以考虑 <CONFIG>_POSTFIXDEBUG_POSTFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_LIBRARY_FILE_PREFIX:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的库文件的前缀。

另请参阅 PREFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_LIBRARY_FILE_SUFFIX:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的库文件的后缀。

后缀对应于文件扩展名(例如“.a”或“.dylib”)。

另请参阅 SUFFIX 目标属性。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_LIBRARY_FILE_NAME:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的库文件的名称。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_LIBRARY_FILE_DIR:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的库文件的目录。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_IMPORT_FILE:tgt>

版本 3.27 中新增。

链接到目标 tgt 时使用的导入文件。这通常是 tgt 所表示的导入文件(.lib.tbd)。因此,当链接步骤中不涉及导入文件时,将返回空字符串。

$<TARGET_LINKER_IMPORT_FILE_BASE_NAME:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的导入文件的基名称,即 $<TARGET_LINKER_IMPORT_FILE_NAME:tgt> 去掉前缀和后缀。例如,如果目标文件名是 libbase.tbd,则基名称为 base

另请参见目标属性 OUTPUT_NAMEARCHIVE_OUTPUT_NAME,以及它们特定于配置的变体 OUTPUT_NAME_<CONFIG>ARCHIVE_OUTPUT_NAME_<CONFIG>

还可以考虑目标属性 <CONFIG>_POSTFIXDEBUG_POSTFIX

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_IMPORT_FILE_PREFIX:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的导入文件的前缀。

另请参见目标属性 IMPORT_PREFIX

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_IMPORT_FILE_SUFFIX:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的导入文件的后缀。

后缀对应于文件扩展名(例如“.lib”或“.tbd”)。

另请参见目标属性 IMPORT_SUFFIX

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_IMPORT_FILE_NAME:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的导入文件的名称。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_LINKER_IMPORT_FILE_DIR:tgt>

版本 3.27 中新增。

用于链接目标 tgt 的导入文件的目录。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_SONAME_FILE:tgt>

包含 soname 的文件(.so.3),其中 tgt 是目标的名称。

$<TARGET_SONAME_FILE_NAME:tgt>

包含 soname 的文件的名称(.so.3)。

请注意,tgt 不会作为此表达式求值所在目标的依赖项添加(请参见策略 CMP0112)。

$<TARGET_SONAME_FILE_DIR:tgt>

包含 soname 的文件的目录(.so.3)。

请注意,tgt 不会作为此表达式求值所在目标的依赖项添加(请参见策略 CMP0112)。

$<TARGET_SONAME_IMPORT_FILE:tgt>

版本 3.27 中新增。

包含 soname 的导入文件(.3.tbd),其中 tgt 是目标的名称。

$<TARGET_SONAME_IMPORT_FILE_NAME:tgt>

版本 3.27 中新增。

包含 soname 的导入文件的名称(.3.tbd)。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_SONAME_IMPORT_FILE_DIR:tgt>

版本 3.27 中新增。

包含 soname 的导入文件的目录(.3.tbd)。

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_PDB_FILE:tgt>

版本 3.1 中新增。

链接器生成的程序数据库文件 (.pdb) 的完整路径,其中 tgt 是目标的名称。

另请参见目标属性 PDB_NAMEPDB_OUTPUT_DIRECTORY,以及它们特定于配置的变体 PDB_NAME_<CONFIG>PDB_OUTPUT_DIRECTORY_<CONFIG>

$<TARGET_PDB_FILE_BASE_NAME:tgt>

版本 3.15 中新增。

链接器生成的程序数据库文件 (.pdb) 的基名称,其中 tgt 是目标的名称。

基名称对应于目标 PDB 文件名(请参见 $<TARGET_PDB_FILE_NAME:tgt>)去掉前缀和后缀。例如,如果目标文件名是 base.pdb,则基名称为 base

另请参见目标属性 PDB_NAME,以及它特定于配置的变体 PDB_NAME_<CONFIG>

还可以考虑目标属性 <CONFIG>_POSTFIXDEBUG_POSTFIX

请注意,tgt 不会被添加为评估此表达式的目标的依赖项。

$<TARGET_PDB_FILE_NAME:tgt>

版本 3.1 中新增。

链接器生成的程序数据库文件 (.pdb) 的名称。

请注意,tgt 不会作为此表达式求值所在目标的依赖项添加(请参见策略 CMP0112)。

$<TARGET_PDB_FILE_DIR:tgt>

版本 3.1 中新增。

链接器生成的程序数据库文件 (.pdb) 的目录。

请注意,tgt 不会作为此表达式求值所在目标的依赖项添加(请参见策略 CMP0112)。

$<TARGET_BUNDLE_DIR:tgt>

在 3.9 版本中添加。

捆绑包目录的完整路径(/path/to/my.app/path/to/my.framework/path/to/my.bundle),其中 tgt 是目标的名称。

请注意,tgt 不会被添加为该表达式求值所针对的目标的依赖项(参见策略 CMP0112)。

$<TARGET_BUNDLE_DIR_NAME:tgt>

版本 3.24 中新增。

包目录的名称(my.appmy.frameworkmy.bundle),其中 tgt 是目标的名称。

请注意,tgt 不会被添加为该表达式求值所针对的目标的依赖项(参见策略 CMP0112)。

$<TARGET_BUNDLE_CONTENT_DIR:tgt>

在 3.9 版本中添加。

包内容目录的完整路径,其中 tgt 是目标的名称。对于 macOS SDK,它指向 /path/to/my.app/Contents/path/to/my.framework/path/to/my.bundle/Contents。对于所有其他 SDK(例如 iOS),由于扁平包结构,它指向 /path/to/my.app/path/to/my.framework/path/to/my.bundle

请注意,tgt 不会被添加为该表达式求值所针对的目标的依赖项(参见策略 CMP0112)。

$<TARGET_OBJECTS:tgt>

版本 3.1 中新增。

构建 tgt 产生的对象列表。这通常用于 对象库 目标。

$<TARGET_RUNTIME_DLLS:tgt>

版本 3.21 中新增。

目标在运行时依赖的 DLL 列表。这由目标的传递依赖项中所有 SHARED 目标的位置决定。如果只需要 DLL 的目录,请参见 TARGET_RUNTIME_DLL_DIRS 生成器表达式。在除可执行文件、SHARED 库和 MODULE 库之外的目标上使用此生成器表达式是一个错误。**在非 DLL 平台上,此表达式始终求值为一个空字符串**。

此生成器表达式可用于在 POST_BUILD 自定义命令中使用 cmake -E copy -t 命令将目标依赖的所有 DLL 复制到其输出目录中。例如

find_package(foo CONFIG REQUIRED) # package generated by install(EXPORT)

add_executable(exe main.c)
target_link_libraries(exe PRIVATE foo::foo foo::bar)
add_custom_command(TARGET exe POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy -t $<TARGET_FILE_DIR:exe> $<TARGET_RUNTIME_DLLS:exe>
  COMMAND_EXPAND_LISTS
)

注意

导入的目标 仅在它们知道其 .dll 文件的位置时才受支持。导入的 SHARED 库必须将其 IMPORTED_LOCATION 设置为其 .dll 文件。有关详细信息,请参阅 add_library 导入库 部分。许多 查找模块 生成具有 UNKNOWN 类型的导入目标,因此将被忽略。

在支持运行时路径(RPATH)的平台上,请参阅 INSTALL_RPATH 目标属性。在 Apple 平台上,请参阅 INSTALL_NAME_DIR 目标属性。

$<TARGET_RUNTIME_DLL_DIRS:tgt>

版本 3.27 中新增。

包含目标在运行时依赖的 DLL 的目录列表(参见 TARGET_RUNTIME_DLLS)。这由目标的传递依赖项中所有 SHARED 目标的位置决定。在除可执行文件、SHARED 库和 MODULE 库之外的目标上使用此生成器表达式是一个错误。**在非 DLL 平台上,此表达式始终求值为一个空字符串**。

此生成器表达式例如可用于使用 file(GENERATE) 创建批处理文件,该文件相应地设置 PATH 环境变量。

导出和安装表达式

$<INSTALL_INTERFACE:...>

当属性使用 install(EXPORT) 导出时,... 的内容,否则为空。

$<BUILD_INTERFACE:...>

当属性使用 export() 导出时,或当目标在同一构建系统中被另一个目标使用时,... 的内容。否则扩展为空字符串。

$<BUILD_LOCAL_INTERFACE:...>

版本 3.26 中新增。

当目标在同一构建系统中被另一个目标使用时,... 的内容。否则扩展为空字符串。

$<INSTALL_PREFIX>

当目标通过 install(EXPORT) 导出时,或在 INSTALL_NAME_DIR 属性或 install(RUNTIME_DEPENDENCY_SET)INSTALL_NAME_DIR 参数中求值时,安装前缀的内容,否则为空。

版本 3.27 中已更改: install(CODE) 的 code 参数或 install(SCRIPT) 的 file 参数中求值时,求值为安装前缀的内容。

多级表达式求值

$<GENEX_EVAL:expr>

版本 3.12 中新增。

在当前上下文中将 expr 评估为生成器表达式的结果。这使得能够使用其评估结果本身为生成器表达式的生成器表达式。

$<TARGET_GENEX_EVAL:tgt,expr>

版本 3.12 中新增。

tgt 目标的上下文中将 expr 评估为生成器表达式的结果。这使得能够使用本身包含生成器表达式的自定义目标属性。

当您想要管理支持生成器表达式的自定义属性时,能够评估生成器表达式非常有用。例如

add_library(foo ...)

set_property(TARGET foo PROPERTY
  CUSTOM_KEYS $<$<CONFIG:DEBUG>:FOO_EXTRA_THINGS>
)

add_custom_target(printFooKeys
  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:foo,CUSTOM_KEYS>
)

`printFooKeys` 自定义命令的这个朴素实现是错误的,因为 `CUSTOM_KEYS` 目标属性没有被评估,其内容被原样传递(即 `$<$<CONFIG:DEBUG>:FOO_EXTRA_THINGS>`)。

为了获得预期结果(即如果配置为 `Debug` 则为 `FOO_EXTRA_THINGS`),需要评估 `$<TARGET_PROPERTY:foo,CUSTOM_KEYS>` 的输出。

add_custom_target(printFooKeys
  COMMAND ${CMAKE_COMMAND} -E
    echo $<TARGET_GENEX_EVAL:foo,$<TARGET_PROPERTY:foo,CUSTOM_KEYS>>
)

转义字符

这些表达式计算结果为特定的字符串字面量。在需要阻止它们具有其特殊含义的地方,使用它们代替实际的字符串字面量。

$<ANGLE-R>

一个字面量 `>`。例如,用于比较包含 `>` 的字符串。

$<COMMA>

一个字面量 `,`。例如,用于比较包含 `,` 的字符串。

$<SEMICOLON>

一个字面量 `;`。用于阻止在带有 `;` 的参数上进行列表展开。

$<QUOTE>

3.30 版本中添加。

一个字面量 `"`。用于允许在生成器表达式中使用字符串字面量引号。

已弃用的表达式

$<CONFIGURATION>

配置名称。自 CMake 3.0 起已弃用。请改用 CONFIG