我有大约20个.cpp文件和多个.h文件。当我编译时,我做
g++ -std=c++11 main.cpp -o main
在main.cpp中的我从一些前向声明开始,然后我包含所有.h和.cpp文件。
因此,在每次编译时,必须重新编译所有文件,这令人不舒服地慢。我想我需要使用.so
和/或.dll
文件,这样在将来的编译中,只需要重新编译修改后的代码。我真的不知道该怎么做。你能给我一些建议吗?
答案 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.o
,src2.o
和src3.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++20或GNU make。确实,你需要一个ninja工具。
您当然应该学习如何在命令行上调用编译器。如果您使用g++
,请阅读build automation。 g++
的论据顺序非常重要。
您可以使用生成配置文件的invoking GCC或cmake等工具(make
或ninja
)。但我建议使用比cmake
或meson
更简单的内容(例如,手动编写Makefile
代码并使用make
)。 meson是make
的{{3}}示例。您需要了解您的构建过程。在某些情况下,您可能会在构建期间生成一些(简单的)C ++文件(例如,使用Here或Makefile
或您自己的脚本或程序发出一些C ++文件。
我想我需要使用
.so
不一定。 .so
个文件是共享库中使用的共享对象。见GNU bison。如上所述,您可以(并且可能首先,您想要)拥有多个目标文件。您稍后可能会考虑制作自己的软件Qt moc,但这仅适用于可重复使用的源代码。
要链接外部库,您甚至可能希望使用this(对于知道它的那些包),它会扩展为g++
的适当构建选项。
还要了解现有的libraries项目的灵感,并研究它们的源代码(包括它们的构建过程)。您可以在Linux发行版中以及pkg-config,free software和其他地方找到其中的许多内容。