本文教你如何在windows上编译gcc16,以体验C++26的反射。以x86_64, ucrt为例
准备工作
你需要:
- 安装 msys2
- 在 msys2 中准备好 gcc 15和其它构建工具:
1 | pacman -S mingw-w64-ucrt-x86_64-toolchain patch base-devel |
准备编译脚本
我们借助 https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-gcc 的脚本来构建gcc。
如果不想clone整个仓库,就用DownGit中把mingw-w64-gcc文件夹下下来,或者用 git 的 sparse-checkout。
然后打开 PKGBUILD 文件,修改如下几个变量:
1 | pkgver=16.0.1 |
然后关闭 Ada 语言支持,因为gcc为其引入了socket,windows下需要修改构建脚本链接ws2_32,但是咱是来体验C++26的,直接关掉最便捷。
1 | if [[ ${CARCH} != i686 ]]; then |
然后关闭 gcc 插件支持,搜索--enable-plugin,注释掉这一行:
1 | local _arch=pentium4 |
这是因为 –enable-plugin 会导出所有符号,gcc 16 的符号数量激增,导致超出了 PE 可执行文件的导出符号数量限制(65,535)。
手动完成 prepare 步骤
首先在mingw-w64-gcc文件夹内执行:
1 | MINGW_ARCH=ucrt64 makepkg-mingw -sLf --skipchecksums --skippgpcheck |
–skipchecksums –skippgpcheck表示跳过哈希校验和gpg校验,因为快照源码没有带 GPG 签名文件,校验不了。
该命令解压完源码后就会出现报错,因为PKGBUILD文件中的prepare()会按顺序打上以下补丁
1 | 0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch |
但是其中有的补丁已经不兼容,有的已经被合并入gcc中。
已知724f36504aa8573883e1919c6968665f8af28aef.patch和e28494e08092c4096a015563c0ba0494ce1edf81.patch不用打,其余的建议手动patch:
1 | cd src/gcc-16-20260308 |
如果报错,会生成一个.rej文件,包含被拒绝的补丁,如果不是已经打过了,就手动打上补丁。
这些补丁都很小,手动打也不耗时间。
打完补丁后,再手动执行prepare()中剩余的指令:
1 | autoreconf -fiv |
然后就可以开始编译了。
编译
再执行以下命令继续编译:
1 | MINGW_ARCH=ucrt64 makepkg-mingw -sLf -e --skipchecksums --skippgpcheck |
-e表示跳过prepare()
随后就是漫长的等待。。。
打包
编译完成后mingw-w64-gcc文件夹内就能得到几个.tar.zst文件
如果你不想把这些包安装进msys2环境,就按照如下步骤打包:
- 把mingw-w64-gcc中生成的所有.tar.zst文件都解压到同一个位置
- 然后下载以下包并解压到相同的文件:
- mingw-w64-ucrt-x86_64-binutils
- mingw-w64-ucrt-x86_64-crt
- mingw-w64-ucrt-x86_64-gmp
- mingw-w64-ucrt-x86_64-headers
- mingw-w64-ucrt-x86_64-libwinpthread
- mingw-w64-ucrt-x86_64-windows-default-manifest
- mingw-w64-ucrt-x86_64-winpthreads
建议更新pacman包列表后用pacman -S -w <包名>下载包,文件会放在path/to/msys2/var/cache/pacman/pkg/内,或者从 https://packages.msys2.org/packages/ 手动下载
- 然后删除.BUILDINFO这几个多余的文件
- 压缩被解压到一起的文件,或者直接用
*如果还是出现缺少dll,直接问ai是缺了哪个包
*以上只包括编译器、汇编器、以及依赖环境,其它工具,如gdb,make,请自己下。
END
恭喜,你已经完成了gcc16的编译,现在该玩反射了😋:
1 | cmake_minimum_required(VERSION 3.10.0) |
1 | #include <print> |