编译器与工具链
编译器是 C/C++ 构建链里真正把源码变成目标文件、库和可执行文件的工具。Make、CMake、Ninja、SCons 最终都会调用编译器和链接器。
这篇只讲使用方式,不讲编译原理。
常见编译器定位
| 工具 | 常见平台 | 定位 |
|---|---|---|
GCC / g++ | Linux、MinGW | GNU 编译器套件 |
Clang / clang++ | macOS、Linux、Windows | LLVM 编译器,诊断信息友好 |
MSVC / cl | Windows | Visual Studio C/C++ 编译器 |
| MinGW | Windows | Windows 上的 GCC 工具链 |
| 交叉编译器 | 嵌入式、跨平台 | 在当前机器生成另一个平台的程序 |
最小编译命令
main.cpp:
#include <iostream>
int main()
{
std::cout << "Hello compiler" << std::endl;
return 0;
}GCC:
g++ main.cpp -std=c++17 -Wall -Wextra -o app
./appClang:
clang++ main.cpp -std=c++17 -Wall -Wextra -o app
./appMSVC,需要在 Developer Command Prompt 或已配置环境的终端里:
cl /std:c++17 /EHsc main.cpp /Fe:app.exe
app.exe多文件项目
目录:
hello-compiler/
├── include/
│ └── hello.h
└── src/
├── hello.cpp
└── main.cppGCC/Clang:
g++ src/main.cpp src/hello.cpp -Iinclude -std=c++17 -o app分步编译和链接:
g++ -Iinclude -std=c++17 -c src/main.cpp -o main.o
g++ -Iinclude -std=c++17 -c src/hello.cpp -o hello.o
g++ main.o hello.o -o appMSVC:
cl /std:c++17 /EHsc /Iinclude src\main.cpp src\hello.cpp /Fe:app.exeDebug / Release
| 类型 | GCC/Clang 常见参数 | MSVC 常见参数 | 说明 |
|---|---|---|---|
| Debug | -g -O0 | /Zi /Od | 方便调试,不追求性能 |
| Release | -O2 -DNDEBUG | /O2 /DNDEBUG | 优化性能,关闭 assert |
示例:
g++ src/main.cpp src/hello.cpp -Iinclude -g -O0 -std=c++17 -o app-debug
g++ src/main.cpp src/hello.cpp -Iinclude -O2 -DNDEBUG -std=c++17 -o app-releaseinclude path、library path、link
| 概念 | GCC/Clang | MSVC | 作用 |
|---|---|---|---|
| 头文件路径 | -Iinclude | /Iinclude | 让编译器找到 .h |
| 库文件路径 | -Llib | /link /LIBPATH:lib | 让链接器找到库文件 |
| 链接库 | -lfoo | foo.lib | 链接具体库 |
| 宏定义 | -DDEBUG | /DDEBUG | 定义预处理宏 |
GCC/Clang 链接示例:
g++ main.cpp -Iinclude -Llib -lfoo -o appMSVC 链接示例:
cl /Iinclude main.cpp /Fe:app.exe /link /LIBPATH:lib foo.lib交叉编译器
交叉编译器的名字通常带目标平台前缀:
arm-none-eabi-g++ main.cpp -mcpu=cortex-m4 -mthumb -o firmware.elf
aarch64-linux-gnu-g++ main.cpp -o app在 CMake 中通常通过 toolchain file 指定:
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=toolchain-arm.cmake
cmake --build build核心命令自查表
| 命令 | 作用 |
|---|---|
g++ main.cpp -o app | 编译并链接单文件 |
g++ -c main.cpp -o main.o | 只编译,不链接 |
g++ main.o hello.o -o app | 链接目标文件 |
g++ -Iinclude main.cpp -o app | 增加头文件搜索路径 |
g++ main.cpp -Llib -lfoo -o app | 链接库 |
clang++ main.cpp -o app | 使用 Clang 编译 |
cl main.cpp /Fe:app.exe | 使用 MSVC 编译 |
g++ --version | 查看 GCC 版本 |
clang++ --version | 查看 Clang 版本 |
cl | 查看 MSVC 是否可用 |
常见错误
| 现象 | 原因 | 处理 |
|---|---|---|
No such file or directory | 头文件路径没加 | 加 -I 或 /I |
undefined reference | 声明有了,但实现没链接进来 | 加源文件、目标文件或库 |
cannot find -lfoo | 链接器找不到库 | 检查 -L 路径和库名 |
LNK2019 | MSVC 未解析外部符号 | 检查 .cpp 或 .lib 是否参与链接 |
cl 不是命令 | 没进入 VS 开发者环境 | 使用 Developer Command Prompt |
注意事项
- 真实项目不建议长期手写超长编译命令,交给 Makefile 或 CMake 管理。
- C 和 C++ 编译器不要混用链接阶段;C++ 项目通常用
g++、clang++或cl进行最终链接。 - Windows 上要注意 x86/x64、Debug/Release、静态/动态运行库一致。