该编译器选项激活了预编译头文件特性。预编译头文件的作用是减少源代码共享同一组 include 文件的应用程序的编译时间,而且这些 include 文件往往有大量的源代码。编译器首先从一个源文件收集一组头文件信息,然后在重新编译该源文件或者其他有同样头文件的源文件时就可以使用这些收集到的信息。编译器收集的信息存储在预编译头文件中。要使用该功能,需要指定 -xpch 和 -xpchstop 选项,并使用 #pragma hdrstop 指令。
另请参见:
指定 -xpch=v 时,v 可以是 collect:pch_filename 或 use:pch_filename。首次使用 -xpch 时,必须指定 collect 模式。指定 -xpch=collect 的编译命令只能指定一个源文件。在以下示例中,-xpch 选项根据源文件 a.cc 创建名为 myheader.Cpch 的预编译头文件:
CC -xpch=collect:myheader a.cc
有效的预编译头文件总是有后缀 .Cpch。在指定 pch_filename 时,后缀可以由您自己增加或由编译器增加。例如,如果指定 cc -xpch=collect:foo a.cc,则预编译头文件称为 foo.Cpch。
在创建预编译头文件时,请选取包含所有源文件之间 include 文件通用序列的源文件,预编译头文件与这些源文件一起使用。include 文件的共同序列在这些源文件之间必须是一样的。请记住,在 collect 模式中只能使用一个源文件名值。例如,CC -xpch=collect:foo bar.cc 有效,而 CC -xpch=collect:foo bar.cc foobar.cc 无效,因为它指定了两个源文件。
可指定 -xpch=use:pch_filename 以使用预编译头文件。您可以将 include 文件同一序列中任意数量的源文件指定为用于创建预编译头文件的源文件。例如,在 use 模式中命令类似于: CC -xpch=use:foo.Cpch foo.c bar.cc foobar.cc。
如果下列情况为真,就只应使用现有的预编译头文件。如果以下任意条件不成立,则应重新创建预编译头文件:
用于访问预编译头文件的编译器与创建预编译头文件的编译器相同。编译器的一个版本创建的预编译头文件可能无法用于另一版本(包括安装的修补程序产生的差异)。
除 -xpch 选项之外,用 -xpch=use 指定的编译器选项必须与创建预编译头文件时指定的选项相匹配。
用 -xpch=use 指定的包含头文件的集合与创建预编译头文件时指定的头文件集合是相同的。
用 -xpch=use 指定的包含头文件的内容与创建预编译头文件时指定的包含头文件的内容是相同的。
当前目录(即发生编译并尝试使用给定预编译头文件的目录)与创建预编译头文件所在的目录相同。
在用 -xpch=collect 指定的文件中预处理指令(包括 #include)的初始序列,与在用 -xpch=use 指定的文件中预处理指令的序列相同。
要在多个源文件间共享预编译头文件,这些源文件必须共享一组共同的 include 文件(按其初始标记序列)。该初始标记序列称为活前缀。活前缀必须在使用相同预编译头文件的所有源文件中解释一致。
源文件的活前缀只能包含注释和以下任意预处理程序指令:
#include #if/ifdef/ifndef/else/elif/endif #define/undef #ident (if identical, passed through as is) #pragma (if identical)
以上任何指令都可以引用宏。#else、#elif 和 #endif 指令必须在活前缀内匹配。
在共享预编译头文件的每个文件的活前缀中,每个相应的 #define 和 #undef 指令都必须引用相同的符号(例如每个 #define 必须引用同一个值)。这些指令在每个活前缀中出现的顺序也必须相同。每个相应 pragma 也必须相同,并且必须按相同顺序出现在共享预编译头文件的所有文件中。
并入预编译头文件的头文件一定不得违反以下约束。这里没有定义对违反任意这些约束的程序的编译结果。
头文件一定不要包含函数和变量定义。
头文件不得使用 __DATE__ 和 __TIME__。使用预处理宏会产生无法预料的结果。
头文件不得包含 #pragma hdrstop。
头文件的活前缀中不得使用 __LINE__ 和 __FILE__。但可以在包含头文件中使用 __LINE__ 和 __FILE__。
下面是为了将 -xpch 合并到生成的程序中而对 make 文件进行修改的几种可能方法。
可以通过使用辅助变量 CCFLAGS 以及 make 和 dmake 的 KEEP_STATE 功能使用隐式 make 规则。预编译头文件在独立的步骤中产生。
.KEEP_STATE: CCFLAGS_AUX = -O etc CCFLAGS = -xpch=use:shared $(CCFLAGS_AUX) shared.Cpch: foo.cc $(CCC) -xpch=collect:shared $(CCFLAGS_AUX) foo.cc a.out: foo.o ping.o pong.o $(CCC) foo.o ping.o pong.o |
您还可以定义自己的编译规则,而无不是尝试使用辅助变量 CCFLAGS。
.KEEP_STATE: .SUFFIXES: .o .cc %.o:%.cc shared.Cpch $(CCC) -xpch=use:shared $(CCFLAGS) -c $< shared.Cpch: foo.cc $(CCC) -xpch=collect:shared $(CCFLAGS) foo.cc -xe a.out: foo.o ping.o pong.o $(CCC) foo.o ping.o pong.o |
可以通过常规编译顺便生成预编译头文件,而无需使用 KEEP_STATE,但该方法要求使用显式编译命令。
shared.Cpch + foo.o: foo.cc bar.h $(CCC) -xpch=collect:shared foo.cc $(CCFLAGS) -c ping.o: ping.cc shared.Cpch bar.h $(CCC) -xpch=use:shared ping.cc $(CCFLAGS) -c pong.o: pong.cc shared.Cpch bar.h $(CCC) -xpch=use:shared pong.cc $(CCFLAGS) -c a.out: foo.o ping.o pong.o $(CCC) foo.o ping.o pong.o |