Microsoft C 和 C++ 编译器提供了用于预编译任何 C 或 C++ 代码(包括内联代码)的选项。利用此性能特性,可以编译稳定的代码体,将已编译状态的代码存储在文件中,以及在随后的编译中,将预编译的代码与仍在开发的代码结合起来。由于不需要重新编译稳定代码,因此后面每次编译的速度都要快一些。
预编译代码有助于在开发周期中缩短编译时间,特别是在以下情况中:
-
总是使用不经常改动的大型代码体。
-
程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
用于创建预编译头文件的第一次编译所花费的时间比后面的编译稍长一些。通过包含预编译代码可以加快后面的编译速度。
C 和 C++ 程序都可以预编译。在 C++ 编程中,常见的做法是将类接口信息分别放到不同的头文件中。此后就可以将这些头文件包含在使用该类的程序中。通过预编译这些头文件,可以缩短程序的编译时间。
注意 |
---|
尽管每个源文件只能使用一个预编译头 (.pch) 文件,但在一个项目中可以使用多个 .pch 文件。 |
http://msdn.microsoft.com/zh-cn/library/de9s74bh(v=vs.80).aspx
PCH 的示例代码
// ANOTHER.H : Contains the interface to code that is not
// likely to change.
//
#ifndef --ANOTHER_H
#define --ANOTHER_H
#include<iostream>
void savemoretime( void );
#endif // --ANOTHER_H
// STABLE.H : Contains the interface to code that is not likely
// to change. List code that is likely to change
// in the makefile's STABLEHDRS macro.
//
#ifndef --STABLE_H
#define --STABLE_H
#include<iostream>
void savetime( void );
#endif // --STABLE_H
// UNSTABLE.H : Contains the interface to code that is
// likely to change. As the code in a header
// file becomes stable, remove the header file
// from the makefile's UNSTABLEHDR macro and list
// it in the STABLEHDRS macro.
//
#ifndef --UNSTABLE_H
#define --UNSTABLE_H
#include<iostream.h>
void notstable( void );
#endif // --UNSTABLE_H
// APPLIB.CPP : This file contains the code that implements
// the interface code declared in the header
// files STABLE.H, ANOTHER.H, and UNSTABLE.H.
//
#include"another.h"
#include"stable.h"
#include"unstable.h"
// The following code represents code that is deemed stable and
// not likely to change. The associated interface code is
// precompiled. In this example, the header files STABLE.H and
// ANOTHER.H are precompiled.
void savetime( void )
{ cout << "Why recompile stable code?\n"; }
void savemoretime( void )
{ cout << "Why, indeed?\n\n"; }
// The following code represents code that is still under
// development. The associated header file is not precompiled.
void notstable( void )
{ cout << "Unstable code requires"
<< " frequent recompilation.\n"; }
// MYAPP.CPP : Sample application
// All precompiled code other than the file listed
// in the makefile's BOUNDRY macro (stable.h in
// this example) must be included before the file
// listed in the BOUNDRY macro. Unstable code must
// be included after the precompiled code.
//
#include"another.h"
#include"stable.h"
#include"unstable.h"
int main( void )
{
savetime();
savemoretime();
notstable();
}
PCH 的示例生成文件
# Makefile : Illustrates the effective use of precompiled
# headers in a project
# Usage: NMAKE option
# option: DEBUG=[0|1]
# (DEBUG not defined is equivalent to DEBUG=0)
#
OBJS = myapp.obj applib.obj
# List all stable header files in the STABLEHDRS macro.
STABLEHDRS = stable.h another.h
# List the final header file to be precompiled here:
BOUNDRY = stable.h
# List header files under development here:
UNSTABLEHDRS = unstable.h
# List all compiler options common to both debug and final
# versions of your code here:
CLFLAGS = /c /W3
# List all linker options common to both debug and final
# versions of your code here:
LINKFLAGS = /NOD /ONERROR:NOEXE
!IF "$(DEBUG)" == "1"
CLFLAGS = /D_DEBUG $(CLFLAGS) /Od /Zi /f
LINKFLAGS = $(LINKFLAGS) /COD
LIBS = slibce
!ELSE
CLFLAGS = $(CLFLAGS) /Oselg /Gs
LINKFLAGS = $(LINKFLAGS)
LIBS = slibce
!ENDIF
myapp.exe: $(OBJS)
link $(LINKFLAGS) @<<
$(OBJS), myapp, NUL, $(LIBS), NUL;
<<
# Compile myapp
myapp.obj : myapp.cpp $(UNSTABLEHDRS) stable.pch
$(CPP) $(CLFLAGS) /Yu$(BOUNDRY) myapp.cpp
# Compile applib
applib.obj : applib.cpp $(UNSTABLEHDRS) stable.pch
$(CPP) $(CLFLAGS) /Yu$(BOUNDRY) applib.cpp
# Compile headers
stable.pch : $(STABLEHDRS)
$(CPP) $(CLFLAGS) /Yc$(BOUNDRY) applib.cpp myapp.cpp
生成过程中的 PCH 文件
软件项目的代码基础通常包含在多个 C 或 C++ 源文件、对象文件、库和头文件中。通常情况下,生成文件将这些元素的组合整理到一个可执行文件中。下图显示了使用预编译头文件的生成文件结构。此关系图中的 NMAKE 宏名和文件名与 PCH 的示例生成文件和 PCH 的示例代码中的示例代码中的名称一致。
此图使用三个关系图设备显示生成过程的流程。命名矩形表示每个文件或宏;三个宏表示一个或多个文件。灰色区域表示每个编译或链接操作。箭头指示在编译或链接过程中组合的文件和宏。
使用预编译头文件的生成文件结构
从关系图顶部开始,STABLEHDRS 和 BOUNDRY 都是 NMAKE 宏,您在这些宏中列出不大可能需要重新编译的文件。只有在预编译头文件 (STABLE.pch) 不存在或对两个宏中列出的文件进行更改时,才使用命令字符串
CL /c /W3 /Yc$(BOUNDRY) applib.cpp myapp.cpp
编译这些文件。无论在哪一种情况下,预编译头文件都将只包含来自 STABLEHDRS 宏中所列文件的代码。在 BOUNDRY 宏中列出最后一个想预编译的文件。
在这些宏中列出的文件可以是头文件,也可以是 C 或 C++ 源文件。(单个 .pch 文件不能同时用于 C 和 C++ 模块。)请注意,可以使用 hdrstop 宏使预编译在 BOUNDRY 文件中的某个位置停止。有关更多信息,请参见 hdrstop。
在关系图中继续向下,APPLIB.obj 表示在最终应用程序中使用的支持代码。它是从 APPLIB.cpp、UNSTABLEHDRS 宏中列出的文件以及来自预编译头的预编译代码创建的。
MYAPP.obj 表示最终应用程序。它是从 MYAPP.cpp、UNSTABLEHDRS 宏中列出的文件以及来自预编译头的预编译代码创建的。
最后,通过链接 OBJS 宏中列出的文件(APPLIB.obj 和 MYAPP.obj)创建可执行文件 (MYAPP.EXE)。