您通常希望每个 translation unit 单独编译,甚至可以并行编译它们(例如,使用 make -j,见下文)。
(我猜测并希望您在 Linux 上并使用 GCC 作为 g++;如果没有,请将此答案调整为您的编译器和操作系统。)
如果您有src1.cpp src2.cpp src3.cpp(每个都包含适当的#include directives,可能带有一个公共头文件),您可以将src1.cpp 编译成object file src1.o using GCC 为:
g++ -Wall -Wextra -g src1.cpp -c -o src1.o
-Wall -Wextra 选项要求提供所有警告和一些额外的警告,而您确实希望它们(改进您的代码以不收到警告)。 -g 选项要求提供DWARF 调试信息(以便以后能够use the gdb debugger,也可以使用valgrind)。 -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
顺便说一句,我更喜欢较短的 .cc 后缀而不是 .cpp。为了进行基准测试,请在编译器中启用 optimizations,例如通过在-g 之后添加-O2 -march=native。
最后你想将link所有三个对象文件src1.o、src2.o和src3.o转换成myprogexecutable:
g++ -g src1.o src2.o src3.o -o myprog
您可以添加其他选项,例如链接外部库。
请注意C++14(以及 C++11 甚至 C++17)没有真正的modules(与 Ocaml 或 Go 相比)。所以预处理器用的很多,实际上你需要包含很多代码;例如,#include <vector> 正在从我的 Linux/Debian 桌面上的标准和内部头文件中提取一万多行 C++ 代码。这解释了为什么 C++ 编译器很慢,因此我建议避免使用太小的 C++ 文件(例如,只有 100 行 C++ 行的源文件,包括 几个 头文件,这实际上会拉出数十万行 C++ 行来自各种内部标题)。我的偏好是在一行或几千行 C++ 的每个 .cc(或 .cpp)源文件中定义几个相关函数(可能还有类)。
(未来的 C++ 标准,也许是 C++20,可能会在语言中添加模块;但这可能会被推迟......)
我的建议是学习使用GNU make 或ninja。确实,您需要一个build automation 工具。
您当然应该学习如何在命令行上调用编译器。如果您使用g++,请阅读invoking GCC。 g++ 的参数顺序非常重要。
您可以使用cmake 或meson 等工具生成配置文件(用于make 或ninja)。但我推荐比cmake 或meson 更简单的东西(例如,手动编写Makefile 并使用make)。 Here 是 Makefile 的示例,用于 make。您需要了解您的构建过程。在某些情况下,您可能会在构建过程中生成一些(简单的)C++ 文件(例如,使用GNU bison 或Qt moc 或您自己的脚本或程序发出一些C++ 文件)。
我想我需要使用.so
不一定。 .so 文件是共享对象,在共享库中使用。见this。如上所述,您可以(并且可能一开始想要)拥有多个目标文件。您以后可能会考虑制作自己的软件libraries,但这仅对可重用的源代码是值得的。
要链接外部库,您甚至可能想要使用pkg-config(对于那些知道它的包),它扩展为g++ 的适当构建选项。
还可以查看现有的 free software 项目以获取灵感,并研究它们的源代码(包括它们的构建过程)。您会在 Linux 发行版、github、sourceforge 和其他地方找到其中的许多。