第1.6章: GCC
GCC(GNU 编译器集合)是世界上最古老、使用最广泛的 C 和 C++ 编译器之一。它是许多 Linux 发行版的默认编译器,以其稳定性、可移植性以及在开源生态中的悠久历史而著称。
理解 GCC 的工具链模型
GCC 使用其文档中描述的三元组配置模型:
GCC 区分:
- --build:构建 GCC 的机器
- --host:运行 GCC 的机器
- --target:GCC 为其生成二进制文件的机器
与 Clang 不同,GCC 不能在编译时自由设置 --target。
这意味着 GCC 必须针对每个目标架构与 sysroot 组合分别构建。
因此,GCC 交叉编译器比 Clang 的更笨重、更不灵活,也更难维护。
下载 GCC 工具链
预构建的 GCC 工具链可在此获取:
每个压缩包遵循如下命名模式:
target.host.tar.xz
例如:
x86_64-linux-gnu.x86_64-w64-mingw32.tar.xz
这表示:
- host:
x86_64-w64-mingw32→ 运行在 Windows 上 - target:
x86_64-linux-gnu→ 产出 Linux 二进制文件
解压压缩包后,把包含 x86_64-linux-gnu-g++ 的 bin 目录
加入你的 Windows PATH。
在 Windows 上使用 GCC 编译 Linux 二进制文件
一旦工具链进入你的 PATH,你就可以直接在 Windows 上编译 Linux 二进制文件:
x86_64-linux-gnu-g++ -o hello hello.cpp -O3 -s -flto
然后把 hello 拷贝到你的 Linux 机器上,将其标记为可执行:
chmod +x hello
然后正常运行它。
使用 GCC 编译 Windows 二进制文件
最容易使用的 GCC 工具链是:
x86_64-w64-mingw32.x86_64-w64-mingw32.tar.xz
这个工具链运行在 Windows 上,并产出 Windows 二进制文件。 你有两种使用方式:
1. 在 Windows 上编译
把工具链的 bin 目录加入你的 Windows PATH,然后编译:
g++ -o hello.exe hello.cpp -O3 -std=c++26 -s -flto
你可以在 Windows 上直接运行 hello.exe。
2. 在 Linux 上通过 Wine 编译
在 Linux 上,你可以通过 Wine 运行 Windows 版的 GCC 编译器。
设置 WINEPATH 以包含工具链的 bin 目录:
wine g++ -o hello.exe hello.cpp -O3 -std=c++26 -s -flto
这会产出 Windows 可执行文件,你可以这样运行:
wine ./hello.exe
这种方法通常比在 Linux 上配置本地 GCC 交叉编译器更简单。
关于面向 Linux 的 GCC 工具链
你也可以尝试这样的工具链:
x86_64-linux-gnu.x86_64-linux-gnu.tar.xz
然而,如果你使用的发行版带有较老版本的 glibc,
这样构建的 Linux 二进制文件可能无法运行。这是 GCC 构建的 Linux 二进制文件的常见问题。
Clang 避免了这个问题,因为它在交叉编译时不依赖宿主系统的 glibc 版本。
运行时库
GCC 二进制文件依赖 GNU C++ 运行时(libstdc++),有时还依赖其他 GCC 运行时库。
运行 GCC 构建的二进制文件时,你可能需要设置:
- LD_LIBRARY_PATH(Linux / BSD / Android)
- WINEPATH(如果在 Linux 下用 Wine 运行 Windows 二进制文件)
这些环境变量确保运行时库能被正确找到。
自行构建 GCC
GCC 官方鼓励用户从源码构建 GCC。 他们不提供官方的预构建二进制文件。
如果你打算自行构建 GCC,可以通过以下选项简化流程:
--disable-bootstrap
这可以避免多阶段的自我重建过程,并显著加快编译速度。
或者,你也可以直接在 Wine 下使用 Windows 版 GCC 二进制文件,这通常更容易,也能避免 glibc 兼容性问题。
后续章节:构建你自己的 GCC 与 LLVM 工具链
在本章中,我们只关注使用预构建的 GCC 工具链。 然而,GCC 和 LLVM 都可以完全从源码构建,包括完整的交叉编译器。
在后续章节中,我们将讲解如何使用加拿大编译来创建你自己的 GCC 与 LLVM 工具链——这是一种构建机、宿主机和目标机三者互不相同的技术。 它是为任意架构或操作系统生产可移植、可复现工具链的标准方法。
一旦你理解了加拿大编译,你就能完全在自己的系统上为 Linux、Windows、macOS、 Android、WebAssembly 等构建工具链。