target_precompile_headers¶
3.16 版新增。
添加要预编译的头文件列表。
预编译头文件可以通过创建某些头文件的部分处理版本来加速编译,然后在编译过程中使用该版本,而不是重复解析原始头文件。
主形式¶
target_precompile_headers(<target>
<INTERFACE|PUBLIC|PRIVATE> [header1...]
[<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])
该命令将头文件添加到 `PRECOMPILE_HEADERS 和/或 INTERFACE_PRECOMPILE_HEADERS 目标属性。命名的 `add_executable() 或 add_library() 等命令创建,并且不能是 别名目标。
关键词 INTERFACE、PUBLIC 和 PRIVATE 是指定以下参数的 作用域 所必需的。PRIVATE 和 PUBLIC 项目将填充 `PRECOMPILE_HEADERS 属性。PUBLIC 和 INTERFACE 项目将填充 `INTERFACE_PRECOMPILE_HEADERS 属性(导入的目标 只支持 INTERFACE 项目)。对同一个 `
项目通常应避免为将被 导出 的目标使用 PUBLIC 或 INTERFACE,或者至少应使用 $<BUILD_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 属性设置为 `PRECOMPILE_HEADERS 属性已设置为,CMake 将会报错并终止。
注意
`REUSE_FROM` 形式要求 `
另请参阅¶
要为特定目标禁用预编译头文件,请参阅
DISABLE_PRECOMPILE_HEADERS目标属性。要防止在编译特定源文件时使用预编译头文件,请参阅
SKIP_PRECOMPILE_HEADERS源文件属性。