You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在macOS上用Clang交叉编译C项目为PE32+可执行文件遇报错

解决交叉编译PE32+时找不到-lgcc/-lgcc_eh的问题

问题根因

你指定了x86_64-unknown-windows-gnu目标,Clang默认会尝试链接GCC的运行时库,但你的环境里缺少对应Windows目标的GCC库——要么是手动下载的mingw工具链路径配置错误,要么是LLD没找到mingw自带的gcc库文件。

具体解决方案

1. 安装完整的mingw-w64工具链(推荐)

放弃手动下载mingw,直接用Homebrew安装,它会自动配置好路径:

brew install mingw-w64

安装完成后,mingw的库路径默认是/usr/local/opt/mingw-w64/x86_64-w64-mingw32/lib,把编译命令里手动指定的mingw路径替换成这个即可。

2. 手动指定gcc库搜索路径

如果不想重新安装,直接在编译命令里添加gcc库的具体路径(替换成你mingw中gcc的实际版本路径,比如13.2.0):

/usr/local/opt/llvm/bin/clang \
    --target=x86_64-unknown-windows-gnu \
    -Wl,-e,_KernMain \
    -o kernel.exe  # PE可执行文件后缀用.exe,不要用.o
    src/Kernel/Kernel.c \
    src/Kernel/Memory/KernMem.c \
    src/Kernel/Graphics/KernGraphics.c \
    -I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/ \
    -I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/X64 \
    -I/Users/kernel/Documents/edk2-master/edk2/KernelOSPkg/src/Common \
    -I/usr/local/opt/mingw-w64/x86_64-w64-mingw32/include \
    -L/usr/local/opt/mingw-w64/x86_64-w64-mingw32/lib \
    -L/Users/kernel/Documents/edk2-master/edk2/MdePkg/Library/ \
    -L/usr/local/lib \
    -L/usr/local/opt/mingw-w64/lib/gcc/x86_64-w64-mingw32/13.2.0 \
    -fuse-ld="/usr/local/opt/llvm/bin/ld.lld"

3. 跳过gcc库(代码无依赖时)

如果你的内核代码没用到GCC的异常处理和特定运行时,可以直接让Clang跳过这些库,手动指定标准库:

/usr/local/opt/llvm/bin/clang \
    --target=x86_64-unknown-windows-gnu \
    -Wl,-e,_KernMain \
    -o kernel.exe \
    src/Kernel/Kernel.c \
    src/Kernel/Memory/KernMem.c \
    src/Kernel/Graphics/KernGraphics.c \
    -I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/ \
    -I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/X64 \
    -I/Users/kernel/Documents/edk2-master/edk2/KernelOSPkg/src/Common \
    -I/usr/local/opt/mingw-w64/x86_64-w64-mingw32/include \
    -L/usr/local/opt/mingw-w64/x86_64-w64-mingw32/lib \
    -L/Users/kernel/Documents/edk2-master/edk2/MdePkg/Library/ \
    -L/usr/local/lib \
    -fuse-ld="/usr/local/opt/llvm/bin/ld.lld" \
    -nostdlib -lc -lm

4. 改用UEFI专属目标(编译UEFI内核时)

从你引入edk2头文件来看,应该是开发UEFI内核,直接用x86_64-unknown-windows-uefi目标更合适,Clang对UEFI的支持更完善,无需依赖gcc库:

/usr/local/opt/llvm/bin/clang \
    --target=x86_64-unknown-windows-uefi \
    -Wl,-e,KernMain  # UEFI入口点不需要下划线前缀
    -o kernel.efi \
    src/Kernel/Kernel.c \
    src/Kernel/Memory/KernMem.c \
    src/Kernel/Graphics/KernGraphics.c \
    -I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/ \
    -I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/X64 \
    -I/Users/kernel/Documents/edk2-master/edk2/KernelOSPkg/src/Common \
    -fuse-ld="/usr/local/opt/llvm/bin/ld.lld"

额外提醒

  • 输出文件后缀:普通Windows PE用.exe,UEFI镜像用.efi,不要用.o(.o是中间目标文件,不是可执行文件)。
  • 入口点差异:windows-gnu目标需要给入口点加下划线前缀,windows-uefi目标不需要。

内容的提问来源于stack exchange,提问作者kernel_dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 07:15:51