Sun Studio 12:C 用户指南

B.2.124 -xpch=v

编译器选项可激活预编译头文件功能。v 可为 autoautofirstcollect:pch_filenameuse:pch_filename。通过将 -xpch(在B.2.124 -xpch=v中进行了详细介绍)和 -xpchstop(在B.2.125 -xpchstop=[file|<include>]中进行了详细介绍)选项与 #pragma hdrstop 指令(在2.8.8 hdrstop中进行了详细介绍)结合使用,可利用此功能。

使用 -xpch 选项可以创建预编译头文件并减少编译时间。预编译头文件的作用是减少源代码共享同一组 include 文件的应用程序的编译时间,这些 include 文件往往包含大量的源代码。预编译头文件的工作机理是,首先从一个源文件收集一组头文件信息,然后在重新编译该源文件或者编译其他有同样头文件顺序的源文件时就可以使用这些收集到的信息。编译器收集的信息存储在预编译头文件中。

另请参见:

B.2.124.1 自动创建预编译头文件

可以让编译器自动生成预编译头文件。选择以下两种方法之一来实现此目的。一种方法是让编译器从在源文件找到的第一个 include 文件创建预编译头文件。另一种方法是让编译器从在源文件中找到的 include 文件集合中选择,选择范围从第一个 include 文件开始,直到已经定义好的确定哪个 include 文件是最后一个的点结束。使用以下标志之一可以确定编译器用于自动生成预编译头文件的方法:

表 B–34 -xpch 标志

标志 

含义 

-xpch=auto

预编译头文件的内容基于编译器在源文件中找到的最长的活前缀(有关如何识别活前缀的说明,请参见下文)。此标志生成的预编译头文件可能包含最多的头文件。 

-xpch=autofirst

此标志生成的预编译头文件仅包含在源文件中找到的第一个头文件。 

B.2.124.2 手动创建预编译头文件

如果决定手动创建预编译头文件,则必须首先使用 -xpch,并指定 collect 模式。指定 -xpch=collect 的编译命令只能指定一个源文件。在以下示例中,-xpch 选项根据源文件 a.c 创建名为 myheader.cpch 的预编译头文件:

cc -xpch=collect:myheader a.c

有效的预编译头文件通常具有后缀 .cpch。在指定 pch_filename 时,后缀可以由您自己增加或由编译器增加。例如,如果指定 cc -xpch=collect:foo a.c,则预编译的头文件名为 foo.cpch

B.2.124.3 编译器如何处理现有的预编译头文件

如果编译器无法使用 -xpch=auto-xpch=autofirst 时的预编译头文件,则会生成新的预编译头文件。如果编译器无法使用 -xpch=use 时的预编译头文件,将发出一个警告,并且使用真实头文件来完成编译。

B.2.124.4 指示编译器使用特定的预编译头文件

您还可以指示编译器使用特定的预编译头文件。要实现此目的,请指定 -xpch=use:pch_filename。可以将 include 文件同一序列中任意数量的源文件指定为用于创建预编译头文件的源文件。例如,在 use 模式中的命令可类似于以下命令:cc -xpch=use:foo.cpch foo.c bar.c foobar.c.

如果以下条件都成立,则只能使用现有的预编译的头文件。如果以下任意条件不成立,则应重新创建预编译头文件:

B.2.124.5 活前缀

为了在多个源文件间共享预编译头文件,这些源文件就必须将通用的 include 文件集合作为其标记的初始序列共享。标记是指关键字、名称或标点符号。被 #if 指令排除的注释和代码不能被编译器识别为标记。该初始标记序列称为活前缀。也就是说,活前缀是源文件中通用于所有源文件的最靠前的部分。创建预编译头文件并进而确定源文件中哪些头文件是预编译的时,编译器使用此活前缀作为整个操作的依据。

编译器在当前编译期间找到的活前缀必须与用于创建预编译头文件的活前缀匹配。也就是说,必须在使用相同预编译头文件的所有源文件中对活前缀给出一致的解释。

源文件的活前缀只能包含注释和以下任意预处理程序指令:

#include
#if/ifdef/ifndef/else/elif/endif
#define/undef
#ident (if identical, passed through as is)
#pragma (if identical)

以上任何指令都可以引用宏。#else#elif#endif 指令必须在活前缀内匹配。注释被忽略。

指定 -xpch=auto-xpch=autofirst 时,编译器自动确定活前缀的终点,定义如下:对于 -xpch=collect-xpch=use,活前缀以 #pragma hdrstop 结尾。

在共享预编译头文件的每个文件的活前缀中,每个相应的 #define#undef 指令都必须引用相同的符号(例如每个 #define 必须引用同一个值)。这些指令在每个活前缀中出现的顺序也必须相同。每个相应 pragma 也必须相同,并且必须按相同顺序出现在共享预编译头文件的所有文件中。

B.2.124.6 浏览头文件以查找问题

如何能够使头文件可以预编译?在不同的源文件中解释一致时,头文件可以预编译。具体来说,就是当它仅包含完全声明时。也就是说,任何一个文件中的声明都必须独自成为有效声明。不完全的类型声明,例如 struct S;,是有效声明。完全类型声明可以出现在某些其他文件中。请考虑这些头文件示例:


file a.h
struct S {
#include "x.h" /* not allowed */
};

file b.h
struct T; // ok, complete declaration
struct S {
   int i;
[end of file, continued in another file] /* not allowed*/

并入预编译头文件的头文件一定不得违反以下约束。这里没有定义对违反上述约束的程序的编译结果。

B.2.124.7 预编译头文件高速缓存

编译器自动创建预编译头文件时,会将该文件写入 SunWS_cache 目录中。此目录始终位于创建目标文件的位置。该文件的更新受锁保护,这样可在 dmake 下正常工作。

如果需要强制编译器重新生成自动生成的预编译头文件,可以使用 CCadmin 工具清除预编译头文件高速缓存目录。有关更多信息,请参见 CCadmin(1) 手册页。

B.2.124.8 警告

B.2.124.9 预编译头文件依赖性和 make 文件

指定 -xpch=collect 时,编译器会生成预编译头文件的依赖性信息。需要在 make 文件中创建适当的规则,以利用这些依赖性。考虑下面的 make 文件示例:


%.o : %.c shared.cpch
         $(CC) -xpch=use:shared -xpchstop=foo.h -c $<
default : a.out

foo.o + shared.cpch : foo.c
         $(CC) -xpch=collect:shared -xpchstop=foo.h foo.c -c

a.out : foo.o bar.o foobar.o
         $(CC) foo.o bar.o foobar.o

clean :
         rm -f *.o shared.cpch .make.state a.out

这些 make 规则以及编译器生成的依赖性,会在与 -xpch=collect 一起使用的任何源文件或属于预编译头文件的一部分的任何头文件发生更改时,强制重新创建手动创建的预编译头文件。这样可防止使用过期的预编译头文件。

您无需在 make 文件中为 -xpch=auto-xpch=autofirst 创建任何其他 make 规则。