When you specify -xpch=v, v can be collect:pch_filename or use:pch_filename. The first time you use -xpch, you must specify the collect mode. The compilation command that specifies -xpch=collect must only specify one source file. In the following example, the -xpch option creates a precompiled-header file called myheader.Cpch based on the source file a.cc:
CC -xpch=collect:myheader a.cc
A valid precompiled-header filename always has the suffix .Cpch. When you specify pch_filename, you can add the suffix or let the compiler add it for you. For example, if you specify cc -xpch=collect:foo a.cc, the precompiled-header file is called foo.Cpch.
When you create a precompiled-header file, pick a source file that contains the common sequence of include files across all the source files with which the precompiled-header file is to be used. The common sequence of include files must be identical across these source files. Remember, only one source filename value is legal in collect mode. For example, CC -xpch=collect:foo bar.cc is valid, whereas CC -xpch=collect:foo bar.cc foobar.cc is invalid because it specifies two source files.
Specify -xpch=use:pch_filename to use a precompiled-header file. You can specify any number of source files with the same sequence of include files as the source file that was used to create the precompiled-header file. For example, your command in use mode could look like this: CC -xpch=use:foo.Cpch foo.c bar.cc foobar.cc.
You should only use an existing precompiled-header file if the following is true. If any of the following is not true, you should recreate the precompiled-header file:
The compiler that you are using to access the precompiled-header file is the same as the compiler that created the precompiled-header file. A precompiled-header file created by one version of the compiler may not be usable by another version of the compiler, including differences caused by installed patches.
Except for the -xpch option, the compiler options you specify with -xpch=use must match the options that were specified when the precompiled-header file was created.
The set of included headers you specify with -xpch=use is identical to the set of headers that were specified when the precompile header was created.
The contents of the included headers that you specify with -xpch=use is identical to the contents of the included headers that were specified when the precompiled header was created.
The current directory (that is, the directory in which the compilation is occurring and attempting to use a given precompiled-header file) is the same as the directory in which the precompiled-header file was created.
The initial sequence of pre-processing directives, including #include directives, in the file you specified with -xpch=collect are the same as the sequence of pre-processing directives in the files you specify with -xpch=use.
In order to share a precompiled-header file across multiple source files, those source files must share a common set of include files as their initial sequence of tokens. This initial sequence of tokens is known as the viable prefix. The viable prefix must be interpreted consistently across all the source files that use the same precompiled-header file.
The viable prefix of a source file can only be comprised of comments and any of the following pre-processor directives:
#include #if/ifdef/ifndef/else/elif/endif #define/undef #ident (if identical, passed through as is) #pragma (if identical)
Any of these may reference macros. The #else, #elif, and #endif directives must match within the viable prefix.
Within the viable prefix of each file that shares a precompiled-header file, each corresponding #define and #undef directive must reference the same symbol (in the case of #define, each one must reference the same value). Their order of appearance within each viable prefix must be the same as well. Each corresponding pragma must also be the same and appear in the same order across all the files sharing a precompiled header.
A header file that is incorporated into a precompiled-header file must not violate the following. The results of compiling a program that violate any of these constraints is undefined.
The header file must not contain function and variable definitions.
The header file must not use __DATE__ and __TIME__. Use of these pre-processor macros can generate unpredictable results.
The header file must not contain #pragma hdrstop.
The header file must not use __LINE__ and __FILE__ in the viable prefix. It is allowed to use __LINE__ and __FILE__ in included headers.
Here are possible approaches to modifying your make files in order to incorporate -xpch into your builds.
You can use the implicit make rules by using an auxiliary CCFLAGS variable and the KEEP_STATE facility of both make and dmake. The precompiled header is produced as a separate, independent step.
.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 |
You can also define your own compilation rule instead of trying to use an auxiliary 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 |
You can produce the precompiled header as a side effect of regular compilation, and without using KEEP_STATE, but this approach requires explicit compilation commands.
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 |