编译 gcc 16,体验 C++26 反射

  • ~3.73K 字
  • 次阅读
  • 条评论
  1. 1. 准备工作
  2. 2. 准备编译脚本
  3. 3. 手动完成 prepare 步骤
  4. 4. 编译
  5. 5. 打包
  6. 6. END

本文教你如何在windows上编译gcc16,以体验C++26的反射。以x86_64, ucrt为例

准备工作

你需要:

  1. 安装 msys2
  2. 在 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
2
3
4
pkgver=16.0.1
_rc=""
_snapshot=20260308
arch=('x86_64')

然后关闭 Ada 语言支持,因为gcc为其引入了socket,windows下需要修改构建脚本链接ws2_32,但是咱是来体验C++26的,直接关掉最便捷。

1
2
3
4
5
6
7
8
9
10
11
12
13
if [[ ${CARCH} != i686 ]]; then
_enable_fortran=yes
_enable_ada=no # <---
_enable_objc=yes
_enable_rust=no
_enable_jit=yes
else
_enable_fortran=yes # Change it to no after dropping gimp
_enable_ada=no
_enable_objc=no
_enable_rust=no
_enable_jit=no
fi

然后关闭 gcc 插件支持,搜索--enable-plugin,注释掉这一行:

1
2
3
4
5
  local _arch=pentium4
else
# _extra_config+=("--enable-plugin")
local _arch=nocona
fi

这是因为 –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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch
0007-Build-EXTRA_GNATTOOLS-for-Ada.patch
0008-Prettify-linking-no-undefined.patch
0011-Enable-shared-gnat-implib.patch
0012-Handle-spaces-in-path-for-default-manifest.patch
0014-gcc-9-branch-clone_function_name_1-Retain-any-stdcall-suffix.patch
0020-libgomp-Don-t-hard-code-MS-printf-attributes.patch
0021-PR14940-Allow-a-PCH-to-be-mapped-to-a-different-addr.patch
0022-unset-native-system-header-dir.patch
0140-gcc-diagnostic-color.patch
0200-add-m-no-align-vector-insn-option-for-i386.patch
2001-fix-building-rust-on-mingw-w64.patch
3001-fix-codeview-crashes.patch
724f36504aa8573883e1919c6968665f8af28aef.patch
e28494e08092c4096a015563c0ba0494ce1edf81.patch
9e2c62a7d397b050427568c83ff5a4c21eb49365.patch

但是其中有的补丁已经不兼容,有的已经被合并入gcc中。
已知724f36504aa8573883e1919c6968665f8af28aef.patch和e28494e08092c4096a015563c0ba0494ce1edf81.patch不用打,其余的建议手动patch:

1
2
cd src/gcc-16-20260308
patch -Nbp1 -i "../X.patch"

如果报错,会生成一个.rej文件,包含被拒绝的补丁,如果不是已经打过了,就手动打上补丁。
这些补丁都很小,手动打也不耗时间。

打完补丁后,再手动执行prepare()中剩余的指令:

1
2
3
4
autoreconf -fiv
sed -i 's/${prefix}\/mingw\//${prefix}\//g' configure
MINGW_NATIVE_PREFIX=$(cygpath -am ${MINGW_PREFIX})
sed -i "s#\\/mingw\\/#${MINGW_NATIVE_PREFIX//\//\\/}\\/#g" gcc/config/mingw/mingw32.h

然后就可以开始编译了。

编译

再执行以下命令继续编译:

1
MINGW_ARCH=ucrt64 makepkg-mingw -sLf -e --skipchecksums --skippgpcheck

-e表示跳过prepare()

随后就是漫长的等待。。。

打包

编译完成后mingw-w64-gcc文件夹内就能得到几个.tar.zst文件

如果你不想把这些包安装进msys2环境,就按照如下步骤打包:

  1. 把mingw-w64-gcc中生成的所有.tar.zst文件都解压到同一个位置
  2. 然后下载以下包并解压到相同的文件:
    • 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/ 手动下载
  3. 然后删除.BUILDINFO这几个多余的文件
  4. 压缩被解压到一起的文件,或者直接用

*如果还是出现缺少dll,直接问ai是缺了哪个包
*以上只包括编译器、汇编器、以及依赖环境,其它工具,如gdb,make,请自己下。

END

恭喜,你已经完成了gcc16的编译,现在该玩反射了😋:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cmake_minimum_required(VERSION 3.10.0)
project(gnucxx26-reflection VERSION 0.1.0 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 26)

file(GLOB_RECURSE SRC src/*.cpp)

add_executable(gnucxx26-reflection ${SRC})

target_compile_options(gnucxx26-reflection PRIVATE
-freflection
)

target_link_libraries(gnucxx26-reflection PRIVATE
stdc++exp # windows下的gcc需要这个才能用std::print
)
1
2
3
4
5
6
7
#include <print>

int main() {
typename[:^^int:] a = 0;
std::println("hello, a={}", a);
return 0;
}
分享这一刻
让朋友们也来瞅瞅!