GCC中使用预编译头文件
2016-09-18 09:11
239 查看
转自: http://blog.csdn.net/wind19/article/details/6332908
既使用过 Microsoft Visual C++ 又使用过 GNU CC 的网友一定会感受到两者编译速度的差异,尤其是对于 wxWidgets 这样头文件内容多的软件。Microsoft? Visual C++ 能够有很高编译效率的原因是其支持“预编译头文件” (Pre-Compiled Header, PCH)。当使用 Microsoft? Visual C++? 建立项目时,常常会建立文件 StdAfx.cpp 和 StdAfx.h。其中 StdAfx.h 包含了项目中所有实质 C/C++ 源文件所要用到的一些系统头文件,而 StdAfx.cpp 只包含了 StdAfx.h。这两个文件便是用来建立预编译头文件“项目名.pch”的。预编译头文件是将一些项目中普遍使用的头文件内容的词法分析、语法分析等结 果缓存在一个特定格式的二进制文件中;当然编译实质 C/C++ 源文件时,就不必从头对这些头文件进行词法-语法分析,而只需要利用那些已经完成词法-语法分析的结果就可以了。
事实上,GNU CC 从 3.4.x 版和 4.x 版开始,也支持了这种提高编译效率的机制。只是由于 GNU CC 的手册 中的《Using Precompiled Headers》一节对此介绍不多,也没有简单的自动项目管理工具支持这项功能,因而许多网友还不知道 GNU CC 的这项功能。
GNU CC 的手册中建议使用 make 管理预编译头文件,还指出 C 语言的预编译头文件和 C++ 语言的预编译头文件是不一样的 。这里首先讲述项目中只有 C 语言源文件或只有 C++ 语言源文件的情形,再讲述项目中两种语言的源文件同时存在的情况。
项目中只有 C 或 C++ 一种语言的源文件时,只需建立一个预编译头文件。
建立一个头文件,例如命名为 inc.h。该文件供项目中所有的 C/C++ 源文件使用。将整个项目所需要的头文件都列在其中:
建立 Makefile,以维护预编译头文件。一方面要建立维护 GNU CC 的预编译头文件 inc.h.gch 的规则;另一方面,要在编译每个 C/C++ 源文件时检查 inc.h.gch,即让所有 .o 文件依赖于 inc.h.gch。
如果项目既包含 C 语言源文件,也包含 C++ 语言源文件,就需要为两种语言分别维护一个预编译头文件。
再建立一个头文件,例如命名为 inc.hpp。inc.h 供 C 语言源文件使用,而 inc.hpp 供 C++ 语言文件使用。假如 inc.hpp 的内容与 inc.h 的相同,只需要简单的写上:
在 Makefile 里也要随之增加对 inc.hpp 的维护。一是要增加产生 inc.hpp.gch 的规则,此时执行 GNU CC 时要增加参数“-x c++-header”;二是要在 clean 一节中删除这个预编译头文件。
这是以上两种 Makefile 的比较:
转自 http://zj880725.blog.163.com/blog/static/86190120200951781657881/
=========================
简单尝试
公司开发了一个自己的基础类库,有着庞大的头文件。为了便于使用并提高编译速度,尝试了一下GCC的预编译头文件的功能:
1、先定义头文件afl.h,内容如下:(afl意味a framework library)
2、预编译这个头文件:
g++ -o afl.h.gch -x c++-header -c afl.h -g -Wall -I”libpath…”
使用-x c++-header来说明这个文件作为C++的预编译头文件。注意:C和C++的处理方式不一样,C要使用-x c-header选项。
3、经过上一步,alf.h.gch的这个预编译的头文件已经产生了。下面是代码中的引用方式:
4、编译这个文件:
呵呵,发现编译的时候相当快,而且不用指定库的头文件路径。
既使用过 Microsoft Visual C++ 又使用过 GNU CC 的网友一定会感受到两者编译速度的差异,尤其是对于 wxWidgets 这样头文件内容多的软件。Microsoft? Visual C++ 能够有很高编译效率的原因是其支持“预编译头文件” (Pre-Compiled Header, PCH)。当使用 Microsoft? Visual C++? 建立项目时,常常会建立文件 StdAfx.cpp 和 StdAfx.h。其中 StdAfx.h 包含了项目中所有实质 C/C++ 源文件所要用到的一些系统头文件,而 StdAfx.cpp 只包含了 StdAfx.h。这两个文件便是用来建立预编译头文件“项目名.pch”的。预编译头文件是将一些项目中普遍使用的头文件内容的词法分析、语法分析等结 果缓存在一个特定格式的二进制文件中;当然编译实质 C/C++ 源文件时,就不必从头对这些头文件进行词法-语法分析,而只需要利用那些已经完成词法-语法分析的结果就可以了。
事实上,GNU CC 从 3.4.x 版和 4.x 版开始,也支持了这种提高编译效率的机制。只是由于 GNU CC 的手册 中的《Using Precompiled Headers》一节对此介绍不多,也没有简单的自动项目管理工具支持这项功能,因而许多网友还不知道 GNU CC 的这项功能。
GNU CC 的手册中建议使用 make 管理预编译头文件,还指出 C 语言的预编译头文件和 C++ 语言的预编译头文件是不一样的 。这里首先讲述项目中只有 C 语言源文件或只有 C++ 语言源文件的情形,再讲述项目中两种语言的源文件同时存在的情况。
项目中只有 C 或 C++ 一种语言的源文件时,只需建立一个预编译头文件。
建立一个头文件,例如命名为 inc.h。该文件供项目中所有的 C/C++ 源文件使用。将整个项目所需要的头文件都列在其中:
/* $FreeBSD$ */ #ifndef _INC_H_ #define _INC_H_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #endif /* ! _INC_H_ *
建立 Makefile,以维护预编译头文件。一方面要建立维护 GNU CC 的预编译头文件 inc.h.gch 的规则;另一方面,要在编译每个 C/C++ 源文件时检查 inc.h.gch,即让所有 .o 文件依赖于 inc.h.gch。
# $FreeBSD$ CC = gcc CFLAGS = -g -Wall CXX = gcc CXXFLAGS = -g -Wall LD = gcc LDFLAGS = -g -Wall EXE = testapp PCH_H = inc.h PCH = inc.h.gch SRCS = testapp.c OBJS = testapp.o LIBS = # System Libraries ECHO = echo CP = cp -v RM = rm -f .SUFFIXES: .SUFFIXES: .o .c .cxx # The meaning of "$<": # BSD Pmake: the implied source # GNU make: the first prerequisite .c.o: $(CC) $(CFLAGS) -c $< .cxx.o: $(CXX) $(CXXFLAGS) -c $< all: $(EXE) # $> $^ # BSD Pmake all sources not defined # GNU make not defined all prerequisites # Both interpret "$@" as target $(EXE): $(OBJS) $(LIBBDD) $(LD) $(LDFLAGS) -o $@ $> $^ $(LIBS) # Pre-compiled header $(OBJS): $(PCH) $(PCH): $(PCH_H) $(CC) $(CFLAGS) $> $^ clean: $(RM) $(PCH) $(OBJS) # For Both UNIX-like OS and Microsoft Windows (MinGW/Cygwin) $(RM) $(EXE) $(EXE).exe
如果项目既包含 C 语言源文件,也包含 C++ 语言源文件,就需要为两种语言分别维护一个预编译头文件。
再建立一个头文件,例如命名为 inc.hpp。inc.h 供 C 语言源文件使用,而 inc.hpp 供 C++ 语言文件使用。假如 inc.hpp 的内容与 inc.h 的相同,只需要简单的写上:
/* $FreeBSD$ */ #ifndef _INC_HPP_ #define _INC_HPP_ #include "inc.h" #endif /* ! _INC_HPP_ */
在 Makefile 里也要随之增加对 inc.hpp 的维护。一是要增加产生 inc.hpp.gch 的规则,此时执行 GNU CC 时要增加参数“-x c++-header”;二是要在 clean 一节中删除这个预编译头文件。
# $FreeBSD$ CC = gcc CFLAGS = -g -Wall CXX = gcc CXXFLAGS = -g -Wall LD = gcc LDFLAGS = -g -Wall EXE = testapp PCH_H = inc.h PCH = inc.h.gch PCH_X_H = inc.hpp PCH_X = inc.hpp.gch SRCS = testapp.c OBJS = testapp.o LIBS = # System Libraries ECHO = echo CP = cp -v RM = rm -f .SUFFIXES: .SUFFIXES: .o .c .cxx # The meaning of "$<": # BSD Pmake: the implied source # GNU make: the first prerequisite .c.o: $(CC) $(CFLAGS) -c $< .cxx.o: $(CXX) $(CXXFLAGS) -c $< all: $(EXE) # $> $^ # BSD Pmake all sources not defined # GNU make not defined all prerequisites # Both interpret "$@" as target $(EXE): $(OBJS) $(LIBBDD) $(LD) $(LDFLAGS) -o $@ $> $^ $(LIBS) # Pre-compiled header $(OBJS): $(PCH) $(PCH): $(PCH_H) $(CC) $(CFLAGS) $> $^ $(PCH_X): $(PCH_X_H) $(CXX) $(CXXFLAGS) -x c++-header $> $^ clean: $(RM) $(PCH) $(PCH_X) $(OBJS) # For Both UNIX-like OS and Microsoft Windows (MinGW/Cygwin) $(RM) $(EXE) $(EXE).exe
这是以上两种 Makefile 的比较:
@@ -12,6 +12,8 @@ EXE = testapp PCH_H = inc.h PCH = inc.h.gch +PCH_X_H = inc.hpp +PCH_X = inc.hpp.gch SRCS = testapp.c OBJS = testapp.o LIBS = # System Libraries @@ -48,7 +50,10 @@ $(PCH): $(PCH_H) $(CC) $(CFLAGS) $> $^ +$(PCH_X): $(PCH_X_H) + $(CXX) $(CXXFLAGS) -x c++-header $> $^ + clean: - $(RM) $(PCH) $(OBJS) + $(RM) $(PCH) $(PCH_X) $(OBJS) # For Both UNIX-like OS and Microsoft Windows (MinGW/Cygwin) $(RM) $(EXE) $(EXE).exe
转自 http://zj880725.blog.163.com/blog/static/86190120200951781657881/
=========================
简单尝试
公司开发了一个自己的基础类库,有着庞大的头文件。为了便于使用并提高编译速度,尝试了一下GCC的预编译头文件的功能:
1、先定义头文件afl.h,内容如下:(afl意味a framework library)
#ifndef _AFL_H_ #define _AFL_H_ // from here to include all head files #include < Log.h > #include < DebugUtil.h > #endif
2、预编译这个头文件:
g++ -o afl.h.gch -x c++-header -c afl.h -g -Wall -I”libpath…”
使用-x c++-header来说明这个文件作为C++的预编译头文件。注意:C和C++的处理方式不一样,C要使用-x c-header选项。
3、经过上一步,alf.h.gch的这个预编译的头文件已经产生了。下面是代码中的引用方式:
// test.cpp #include " alf.h " int main() { LOG( " test " ); return 1 ; }
注意:所有的需要库的地方,都引用alf.h就可以了。
4、编译这个文件:
g++ -o test.o -c test.cpp -g -Wall
呵呵,发现编译的时候相当快,而且不用指定库的头文件路径。
相关文章推荐
- 如何在XCode中使用gcc编译生成的.a库文件?
- 使用gcc编译Windows程序并使用资源文件
- Linux操作系统的简单指令及如何使用vim编写一个程序,然后使用gcc查看【预处理】、【编译】、【汇编】、【链接】各阶段文件的内容。
- 在 iOS 上使用 gcc 编译 C/C++ 文件
- Linux使用GCC编译matlab的m文件使其可执行
- GCC 编译动态库 so文件时,静态链接libmysqlclient.a 与动态链接参数一起使用问题。
- 1.2.在linux环境实践,使用vim编写一个程序,然后使用gcc查看【预处理】、【编译】、【汇编】、【链接】各阶段文件的内容。并熟悉相关指令。
- gcc编译使用log、exp等函数的文件
- Linux使用GCC编译matlab的m文件使其可执行
- 查看库文件编译时所使用的GCC版本号
- 使用gcc编译.c文件,生成汇编.s文件的方法
- gcc和g++区别,使用g++编译多个文件
- windows 下使用gcc编译. c文件的实现方法。
- 使用静态库时需要注意的事项(gcc下程序调用静态库编译命令:主文件必须在静态库前面!)
- windows命令行使用gcc编译.c/.cpp文件
- 菜鸟攻略–C语言多文件编程初探(二):使用 gcc 手动编译多文件 C 程序
- window系统下使用gcc编译简单C程序(缺少regex.h文件库)
- gcc下.a库文件的编译生成和使用
- C语言学习11:typedef和define区别,头文件的使用以及 <>和“”区别,宏定义中#和##的用法,条件编译,gcc和c99中宏定义使用printf和sprintf,条件编译避免头文件包含
- 使用gcc编译时,头文件和库的位置指定参数