C++交叉编译问题排查
1. 编译器版本的问题
1.1. 问题现象
在X86_64 Ubuntu24.04系统上用aarch64-linux-gnu-g++进行交叉编译C++代码, C++源码文件如下:
// Test.cpp
#include <iostream>
int main()
{
std::cout << "Hello world!" << std::endl;
return 0;
}
编译命令如下:
aarch64-linux-gnu-g++ ./Test.cpp -o Test
编译成功后,将目标文件Test通过scp工具推送到ARM64 Ubuntu22.04系统上,然后执行./Test, 但出现如下报错:
./Test
./Test: /lib/aarch64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.32' not found (required by ./Test)
1.2. 原因分析
错误来自 libstdc++ 版本不匹配:你在 x86_64 上用 aarch64 的交叉编译器(通常基于较新的 GCC)生成的二进制,链接到了 GLIBCXX_3.4.32。目标机(ARM64 Ubuntu 22.04)上的 /usr/lib/aarch64-linux-gnu/libstdc++.so.6 没有这个版本符号,运行时找不到所以报错。
1.3. 解决方法
1.3.1. 方法1:静态链接 C++ 标准库
静态链接libstdc++
最简单的解决方案是静态链接 libstdc++:
aarch64-linux-gnu-g++ ./Test.cpp -o Test -static-libstdc++ -static-libgcc
该方法在我的环境上验证失败,报错信息如下:
# ARM64 Ubuntu22.04 上运行
./Test
./Test: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by ./Test)
./Test: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.36' not found (required by ./Test)
1.3.2. 完全静态链接
如果还有问题,可以采用完全静态链接:
aarch64-linux-gnu-g++ ./Test.cpp -o Test -static
该方法在我的环境上验证成功:
# ARM64 Ubuntu22.04 上运行
./Test
Hello world!
优点:生成的可执行文件在目标系统上不依赖动态库版本 缺点:文件体积会变大
以Test为例,体积比较如下:
# 不使用静态链接
-rwxr-xr-x 1 root root 70K Jan 30 06:57 Test
# 静态链接libstdc++
-rwxr-xr-x 1 root root 2.6M Jan 30 07:21 Test
# 完全静态链接
-rwxr-xr-x 1 root root 3.2M Jan 30 07:13 Test
1.3.2. 方法2:使用目标系统兼容的工具链
安装与 Ubuntu 22.04 兼容的交叉编译工具链:
# 移除可能存在的现有工具链
sudo apt remove gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
# 安装 Ubuntu 22.04 兼容的工具链
sudo apt update
sudo apt install gcc-11-aarch64-linux-gnu g++-11-aarch64-linux-gnu
然后使用特定的版本编译:
aarch64-linux-gnu-g++-11 ./Test.cpp -o Test
验证成功:
# ARM64 Ubuntu22.04 上运行
./Test
Hello world!
1.3.3. 方法3 使用ubuntu:22.04的Docker镜像
使用 Docker 创建一个与目标系统兼容的编译环境:
# 创建 Dockerfile
cat > Dockerfile << 'EOF'
FROM ubuntu:22.04
RUN apt-get update && \
apt-get install -y \
gcc-aarch64-linux-gnu \
g++-aarch64-linux-gnu \
build-essential && \
apt-get clean
WORKDIR /workspace
EOF
# 构建镜像并编译
docker build -t cross-compile-env .
docker run -v $(pwd):/workspace cross-compile-env \
aarch64-linux-gnu-g++ /workspace/Test.cpp -o /workspace/Test