cmake-generator-expressions(7)

简介

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

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

这将根据使用的 C++ 编译器扩展为 /opt/include/GNU/opt/include/Clang 等。

生成器表达式允许在许多目标属性的上下文中使用,例如 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>
)

如果 CMAKE_CXX_COMPILER_VERSION 小于 4.2.0,则上述内容将扩展为 OLD_COMPILER

空格和引用

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

在使用 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_stringcondition 的任何其他值都会导致错误。

版本 3.28 新增: 此生成器表达式采用短路求值,因此当 condition1 时,false_string 中的生成器表达式不会被求值;当 condition0 时,true_string 中的生成器表达式不会被求值。

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

$<$<CONFIG:Debug>:DEBUG_MODE>

除了 10 之外的布尔值 condition 值可以通过用 $<BOOL:...> 生成器表达式包装来处理:

$<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 的项的索引,如果 value 不在 list 中,则为 -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(或多个项)插入到 list 中指定的 index 处。多个项应以逗号分隔。

指定超出范围的 index 是一个错误。有效索引是 0 到 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 版本中新增。

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

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

在 3.27 版本中新增。

通过将 ACTION 应用于所有列表项,或者通过指定 SELECTOR 应用于选定的列表项,来转换 list

注意

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

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

APPEND, PREPEND

在列表的每个项中添加、前置指定的值。

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

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

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

从列表的每个项中删除前导和尾随空格。

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

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

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

版本 4.1 中更改: ^ 锚点现在仅匹配输入元素的开头,而不是每个重复搜索的开头。请参阅策略 CMP0186

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>

listglue 字符串的内容插入到每个项之间,连接起来。这在概念上与 $<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 新增。

list 中包含或删除匹配正则表达式 regex 的项。结果与 $<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() 命令的 查询 选项等效的生成时功能。所有路径都预计为 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 至少有一个非空时,才会返回 true 结果。

  • 对于 HAS_PARENT_PATH,根目录也被视为具有父目录,即它本身。除路径仅包含 文件名 的情况外,结果为 true。

$<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() 命令的 分解 选项等效的生成时功能。所有路径都预计为 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:NATIVE_PATH[,NORMALIZE],path...>

4.0 版本新增。

返回转换为本机格式的 path,带有平台特定的斜杠(Windows 主机上为 \,其他地方为 /)。

当指定 NORMALIZE 选项时,路径在转换前会 规范化

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

在 3.24 版本中添加。

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

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

$<PATH:REMOVE_FILENAME,path...>

在 3.24 版本中添加。

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

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

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

在 3.24 版本中添加。

返回用 input 替换文件名组件的 path。如果 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 版本中添加。

返回替换了 扩展名(如果有)为 inputpath

有关更多详细信息,请参阅 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 源代码中将包含此 genex 的参数用双引号括起来,以免 ; 分割参数。

配置表达式

$<CONFIG>

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

$<CONFIG:cfgs>

如果配置是逗号分隔列表 cfgs 中的任何一个条目,则为 1,否则为 0。这是一个不区分大小写的比较。当此表达式在 IMPORTED 目标的属性上进行求值时,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:languages>

$<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++(编译器 ID 检查已省略)使用 -fno-exceptions 编译选项、COMPILING_CXX 编译定义和 cxx_headers 包含目录。它还为 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 新增。

当编译单元使用的语言与 language 匹配且 language 编译器的 CMake 编译器 ID 与逗号分隔的 compiler_ids 中的任何一个条目匹配时为 1,否则为 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>

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

目标属性

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

$<TARGET_PROPERTY:tgt,prop>

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

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

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

$<TARGET_PROPERTY:prop>

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

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

目标构建规范属性

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

4.1 版本中已更改:LINK_LIBRARIES 本身的评估现在是传递性的。请参阅策略 CMP0189

目标使用要求属性

这些评估为 分号分隔的列表,表示目标本身的值与目标 INTERFACE_LINK_LIBRARIES 命名的目标上相同属性的值的并集

4.1 版本中已更改:INTERFACE_LINK_LIBRARIES 本身的评估现在是传递性的。请参阅策略 CMP0189

自定义传递属性

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>

请注意,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 中添加。

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

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

$<TARGET_BUNDLE_DIR_NAME:tgt>

在 3.24 版本中添加。

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

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

$<TARGET_BUNDLE_CONTENT_DIR:tgt>

版本 3.9 中添加。

bundle 内容目录的完整路径,其中tgt是目标的名称。对于macOS SDK,它指向/path/to/my.app/Contents/path/to/my.framework/path/to/my.bundle/Contents。对于所有其他SDK(例如iOS),由于平面bundle结构,它指向/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 版本新增。

expr的内容在tgt目标的上下文中作为生成器表达式进行评估。这使得能够使用本身包含生成器表达式的自定义目标属性。

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

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