制作 Windows 上的 aarch64-linux-gnu 交叉编译器
2025-07-20 12:13:12

有了之前制作交叉编译器的经验,现在只用照猫画虎即可,还是那套流程。


这次的硬件是 Mac Mini4,在虚拟机里安装了 Ubuntu 20.04 ARM64
系统镜像用的是:https://old-releases.ubuntu.com/releases/20.04.0/ubuntu-20.04-live-server-arm64.iso

准备工作

确定软件版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal

# uname -r
5.4.0-216-generic

# ldd --version
ldd (Ubuntu GLIBC 2.31-0ubuntu9.18) 2.31
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

Binutils 版本选择的是 2.44:https://mirrors.ustc.edu.cn/gnu/binutils/
GCC 版本选择的是 15.1.0:https://mirrors.ustc.edu.cn/gnu/gcc/gcc-15.1.0/
Linux内核版本是 5.4:https://mirrors.ustc.edu.cn/kernel.org/linux/kernel/v5.x/linux-5.4.tar.xz
glibc版本是 2.31:https://mirrors.ustc.edu.cn/gnu/glibc/glibc-2.31.tar.xz


安装必要的软件包

1
sudo apt -y install bison p7zip-full

环境变量

设置必要的环境变量

1
2
3
4
5
6
7
8
9
10
11
# 将上次制作的交叉工具链加入到 PATH 环境变量中
export PATH=/opt/x86_64-w64-mingw32-15.1/bin:$PATH

# 使用自编译的 GCC 库,如果是用的系统的 GCC 或安装路径和我的不同,就跳过这步或调整为自己的路径
export LD_LIBRARY_PATH=/usr/local/lib64

export BUILD=aarch64-linux-gnu
export HOST=x86_64-w64-mingw32
export TARGET=aarch64-linux-gnu
export PREFIX=/opt/cross
export SYSROOT=$PREFIX/$TARGET

确保 GCC 版本一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/bin/../libexec/gcc/aarch64-linux-gnu/15/lto-wrapper
Target: aarch64-linux-gnu
Configured with: ../configure --prefix=/opt/gcc-15.1.0 --with-gcc-major-version-only --program-suffix=-15 --enable-languages=c,c++ --enable-shared --enable-fix-cortex-a53-843419 --disable-werror --disable-multilib --disable-checking --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 15.1.0 (GCC)

# aarch64-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=aarch64-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/usr/local/bin/../libexec/gcc/aarch64-linux-gnu/15/lto-wrapper
Target: aarch64-linux-gnu
Configured with: ../configure --prefix=/opt/gcc-15.1.0 --with-gcc-major-version-only --program-suffix=-15 --enable-languages=c,c++ --enable-shared --enable-fix-cortex-a53-843419 --disable-werror --disable-multilib --disable-checking --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 15.1.0 (GCC)

# x86_64-w64-mingw32-gcc -v
Using built-in specs.
COLLECT_GCC=x86_64-w64-mingw32-gcc
COLLECT_LTO_WRAPPER=/opt/x86_64-w64-mingw32-15.1/bin/../libexec/gcc/x86_64-w64-mingw32/15.1.0/lto-wrapper
Target: x86_64-w64-mingw32
Configured with: ../configure --prefix=/opt/cross --with-sysroot=/opt/cross/x86_64-w64-mingw32 --enable-languages=c,c++ --enable-threads=win32 --enable-shared --disable-multilib --disable-werror --disable-checking --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=x86_64-w64-mingw32
Thread model: win32
Supported LTO compression algorithms: zlib
gcc version 15.1.0 (GCC)

编译 Binutils

1
2
3
4
5
6
7
cd /opt
tar xf binutils-2.44.tar.xz
cd binutils-2.44/
mkdir build && cd build
../configure --prefix=$PREFIX --disable-nls --disable-multilib --build=$BUILD --host=$HOST --target=$TARGET
make -j$(nproc)
make install-strip

安装 Linux 内核头文件

1
2
3
4
cd /opt
tar xf linux-5.4.tar.xz
cd linux-5.4/
make ARCH=arm64 headers_install INSTALL_HDR_PATH=$SYSROOT

头文件会安装到$SYSROOT/include下。

编译 glibc

1
2
3
4
5
6
7
cd /opt
tar xf glibc-2.31.tar.xz
cd glibc-2.31/
mkdir build && cd build
../configure --prefix=$SYSROOT --with-headers=$SYSROOT/include --disable-multilib --disable-werror --build=$BUILD --host=$TARGET
make -j$(nproc)
make install

编译 GCC

关键点来了,前面我们将 glibc 安装到$SYSROOT下了,但是 GCC 在编译时会从$SYSROOT/usr下搜索头文件,所以我们要临时创建usr目录的软链接

1
ln -s $SYSROOT $SYSROOT/usr

这样当 GCC 访问$SYSROOT/usr/include时,实际访问的就是$SYSROOT/include目录。

开始编译 GCC

1
2
3
4
5
6
cd /opt/gcc-15.1.0/
./contrib/download_prerequisites
mkdir build && cd build
../configure --prefix=$PREFIX --with-sysroot=$SYSROOT --enable-languages=c,c++ --enable-shared --enable-fix-cortex-a53-843419 --disable-multilib --disable-werror --disable-checking --build=$BUILD --host=$HOST --target=$TARGET
make -j$(nproc)
make install-strip


编译完成后,编辑aarch64-linux-gnu/lib/libc.so文件,去掉其中的绝对路径,仅保留文件名。

1
2
3
4
5
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-littleaarch64)
GROUP ( /opt/cross/aarch64-linux-gnu/lib/libc.so.6 /opt/cross/aarch64-linux-gnu/lib/libc_nonshared.a AS_NEEDED ( /opt/cross/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 ) )

打包

1
7z a -l cross.7z $PREFIX

好了,拷贝到 Windows 上开始使用吧!