1. 编译环境准备
在 Windows 上为 i686-elf 编译 GCC 是一个痛苦的过程,期间可能会有大量的错误需要解决。所以选择 debian-11.0-i386 操作系统来编译 32 位的 gcc 工具,系统镜像下载地址如下所示:
# debian-11.0-i386 下载地址
http://gemmei.ftp.acc.umu.se/cdimage/archive/11.0.0/i386/iso-dvd/debian-11.0.0-i386-DVD-1.iso
1.1 更换镜像源
使用国内的镜像源如清华镜像源能显著的提高软件下载速度,可以在安装时选择镜像源,或者手动更换清华镜像源。
1.2 安装相关软件
编译 GCC 源码前,必须安装相关的工具链,如下载源码的 git 工具,编译源码的 make 工具等。
# 切换为 root 用户
su root
apt update
apt install -y git make autoconf automake autopoint bash bison flex texinfo gettext g++ gperf \
libffi-dev g++-multilib libtool libltdl-dev libssl-dev libxml-parser-perl pkg-config zip unzip \
wget libtool-bin build-essential libc6-dev python scons p7zip-full ruby lzip intltool \
librust-gdk-pixbuf-dev libgmp-dev
# 查看本地安装的 gcc 版本
# gcc version 10.2.1 20210110 (Debian 10.2.1-6)
gcc -v
1.3 交叉编译环境
使用 mxe 可以在 Linux 系统上交叉编译 windows 平台的应用程序,按照如下操作安装 mxe 交叉编译环境:
# 下载 mxe 源码
cd /opt
wget https://codeload.github.com/mxe/mxe/tar.gz/refs/tags/build-2021-04-22
# 解压 mxe 源码
tar -zxvf build-2021-04-22
# 编译 mxe
# 此步要下载 binutils、mingw、gmp、isl、mpfr、gcc等,相当慢
cd mxe-build-2021-04-22
make gcc
# 添加环境变量
vim /etc/profile
# 在 /etc/profile 文件末尾添加
export PATH="/opt/mxe-build-2021-04-22/usr/bin:$PATH"
# 更新环境变量
source /etc/profile
2. GCC源码编译
下载 binutils、gcc、gdb 源码
mkdir /home/build-i686
mkdir /home/build-i686/output
cd /home/build-i686
# 下载 需要编译的binutils, gcc, gdb 源码
wget https://ftp.gnu.org/gnu/binutils/binutils-2.35.tar.gz \
https://ftp.gnu.org/gnu/gcc/gcc-10.2.0/gcc-10.2.0.tar.gz \
https://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
# 解压 binutils
tar -zxvf binutils-2.35.tar.gz
# 解压 gcc
tar -zxvf gcc-10.2.0.tar.gz
# 解压 gdb
tar -zxvf gdb-10.2.tar.gz
2.1 编译 binutils
cd /home/build-i686
mkdir build-binutils
cd build-binutils
# 配置 binutils
../binutils-2.35/configure --target=i686-elf --with-sysroot --disable-nls \
--disable-werror --prefix=/home/build-i686/output --host=i686-w64-mingw32.static
# 编译 binutils
make
# 安装 binutils
make install
2.2 编译 gcc
# 安装 gcc 相关依赖
cd /home/build-i686/gcc-10.2.0
./contrib/download_prerequisites
mkdir /home/build-i686build-gcc
cd /home/build-i686/build-gcc
# 配置 gcc
../gcc-10.2.0/configure --target=i686-elf --disable-nls --enable-languages=c,c++ \
--without-headers --prefix=/home/build-i686/output --host=i686-w64-mingw32.static
# 编译安装
make all-gcc
make install-gcc
make all-target-libgcc
make install-target-libgcc
若编译过程中出现报错如下:
# 编译中遇到一些错误
i686-elf-gcc: command not found
i686-elf-cc: command not found
i686-elf-ar: command not found
i686-elf-ranlib: command not found
# 解决办法
ln -sf /usr/bin/gcc /usr/bin/i686-elf-gcc
ln -sf /usr/bin/cc /usr/bin/i686-elf-cc
ln -sf /usr/bin/ar /usr/bin/i686-elf-ar
ln -sf /usr/bin/ranlib /usr/bin/i686-elf-ranlib
2.3 编译 gdb
mkdir /home/build-i686/build-gdb
cd /home/build-i686/build-gdb
# 配置 gdb
../gdb-10.2/configure --target=i686-elf --disable-nls --disable-werror \
--prefix=/home/build-i686/output --host=i686-w64-mingw32.static
# 编译安装
make
make install
2.4 打包
cd /home/build-i686/output
zip -r /home/build-i686/gcc-i686-elf.zip *
# 最后将 /home/build-i686/gcc-i686-elf.zip 文件通过 sftp 下载到 windows 中即可
# 在 windows 中检查测试ld支持的链接模式
i686-elf-ld -m --help
# 显示支持模式如下
# i686-elf-ld: unrecognised emulation mode: --help
# Supported emulations: elf_i386 elf_iamcu
3. 文件瘦身
GCC源码编译完成后的目录结果如下
.
+-- bin
+-- i686-elf
╎ +-- bin
╎ +-- lib
╎ └─── +-- ldscripts
+-- include
╎ +-- gdb
+-- lib
╎ +-- gcc
╎ └─── +-- i686-elf
╎ └─── +-- 10.2.0
╎ ╎ +-- 64
╎ ╎ +-- include
╎ ╎ +-- include-fixed
╎ ╎ +-- install-tools
╎ ╎ └─── +-- include
╎ └─── +-- x32
+-- libexec
╎ +-- gcc
╎ └─── +-- i686-elf
╎ └─── +-- 10.2.0
╎ └─── +-- install-tools
+-- share
╎ +-- gdb
╎ ╎ +-- syscalls
╎ └─── +-- system-gdbinit
╎ +-- info
╎ +-- man
╎ ╎ +-- man1
╎ ╎ +-- man5
╎ └─── +-- man7
仅保留 gcc,g++, ld, gdb, as, objcopy, objdump 的目录结构如下
.
+-- bin
╎ +-- i686-elf-as.exe
╎ +-- i686-elf-g++.exe
╎ +-- i686-elf-gcc.exe
╎ +-- i686-elf-gdb.exe
╎ +-- i686-elf-ld.exe
╎ +-- i686-elf-objcopy.exe
╎ +-- i686-elf-objdump.exe
+-- i686-elf
╎ +-- bin
╎ ╎ +-- as.exe
╎ ╎ +-- ld.exe
╎ ╎ +-- objcopy.exe
╎ └─── +-- objdump.exe
+-- libexec
╎ +-- gcc
╎ └─── +-- i686-elf
╎ └─── +-- 6.3.0
╎ ╎ +-- cc1.exe
╎ └─── +-- cc1plus.exe
若设置PATH环境变量, 再把文件重命名(去掉i686-elf),目录结构还可以进一步简化为
.
+-- bin
╎ +-- g++.exe
╎ +-- gcc.exe
╎ +-- gdb.exe
╎ +-- as.exe
╎ +-- ld.exe
╎ +-- objcopy.exe
╎ +-- objdump.exe
╎ +-- cc1.exe
╎ +-- cc1plus.exe