预编译头文件
解析系统库的头文件非常耗时。典型的源代码文件少于一千行代码。相比之下,大型库的头文件可能包含数万行代码。这在 C++ 中尤其成问题,因为 C++ 中常见的头文件库可能包含极其复杂的代码,导致编译速度缓慢。
预编译头文件是一种缓解此问题的工具。它们的作用是解析头文件,并将编译器的内部状态序列化到磁盘。预编译头文件的缺点是它们难以设置。Meson 原生支持预编译头文件,但使用它们需要一些操作。
预编译头文件相对简单。它是一个头文件,包含用于预编译的系统头文件的 `#include` 指令。以下是一个 C++ 示例。
#include<vector>
#include<string>
#include<map>
在 Meson 中,预编译头文件始终是针对每个目标的。也就是说,给定的预编译头文件在编译目标中的每个文件时都会使用。由于底层编译器的限制,此头文件不能与任何源代码文件位于相同的子目录中。强烈建议您在目标目录中创建一个名为 `pch` 的子目录,并将头文件(以及其他内容)放在其中。
切换预编译头文件的用法
如果您希望在不使用预编译头文件的情况下编译项目,可以通过在配置时将 `-Db_pch=false` 参数传递给 Meson 或稍后使用 `meson configure` 命令来更改 pch 选项的值。您也可以使用 GUI 工具在已配置的构建目录中切换 pch 的使用。您无需对源代码进行任何更改。通常这样做是为了测试项目是否可以在不使用 pch 的情况下干净地编译(即检查其 `#include` 是否按顺序排列),以及解决编译器错误。
在 GCC 及其衍生产品中使用预编译头文件
拥有要预编译的文件后,您可以使用 `pch` 关键字参数为给定目标启用 pch 的使用。例如,假设您要使用预编译头文件构建一个小型 C 二进制文件。假设该二进制文件的源代码文件使用系统头文件 `stdio.h` 和 `string.h`。然后,您创建一个名为 `pch/myexe_pch.h` 的头文件,其中包含以下内容
#include <stdio.h>
#include <string.h>
并将以下内容添加到 Meson 中
executable('myexe', sources : sourcelist, c_pch : 'pch/myexe_pch.h')
就是这样。请注意,您的源代码文件 *不能* 包含文件 `myexe_pch.h`,并且您 *不能* 将 pch 子目录添加到搜索路径中。无需对原始程序文件进行任何修改。Meson 将使用编译器选项使编译器包含 pch。如果您想禁用 pch(例如,由于编译器错误),可以在构建系统端完成,无需对源代码进行任何更改。
您可以在任何构建目标上使用预编译头文件。如果您的目标包含多种语言,您可以指定多个 pch 文件,如下所示。
executable('multilang', sources : srclist,
c_pch : 'pch/c_pch.h', cpp_pch : 'pch/cpp_pch.h')
在 MSVC 中使用预编译头文件
自 Meson 0.50.0 版本起,MSVC 中的预编译头文件与 GCC 中的工作方式相同。Meson 将自动为您创建匹配的 pch 实现文件。
在 0.50.0 版本之前,除了头文件之外,Meson 还需要一个相应的源文件。如果您的头文件名为 `foo_pch.h`,则相应的源文件通常称为 `foo_pch.cpp`,它与头文件位于同一个 `pch` 子目录中。其内容如下
#if !defined(_MSC_VER)
#error "This file is only for use with MSVC."
#endif
#include "foo_pch.h"
要启用 pch,只需在目标定义中列出这两个文件即可
executable('myexe', sources : srclist,
cpp_pch : ['pch/foo_pch.h', 'pch/foo_pch.cpp'])
此形式将在 GCC 和 msvc 中有效,因为 Meson 知道 GCC 不需要 `。cpp` 文件,因此会忽略它。
需要注意的是,由于 MSVC 编译器的实现细节,在一个目标中为多种语言使用预编译头文件无法保证能正常工作。
搜索结果为