在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
祝大家玩得愉快!
在VisualGDB中配置预编译头加快编译速度的更多相关文章
- 在Editplus中配置java的(带包)编译(javac)和运行(java)的方法
配置的前提是电脑安装了JDK并且配置好了相关的环境变量(JAVA_HOME,path和classpath). 配置好后在命令行中输入javac和java验证是否配置成功: 如果出现上面的情况则说明配置 ...
- 在eclipse中配置android ndk的自动编译环境builders
无论linux还是mac在jni目录中直接运行 ndk-build 就可以生成 lib目录及所需要的 so文件: windows 装上lnx模拟器也是一样: 每次修改完 c++代码, 都要运行一下 ...
- 在Editplus中配置java的(带包)编译(javac)和执行(java)的方法
配置的前提是电脑安装了JDK而且配置好了相关的环境变量(JAVA_HOME,path和classpath). 配置好后在命令行中输入javac和java验证是否配置成功: 假设出现上面的情况则说明配置 ...
- 在Ubuntu14.4(32位)中配置I.MX6的QT编译环境
1,开发工具下载 一,下载VMware Workstation虚拟机 地址:http://1.xp510.com:801/xp2011/VMware10.7z 二,下载Ubuntu 14.04.5 L ...
- 在 .pro里加入 QMAKE_CXXFLAGS += /MP 将并行编译,加快编译速度(姚冬的办法)
但是只对VC编译器有效果. 另外还可以自己设置stdafx.h文件 http://www.zhihu.com/question/23045749
- SASS环境搭建及HBuilder中sass预编译配置
---------------------------------Ruby环境安装-------------------------------- 至于为什么要安装ruby环境请移步:https:// ...
- QT:提高QT Creator编译速度,配置预编译头Stable.h
提高QT Creator编译速度,配置预编译头Stable.h QT Creator支持预编译头提高编辑速度,网上有些教程写得不详细,走了弯路,具体实现方法如下. (1)工程.PRO文件加入下面代码 ...
- 带你玩转Visual Studio——带你理解微软的预编译头技术
原文地址:http://blog.csdn.net/luoweifu/article/details/49010627 不陌生的stdafx.h 还记得带你玩转Visual Studio——带你新建一 ...
- fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "StdAfx.h"”? 解决方法
错误描述: fatal error C1010: 在查找预编译头时遇到意外的文件结尾.是否忘记了向源中添加“#include "StdAfx.h"”? 错误分析: 此错误发 ...
随机推荐
- MySQL中的触发器insert、update
以下为MySQL 触发器insert 的3个示例演示(update类似) delimiter // create trigger InsertUser before insert on user fo ...
- element ui step组件在另一侧加时间轴显示
这是我开发的时候遇到的一个问题:项目需要在步骤条(竖直方向)的另一侧加时间显示,但是我在element ui 的step组件中一直没找着设置方法,所以就自己想了个办法加进来,效果如下: 代码如下,先上 ...
- js函数方法
/** * call()和apply * 这两个方法都是函数对象的方法,需要通过函数对象来调用 * 当对函数调用call()和apply()都会调用函数执行 * 在调用call()和apply()可以 ...
- ES5新增方法(数组,字符串,对象)
一.数组方法 迭代(遍历)方法:forEach().map().filter().some().every(): 1. array. forEach(function(value,index,arr) ...
- Light项目---实现后端接口时遇见的一些问题
ImproperlyConfigured: WSGI application 'lightapi.wsgi.application' could not be loaded; 在moddleware中 ...
- OpenGL学习——绘制第一个三角形
终于把三角形绘制出来了,首先一些关键概念.操作. Vertex Data 顶点数据 VBO Vertex Buffer Objects 顶点缓冲对象 VA ...
- Linux账号管理与ALC权限设定(二) 批量增加用户脚本
接上篇.鸟哥提出了一个问题.就是 如果myuser1用户是这个项目的助理,他只能查看该目录下的内容,而无法修改删除.那该如何操作呢? 首先,不能将该用户加入projecta这个群组,否则他也可以修改删 ...
- shell script 学习
终于来到了shell脚本的学习,貌似很牛叉. shell script鸟叔解释:利用shell的功能写的一个program,使用纯文本文件,将一些shell语法和指令写在里面,搭配正则表示法,管线命令 ...
- sysprep
今天做虚拟机模板,以及克隆.单纯的克隆会造成很多冲突问题的产生,所以在这里,windows自带的sysprep功能很好的解决了这一点. 路径位于:C:\Windows\System32\Sysprep ...
- git安装和使用方法url
1.如何在ubuntu下使用Github? https://blog.csdn.net/tina_ttl/article/details/51326684 https://segmentfault.c ...