使用arm交叉编译工具并解决GLIBC版本不匹配的问题

介绍如何使用arm交叉编译工具来编译Go程序,并解决在arm平台上运行时出现GLIBC版本不匹配的问题。

  1. 下载 ARM 交叉编译工具,可以从官方网站下载。比如,可以从如下链接下载 GNU 工具链:https://developer.arm.com/downloads/-/gnu-a

    示例:https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-mingw-w64-i686-aarch64-none-elf.tar.xz

  2. 设置 Go ARM 交叉编译环境变量。具体来说,需要设置以下变量:

1
2
3
4
5
$env:GOOS="linux"
$env:GOARCH="arm64"
$env:CGO_ENABLED=1 
$env:CC="D:\arm\gcc-arm-10.3-2021.07-mingw-w64-i686-aarch64-none-linux-gnu\bin\aarch64-none-linux-gnu-gcc.exe"
$env:CXX="D:\arm\gcc-arm-10.3-2021.07-mingw-w64-i686-aarch64-none-linux-gnu\bin\aarch64-none-linux-gnu-g++.exe"
  1. 在 ARM 上运行程序时可能会出现如下错误:
1
2
3
./bupload: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by ./bupload)
./bupload: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./bupload)
./bupload: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by ./bupload)

这是因为程序需要使用较新版本的 GLIBC 库,而 ARM 上安装的库版本较旧。可以通过以下步骤来解决这个问题:

  1. 查看当前系统中 libc 库所支持的版本:
1
strings /lib/aarch64-linux-gnu/libc.so.6 | grep GLIBC_
  1. 备份整个 /lib 目录和 /usr/include 目录,以便稍后还原。
  2. 从 GNU libc 官方网站下载对应版本的 libc 库。例如,可以从如下链接下载 2.35 版本的 libc 库:http://ftp.gnu.org/gnu/glibc/glibc-2.35.tar.xz
  3. 解压 libc 库:
1
2
xz -d glibc-2.35.tar.xz
tar xvf glibc-2.35.tar glibc-2.35
  1. 创建并进入 build 目录:
1
2
mkdir build
cd build
  1. 配置 libc 库的安装选项:
1
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
  1. 编译并安装 libc 库:
1
2
make -j4
make install

接下来是关于 make 报错的部分:

1
asm/errno.h: No such file or directory

这个报错是因为 errno.h 文件中包含了 asm/errno.h 文件,但是找不到这个文件。为了解决这个问题,我们需要创建一个软链接:

1
ln -s /usr/include/asm-generic /usr/include/asm

然后又出现了另一个报错:

1
/usr/include/aarch64-linux-gnu/asm/sigcontext.h: No such file or directory

这个问题也可以通过重新安装linux-libc-dev后创建软链接来解决:

1
2
3
# find / -name sigcontext.h
sudo apt-get install --reinstall linux-libc-dev
ln -s /usr/include/aarch64-linux-gnu/asm/sigcontext.h /usr/include/asm/sigcontext.h

接下来,还有一个报错:

1
asm/sve_context.h: No such file or directory

这个报错是因为最新的 Linux 内核在启用 ARM Scalable Vector Extension (SVE) 后,需要包含 asm/sve_context.h 文件。我们需要创建一个软链接来解决这个问题:

1
2
# find / -name sve_context.h
ln -s /usr/include/aarch64-linux-gnu/asm/sve_context.h /usr/include/asm/sve_context.h

最后,还需要创建一个软链接:

1
2
# find / -name byteorder.h
ln -s /usr/include/aarch64-linux-gnu/asm/byteorder.h /usr/include/asm/byteorder.h

完成以上步骤后,我们再次执行 make 命令,就应该可以顺利地编译和安装 glibc 了。

Built with Hugo
Theme Stack designed by Jimmy