target_precompile_headers

在 3.16 版本中添加。

添加要预编译的头文件列表。

预编译头文件可以通过创建某些头文件的局部处理版本来加快编译速度,然后在编译期间使用该版本,而不是重复解析原始头文件。

主表单

target_precompile_headers(<target>
  <INTERFACE|PUBLIC|PRIVATE> [header1...]
  [<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])

该命令将头文件添加到 PRECOMPILE_HEADERS 和/或 INTERFACE_PRECOMPILE_HEADERS <target> 的目标属性中。指定的 <target> 必须通过以下命令(例如 add_executable()add_library())创建,并且不能是 别名目标

必需 INTERFACEPUBLICPRIVATE 关键字来指定以下参数的 范围PRIVATEPUBLIC 项将填充 PRECOMPILE_HEADERS <target> 的属性。 PUBLICINTERFACE 项将填充 INTERFACE_PRECOMPILE_HEADERS <target> 的属性(导入目标 仅支持 INTERFACE 项)。对同一 <target> 的重复调用将按照调用的顺序追加项。

项目通常应避免为将exported的目标使用 PUBLICINTERFACE,或者它们至少应使用 $<BUILD_INTERFACE:...> 生成器表达式来防止在安装的已导出目标中出现预编译头文件。目标的使用者通常应控制自己使用的预编译头文件,而不是被使用目标强制使用预编译头文件(因为预编译头文件通常不是使用要求)。一个引人注目的例外是创建 interface 库 来在一个位置定义常用的一组预编译头文件,然后其他目标私下链接到该 interface 库。在这种情况下,interface 库特别存在于将预编译头文件传播到使用者,而使用者依然有效地处于控制中,因为使用者决定是否链接到 interface 库。

将使用头文件列表生成名为 cmake_pch.h|xx 的头文件,此头文件用于生成预编译头文件(.pch.gch.pchi)工件。将 cmake_pch.h|xx 头文件强制性地包含到所有源文件(GCC 为 -include,MSVC 为 /FI),因此源文件不需要带有 #include "pch.h"

使用尖括号指定(例如 <unordered_map>)或使用显式双引号(对 cmake-language(7) 转义,例如 [["other_header.h"]])的头文件名将按原样处理,编译器必须可访问包含目录才能找到它们。其他头文件名(例如 project_header.h)将被解释为相对于当前源目录(例如 CMAKE_CURRENT_SOURCE_DIR),并且将按绝对路径包含。例如

target_precompile_headers(myTarget
  PUBLIC
    project_header.h
  PRIVATE
    [["other_header.h"]]
    <unordered_map>
)

有关定义构建系统属性的更多信息。

target_precompile_headers 参数可以使用带 $<...> 语法的生成器表达式。查看 cmake-generator-expressions(7) 手册了解可用的表达式。$<COMPILE_LANGUAGE:...> 生成器表达式对仅针对一种语言(例如,CXX 但不针对 C)指定语言特定的预编译标头非常有用。在这种情况下,没有明确放在双引号或尖括号中的头文件名称必须由绝对路径指定。另外,在生成器表达式中指定尖括号时,务必将结束的 > 编码为 $<ANGLE-R>。例如

target_precompile_headers(mylib PRIVATE
  "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_only.h>"
  "$<$<COMPILE_LANGUAGE:C>:<stddef.h$<ANGLE-R>>"
  "$<$<COMPILE_LANGUAGE:CXX>:<cstddef$<ANGLE-R>>"
)

重用预编译标头

此命令还支持第二个签名,该签名可用于指定某目标重用其他目标的预编译标头文件工件,而不是生成其自己的标头

target_precompile_headers(<target> REUSE_FROM <other_target>)

此形式设置 PRECOMPILE_HEADERS_REUSE_FROM 属性为 <other_target> 并添加一个依赖项,使 <target> 依赖于 <other_target>。如果 PRECOMPILE_HEADERS 属性在使用 REUSE_FROM 形式时已设置,CMake 将停止并显示错误。

注意

REUSE_FROM 形式对 <target><other_target> 要求具有相同的一组编译器选项、编译器标志和编译器定义。某些编译器(如 GCC)在无法使用预编译标头文件时可能发出警告(-Winvalid-pch)。

另请参阅