msvc编译路径_C++加快编译速度(FastBuild)的措施总结
1. 前项声明 - 尽可能的使⽤forward来声明⽽不是直接包含定义
2. pimp模式 - 将实现隐藏在指针内,放在⼀个分离的class中。另外⼀种范式就是通过定义抽象类,然后⼦类化他所对应的接⼝,这样女女接吻
网家你所依赖的是稳定的接⼝函数,不会随着他的实现的修改⽽重新编译。
3. 并⾏编译 - 在Visual Studio中你通过打开flag /MP[processorMax]或者在Make中通过追加-jN来实现。如果你⽤的CMake你可以
简笔画植物通过target_compile_options来追加,⽐如你也可以直接命令⾏给Make参数
4. 分布式编译 - 我们可以通过追加nodes来加快我们编译速度, 当你设置好⽐如distcc之后,你在CMake 3.4可以定义这个选项来帮助
你使⽤distcc, cmake -DCMKAE_CXX_COMPILER_LAUNCHER=/usr/bin/distcc /path/to/cmakedir. 让你的source file在你的本机或其他机器上进⾏预处理(注意:如果你想在预处理阶段交给所有的机器,你需要统⼀他们的compile versions, libraries等)在本地和其他机器上进⾏compile接收来⾃其他机器的objs进⾏link
5. Compiler Cache(编译缓存) - 这个机制建⽴的前提是不再依靠时间戳timestamp来做某个⽂件是否要重新编译的依据,相反,他建⽴
在根据⽂件本⾝的内容和compiler flags来建⽴计算对应的hash value. 再把每个hash value和obj files做好注册映射放在compiler cache⾥,这样⼀旦你需要重新编译某个内容没有更改的cpp,他就会直接从这个cache中帮你拿过来。UNIX⽐较流⾏的就是ccahe, Windows的话可以使⽤clcache. 同样的,你也可以通过cmake -DCMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/ccache /path/to/cmakedir来建⽴这个CMake关系。 当然了,你甚⾄可以结合第四部的分布式编译,你需要设置的环境变量是export CCACHE_PREFIX=distcc 然后再利⽤上⾯的cmake .. -Dxxx来建议你的compiler launcher即可
木板雕刻6. 预编译头⽂件(Precompiled Header Files) - 把⼀系列需要⼀直包含的那些重型头⽂件(⽐如iostream)单独拎出来放到⼀个额外的⽂
件中去,并且对他进⾏编译,然后把这个编译后的⽂件给所有的编译单元(translation units)进⾏include在最开始的时候。 在MSVC 下,你需要创建两个⽂件,⼀个是stdafx.h另外⼀个是stdafx.cpp 你需要先编译stdafx.cpp通过/Yc"path-to-stdafx.h"默认会为你⽣成⼀个.pch的⽂件当你想使⽤这个pch⽂件的时候,你既需要指定Fp"path-to-pch"和/Ycand /Yu来指定你的.pch⽂件的路径。随后我们需要修改我们的cpp,要么就是在最开始的时候进⾏#include "path-to-stdafx.h"要么就直接加/FI"path-to-stdafx.h"这个编译选项。在GCC下会有点不同,你需要传递给complier的是prefix header⽽不是编译好后的⽂件。 由编译器来帮你⾃动⽣成对应的.gch编译⽂件。 然后你通过-x这个选项,你可以指定是否是c-header还是c++-header, 随后你就可以通过在你的源码中进⾏#include或者直接gcc的-include来
强制包含达到结合这个预处理头⽂件的⽬的CMake在3.16引⼊了
target_precompiled_headers,在这个版本之前你可以尝试搜索cotire这个module,他会⾃动帮你做对应的pch处理闰五月
7. Single Compilation Unit(统⼀化编译单元) - 运⾏核⼼的原理是通过⼀个cpp去包含别的cpp组装成⼀个巨⼤的cpp,⽐如,如果⼀个
⽂件包含了所有的translation units,那么这个⽅法就叫为Unity Build。下⾯是他的诸多优点: 编译单元的数量急剧减少,因此你的磁盘操作数也会下降。编译器针对模板实例化的操作也下降,这个极⼤的优化了编译的时间LTO(Link Time
Optimization)/WPO(Whole Program Optimization)的linker优化可以进⾏实施这会对你DevOps的incremental build有⼀些恶化的效果,因为此时当你修改某个编译单元之后,你的整个single translation unit都要重新编译因为使⽤了Unity Build,因此你再想使⽤分布式编译已经不可能了,因为此时的cpp就没⼏个当然⽤这种⽅法之后其实也有有⼀些缺点: 违反ODR原则(在匿名空间中的macros,local static functions, global static variables会容易起冲突)你可能需要使⽤namespace来做名字的格⼒多核系统会因为这个受益颇多: 针对多个Single Compliation Unit并⾏编译并且使⽤precompiled header利⽤compiler cache的分布式编译
夫子庙灯会
浪人情歌简谱8. 替换你的编译组件 - ⽐如你可以替换你的ld为gold,如果你的binutils是2.19以后的版本,那默认会随着这个⼯具,你也可以通过-
无花果瘦肉汤fu-ld=gold来让gcc帮你选择gold,下⾯是⼀个CMake的实⼒版本来invoke你的gold,当然如果你有llvm的ldb其实更好,他甚⾄⽐你的gold更快