最近在弄GCC的预编译头,用C++开发工程最难以忍受的就是乌龟似地的编译速度,用VC开发工程的时候,VC会默认帮我们引入预编译头,那么GCC呢?其实GCC也是支持预编译头得, http://lych.yo2.cn/articles/浅谈gcc预编译头技术.html 这篇文章就详细讲解了如何GCC下预编译头得一些知识, 所以具体如何在GCC中加入预编译头,大家可以参考这篇文章。
在给GCC添加预编译头时也遇到了一些问题,并且对C++/C的编译有了一些新的认识!
很多在linux下写程序的人都应该看过《和我一起写Makefile》这篇文章,里面讲过如何利用GCC的-MM选项自动生成依赖:
%.d: %.cpp
@$(GPP) -MM $(INCLUDE) $< > $@.tmp;\
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.tmp > $@;\
rmf $@.tmp
这里利用了一个模式规则,将CPP文件依赖的头文件写到一个.d文件中,执行Makefile时我们只需要include这些.d文件,GCC就会根据里面的依赖关系来生成对应的.o文件了!
但是实际上GCC的自动推导能力非常强大,我们其实只需要写下一条这样的模式就可以了,
%.o:%.cpp
@$(GPP) $(CPPFLAGS) $< $(INCLUDE)
GCC就会自动推导出CPP文件所需要依赖的头文件进行编译了!
如果你在自己的工程中加入了预编译头,你就必须使用下面一种模式。
举个例子,比如你们工程开发了一些基础库,已经比较稳定了,除了一些少量的BUG FIX外,很少需要修改,当你通过源码形式引用的时候,你当然不希望每次编译的时候都去编译
这些基础库,如是你决定将他们加入预编译头中去,但是当你使用第一种方式写Makefile的时候,你发现被你加入到预编译头中的头文件还是被重复编译了,因为-MM选项会把你CPP文件
依赖的非系统头文件全部放在对应的.d文件中。但是当你使用第二种Makefile时,GCC看到一个预编译头后,他不会按照常规的方式将它展开,而是回去寻找对应的.gch文件,然后进行编译,
如果你想一探究竟的话,编译加上-H选项就可以看出其中的差异了!
这样生成的预编译头如果要使用的话,需要和编译CPP文件使用相同的选项,否则后出现一些奇怪的编译错误,我的做法是写一个预编译头得模式:
%.h.gch:%.h
$(GPP) $(CPPFLAGS) $< $(INCLUDE)