在VisualGDB中配置预编译头加快编译速度

今天是中秋佳节,但是写完已经是第二天凌晨了,还是祝大家中秋快乐!

VS对C++的支持相较GCC太弱了,连续几个VS版本对C++的改进都很小、很少。对Cpper也许是一种痛,我们也许希望能使用VS的强大编辑功能,组合GCC以及GDB的强大编译器以及调试功能进行开发。自从有了VisualGDB,这一切都变成真的了,那VS默认会有预编译头,GCC呢?VisualGDB呢?我们只能手动去写Makefile,不错,手动去写,下面就与大家分享VisualGDB中的预编译头设置。

在之前的博客(VisualGDB使用随笔)中提到,我初尝螃蟹,发现了VisualGDB这个超级好用的VS插件后,一直是爱不释手。但后面的几年时间里一直没新项目可以使用这个工具,一展其光辉。博客最后也提到了要分享VisualGDB中添加预编译以及类似VS的Compile输出而不是一长串命令行的修改。实在不好意思,事隔三年了,今天才将它分享出来。

在大项目中添加预编译头的好处,我就不多说了。

说起预编译头,让我想起了一个我亲身经历的事:前几年初到一家公司做项目,由于该项目比较庞大,机器配置也比较差,当时要全部重新编译一次项目大概需要半小时(也许有人说可以使用联合编译,确实,公司就是使用的联合编译,但编译一次也得在十几分钟的样子),为什么会这样,我看了一下项目配置,居然没配置预编译头。对我而言,编译一次需要最少需要10几分钟,去上个厕所,去冲杯咖啡回来都还没编译完成,我实在是受不了。于是我决定加上预编译头,由于项目比较大,文件比较多,头文件的包含顺序错综复杂,不想手工去一个一个理(估计得理个几天吧),就写了一个小工具去整理这些包含顺序,自动生成 一个预编译头文件。最后弄下来,编译速度得到了极大提高,直接单机编译只需要三五几分钟就编译完成(为此公司还给我发了一笔奖金)。

好了,言归正传,我们知道VisualGDB自动生成的Makefile中并不包括预编译头的任何选项,只能通过自己修改Makefile来达到目的。对于初学者或者根本不懂Makefile的同学来说是有一定难度的。使用过VS的同学一定知道,VS的项目配置中一个项目只能配置一个预编译头,如果这个项目既使用了C又使用了C++那么两者是不能同时生成预编译头的。而GCC,准确的说应该是使用Makefile的方式就可以做到,下面就为大家分享VisualGDB项目生成的Makefile如何同时生成和使用C以及C++的预编译头。

关于普通的GCC项目使用预编译头加快编译速度可以参考之前我转的一篇文章《使用 GNU CC 的预编译头文件加快编译速度》,VisualGDB生成的Makefile与文中所示的Makefile类似,只是VisualGDB的Makefile会根据项目中的文件自动修改其中的SOURCEFILES参数,但规则部分是一经生成就不会被修改,而我们要做的也是修改规则。

BTW:当然如果不想让VisualGDB自动添加项目文件到SOURCEFILES项,可以把Makefile中的

#VisualGDB: AutoSourceFiles		#<--- remove this line to disable auto-updating of SOURCEFILES and EXTERNAL_LIBS

删除掉即可(不建议删除)

我们看一下VisualGDB自动生成的Makefile编译规则部分:

#VisualGDB: FileSpecificTemplates		#<--- VisualGDB will use the following lines to define rules for source files in subdirectories
$(BINARYDIR)/%.o : %.cpp $(all_make_files) |$(BINARYDIR)
	$(CXX) $(CXXFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

$(BINARYDIR)/%.o : %.c $(all_make_files) |$(BINARYDIR)
	$(CC) $(CFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

$(BINARYDIR)/%.o : %.S $(all_make_files) |$(BINARYDIR)
	$(CC) $(CFLAGS) $(ASFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

$(BINARYDIR)/%.o : %.s $(all_make_files) |$(BINARYDIR)
	$(CC) $(CFLAGS) $(ASFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

$(BINARYDIR)/%.o : %.cc $(all_make_files) |$(BINARYDIR)
	$(CC) $(CFLAGS) $(CXXFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

$(BINARYDIR)/%.o : %.cxx $(all_make_files) |$(BINARYDIR)
	$(CC) $(CFLAGS) $(CXXFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

#VisualGDB: GeneratedRules				#<--- All lines below are auto-generated

这里列出了以下几种源文件的编译规则:

1.扩展名为cpp、cc、cxx的C++源文件

2.扩展名为c的C源文件

3.扩展名为s、S的汇编源文件,这种汇编文件一般是AT&T格式的汇编文件而不是Intel格式的汇编文件。

为了让项目同时支持C以及C++的预编译头,首先我们假定C及C++的头文件使用如下选项来定义:

# C Header
PCH_H = prec.h
PCH = prec.h.gch

# C++ Header
PCH_X_H = prec.hpp  
PCH_X = prec.hpp.gch

这部分代码可以放在Makefile的生成规则之前的某个适当位置,也可以放在debug.mak和release.mak中,需要特别注意的是预编译生成的文件一定是在预编译头文件后加gch后缀,同时要求预编译文件头文件在同一个目录,不然GCC找不到预编译文件。然后在Makefile

#VisualGDB: GeneratedRules				#<--- All lines below are auto-generated

这行之前加上生成预编译头的规则,

# C Prec Header Rule
$(BINARYDIR)/$(PCH) : $(PCH_H)
	$(CC) $(CFLAGS) $> $^
	
# C++ Prec Header Rule
$(BINARYDIR)/$(PCH_X) : $(PCH_X_H)
	$(CXX) $(CXXFLAGS) $> $^

添加好预编译头的规则后,我们还需要使用生成的预编译头,注意C与C++的预编译头不能混合使用,不能编译会报错。例如添加cpp以及c源文件的预编译头使用规则:

$(BINARYDIR)/%.o : %.cpp $(all_make_files) |$(BINARYDIR) $(BINARYDIR)/$(PCH_X)
	$(CXX) $(CXXFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

$(BINARYDIR)/%.o : %.c $(all_make_files) |$(BINARYDIR) $(BINARYDIR)/$(PCH)
	$(CC) $(CFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

此时我们在项目中添加两个头文件prec.h以及prec.hpp就可以自动生成并使用各自的预编译头了。

最后,使用惯了VS的同学可能不太习惯编译时的一大串命令行,没关系,我们也可以通过修改Makefile来做到只显示简要信息。我们规则部分的命令使用@符号作前缀即可,知道DOS命令的同学应该比较熟悉如下命令

@echo off
@echo on

然后加上我们想要显示的信息比如Compile XXX

好了,下面我就直接把完整的Makefile规则部分贴出来:

#VisualGDB: FileSpecificTemplates		#<--- VisualGDB will use the following lines to define rules for source files in subdirectories
$(BINARYDIR)/%.o : %.cpp $(all_make_files) |$(BINARYDIR) $(BINARYDIR)/$(PCH_X)
	@$(CXX) $(CXXFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)
	@echo Compile $<

$(BINARYDIR)/%.o : %.c $(all_make_files) |$(BINARYDIR) $(BINARYDIR)/$(PCH)
	@$(CC) $(CFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)
	@echo Compile $<

$(BINARYDIR)/%.o : %.S $(all_make_files) |$(BINARYDIR)
	$(CC) $(CFLAGS) $(ASFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

$(BINARYDIR)/%.o : %.s $(all_make_files) |$(BINARYDIR)
	$(CC) $(CFLAGS) $(ASFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

$(BINARYDIR)/%.o : %.cc $(all_make_files) |$(BINARYDIR) $(BINARYDIR)/$(PCH_X)
	$(CC) $(CFLAGS) $(CXXFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

$(BINARYDIR)/%.o : %.cxx $(all_make_files) |$(BINARYDIR) $(BINARYDIR)/$(PCH_X)
	$(CC) $(CFLAGS) $(CXXFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)
	
# C Prec Header Rule
$(BINARYDIR)/$(PCH) : $(PCH_H)
	@$(CC) $(CFLAGS) $> $^
	@echo Compile $^
	
# C++ Prec Header Rule
$(BINARYDIR)/$(PCH_X) : $(PCH_X_H)
	@$(CXX) $(CXXFLAGS) $> $^
	@echo Compile $^

#VisualGDB: GeneratedRules				#<--- All lines below are auto-generated


祝大家玩得愉快!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值