如何避免每次重新编译所有文件?

时间:2017-12-26 10:56:26

标签: c++ performance compiler-errors compilation

我有大约20个.cpp文件和多个.h文件。当我编译时,我做

g++ -std=c++11 main.cpp -o main
在main.cpp中的

我从一些前向声明开始,然后我包含所有.h和.cpp文件。

因此,在每次编译时,必须重新编译所有文件,这令人不舒服地慢。我想我需要使用.so和/或.dll文件,这样在将来的编译中,只需要重新编译修改后的代码。我真的不知道该怎么做。你能给我一些建议吗?

2 个答案:

答案 0 :(得分:2)

  

...然后我包含所有.h和.cpp文件。

.cpp个文件(也称为翻译单元)并不意味着包含。您应该使用脚本或任何其他类型的构建系统,它们分别编译每个.o文件,并将所有生成的.cpp目标文件链接到可执行程序中。

如果它们不受头文件更改的影响,可以启用此功能以避免重新编译所有{{1}}个文件。

答案 1 :(得分:2)

您通常希望单独编译每个translation unit,甚至可以并行编译它们(例如使用make -j,见下文)。

(我猜测并希望你在Linux上并使用GCC作为g++;如果不是,请将此答案改编为编译器和操作系统。)

如果您有src1.cpp src2.cpp src3.cpp(每个都包含适当的#include directives,可能包含公共头文件),您可以将src1.cpp编译为object file src1.o {{ 3}} as:

g++ -Wall -Wextra -g src1.cpp -c -o src1.o

-Wall -Wextra选项会询问所有警告和一些额外的警告,而您确实需要它们(改进代码以获取警告)。 -g选项会询问using GCC调试信息(以后可以DWARF,还可以使用use the gdb debugger)。 -c选项仅需要编译步骤而不进行链接。 -o src1.o表示输出对象文件。

同样,您将src2.cpp编译为src2.o

g++ -Wall -Wextra -g src2.cpp -c -o src2.o

src3.cpp

g++ -Wall -Wextra -g src3.cpp -c -o src3.o

BTW我更喜欢较短的.cc后缀到.cpp。出于基准测试目的,请在编译器中启用valgrind,例如在-O2 -march=native之后添加-g

最后,您希望将optimizations所有三个对象文件src1.osrc2.osrc3.o加入myprog link

g++ -g src1.o src2.o src3.o -o myprog

您可以添加其他选项,例如链接外部库。

请注意executable(以及C ++ 11甚至C ++ 17)没有真正的C++14(与Ocaml或Go相反)。所以预处理器经常使用,你实际上需要包含很多代码;例如,#include <vector>从Linux / Debian桌面上的标准和内部头文件中提取了超过一万行C ++代码。这解释了为什么C ++编译器很慢,因此我建议避免使用太小的C ++文件(例如,只有一百个C ++行的源文件,包括几个头文件,这实际上会吸引数十万个C ++行来自各种内部标题)。我的偏好是在每一个或几千行C ++的.cc(或.cpp)源文件中定义几个相关函数(也许是类)。

(未来的C ++标准,也许是modules,可能会为该语言添加模块;但这可能会被推迟......)

我的建议是学会使用C++20GNU make。确实,你需要一个ninja工具。

您当然应该学习如何在命令行上调用编译器。如果您使用g++,请阅读build automationg++的论据顺序非常重要。

您可以使用生成配置文件的invoking GCCcmake等工具(makeninja)。但我建议使用比cmakemeson更简单的内容(例如,手动编写Makefile代码并使用make)。 mesonmake的{​​{3}}示例。您需要了解您的构建过程。在某些情况下,您可能会在构建期间生成一些(简单的)C ++文件(例如,使用HereMakefile或您自己的脚本或程序发出一些C ++文件。

  

我想我需要使用.so

不一定。 .so个文件是共享库中使用的共享对象。见GNU bison。如上所述,您可以(并且可能首先,您想要)拥有多个目标文件。您稍后可能会考虑制作自己的软件Qt moc,但这仅适用于可重复使用的源代码。

要链接外部库,您甚至可能希望使用this(对于知道它的那些包),它会扩展为g++的适当构建选项。

还要了解现有的libraries项目的灵感,并研究它们的源代码(包括它们的构建过程)。您可以在Linux发行版中以及pkg-configfree software和其他地方找到其中的许多内容。