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

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中配置预编译头加快编译速度的更多相关文章

  1. 在Editplus中配置java的(带包)编译(javac)和运行(java)的方法

    配置的前提是电脑安装了JDK并且配置好了相关的环境变量(JAVA_HOME,path和classpath). 配置好后在命令行中输入javac和java验证是否配置成功: 如果出现上面的情况则说明配置 ...

  2. 在eclipse中配置android ndk的自动编译环境builders

    无论linux还是mac在jni目录中直接运行  ndk-build 就可以生成 lib目录及所需要的 so文件: windows 装上lnx模拟器也是一样: 每次修改完 c++代码, 都要运行一下 ...

  3. 在Editplus中配置java的(带包)编译(javac)和执行(java)的方法

    配置的前提是电脑安装了JDK而且配置好了相关的环境变量(JAVA_HOME,path和classpath). 配置好后在命令行中输入javac和java验证是否配置成功: 假设出现上面的情况则说明配置 ...

  4. 在Ubuntu14.4(32位)中配置I.MX6的QT编译环境

    1,开发工具下载 一,下载VMware Workstation虚拟机 地址:http://1.xp510.com:801/xp2011/VMware10.7z 二,下载Ubuntu 14.04.5 L ...

  5. 在 .pro里加入 QMAKE_CXXFLAGS += /MP 将并行编译,加快编译速度(姚冬的办法)

    但是只对VC编译器有效果. 另外还可以自己设置stdafx.h文件 http://www.zhihu.com/question/23045749

  6. SASS环境搭建及HBuilder中sass预编译配置

    ---------------------------------Ruby环境安装-------------------------------- 至于为什么要安装ruby环境请移步:https:// ...

  7. QT:提高QT Creator编译速度,配置预编译头Stable.h

    提高QT Creator编译速度,配置预编译头Stable.h QT Creator支持预编译头提高编辑速度,网上有些教程写得不详细,走了弯路,具体实现方法如下. (1)工程.PRO文件加入下面代码 ...

  8. 带你玩转Visual Studio——带你理解微软的预编译头技术

    原文地址:http://blog.csdn.net/luoweifu/article/details/49010627 不陌生的stdafx.h 还记得带你玩转Visual Studio——带你新建一 ...

  9. fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "StdAfx.h"”? 解决方法

    错误描述: fatal error C1010: 在查找预编译头时遇到意外的文件结尾.是否忘记了向源中添加“#include "StdAfx.h"”? 错误分析:     此错误发 ...

随机推荐

  1. android 拖拉和放大

    public class MainActivity extends Activity { private ImageView imageView; @Override public void onCr ...

  2. enovia plm export to sap

    UPC creation UPC 结构 PLM 使用的UPC 是 14个数字组成的,兼容. 前两位为 0,后12位为有效数字,在SAP中0会被忽略,符合国际UPC通用 规则, 前一位为0,后13 位为 ...

  3. Java 简单链表实现

    1.初衷 最近在看Java基础,有一章节涉及到链表,便记之所学所得. 2.链表的定义 链表是存储地址不连续的线性存储结构 3.链表的基本结构 一个节点包含当前节点,与下个节点的引用 4.简单链表的实现 ...

  4. 简单记录下Jmeter通过CSV保存测试数据,测试用例,及将测试结果导出到Excel里

    1.CSV保存测试数据,并上传到CSV Data Set Config,设置相关属性 2.CSV保存测试用例,并上传到CSV Data Set Config,设置相关属性 3.设置一个http请求,设 ...

  5. Clickhouse集群部署

    1.集群节点信息 10.12.110.201 ch201 10.12.110.202 ch202 10.12.110.203 ch203 2. 搭建一个zookeeper集群 在这三个节点搭建一个zo ...

  6. Windows win32 API 类库 硬件

    // 硬件 Win32_Processor, // CPU 处理器 Win32_PhysicalMemory, // 物理内存条 Win32_Keyboard, // 键盘 Win32_Pointin ...

  7. apue 第18章 终端I/O

    终端I/O有两种不同的工作模式: (1)规范模式:输入以行单位进行处理,每个读请求也最多返回一行. (2)非规范模式:输入字符不装配成行. 终端设备是由通常位于内核中的终端驱动程序控制的.每个终端设备 ...

  8. C语言新手写扫雷攻略3

    界面绘制好后,雷数也布置了,接下来就是游戏的运行过程了,今天先不说具体过程,再来看看需要用到的辅助函数 先是简单的画红旗,鼠标右键的功能是画红旗,至此我们都是在使用函数自己绘图,效率是低,但有助于理解 ...

  9. VS2012编译WDM驱动

    新版的VS2012中集成了WDK8,而且WDK8中已经没有之前的Build Environment了,看来编译驱动只能通过VS2012了,直接开发WDF驱动很方便直接选取相应的模板即可,若是编译以前的 ...

  10. springboot接口:CommandLineRunner

    springBoot接口:CommandLineRunner 一.作用: 在使用SpringBoot构建项目时,我们通常有一些预先数据的加载.那么SpringBoot提供了一个简单的方式来实现–Com ...