基于ARM ubuntu如何进行交叉编译

场景总结:

  • 平台:x86 主机

  • 工具链:aarch64-linux-gnu-gcc(用于编译 64-bit ARM 程序)

  • 目标:让 gcc 自动使用 ARM Ubuntu rootfs 中的头文件和库(位于 /opt/arm64-ubuntu

  • 不希望每次编译都加 --sysroot 参数,而是用 export 设置全局环境变量


✅ 推荐的 export 变量配置

假设 ARM Ubuntu 根目录为:

export SYSROOT=/opt/arm64-ubuntu

然后设置以下环境变量:

复制代码
# 设置交叉编译器(非必须,如果你明确指定 gcc 可省略)
export CC="aarch64-linux-gnu-gcc"
export CXX="aarch64-linux-gnu-g++"

# 头文件路径
export CFLAGS="--sysroot=$SYSROOT -I$SYSROOT/usr/include -I$SYSROOT/include"

# C++头文件路径
export CXXFLAGS="--sysroot=$SYSROOT -I$SYSROOT/usr/include -I$SYSROOT/include"

# 库文件路径
export LDFLAGS="--sysroot=$SYSROOT -L$SYSROOT/lib -L$SYSROOT/usr/lib -L$SYSROOT/usr/lib/aarch64-linux-gnu"

# 动态链接库搜索路径(用于运行/调试或给链接器 ld 使用)
export LIBRARY_PATH="$SYSROOT/lib:$SYSROOT/usr/lib:$SYSROOT/usr/lib/aarch64-linux-gnu"

# 包配置路径(如 pkg-config 使用)
export PKG_CONFIG_SYSROOT_DIR=$SYSROOT
export PKG_CONFIG_LIBDIR=$SYSROOT/usr/lib/aarch64-linux-gnu/pkgconfig

# 让 Make / Autotools 项目识别交叉平台
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

✅ 示例:不带参数的编译

设置好这些后,就可以直接运行:

$CC hello.c -o hello_arm

不需要每次写 --sysroot 和路径。


🔍 验证输出是否正确

应看到:file hello_arm64

ELF 64-bit LSB executable, ARM aarch64, ...


✅ 补充建议:写入 shell 脚本或 profile 文件

你可以把上面所有内容保存为 env-setup.sh 脚本:

然后执行:

source env-setup.sh

复制代码
#!/bin/bash
export SYSROOT=/opt/arm64-ubuntu
export CC="aarch64-linux-gnu-gcc"
export CXX="aarch64-linux-gnu-g++"
export CFLAGS="--sysroot=$SYSROOT -I$SYSROOT/usr/include -I$SYSROOT/include"
export CXXFLAGS="--sysroot=$SYSROOT -I$SYSROOT/usr/include -I$SYSROOT/include"
export LDFLAGS="--sysroot=$SYSROOT -L$SYSROOT/lib -L$SYSROOT/usr/lib -L$SYSROOT/usr/lib/aarch64-linux-gnu"
export LIBRARY_PATH="$SYSROOT/lib:$SYSROOT/usr/lib:$SYSROOT/usr/lib/aarch64-linux-gnu"
export PKG_CONFIG_SYSROOT_DIR=$SYSROOT
export PKG_CONFIG_LIBDIR=$SYSROOT/usr/lib/aarch64-linux-gnu/pkgconfig
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

✅ 总结

变量 用途
CFLAGS, CXXFLAGS 让 gcc 使用目标 rootfs 的头文件
LDFLAGS, LIBRARY_PATH 让链接器使用目标 rootfs 的库
PKG_CONFIG_* 使用 .pc 文件时自动指向目标 rootfs
SYSROOT 提供统一根路径,避免重复书写
CROSS_COMPILE 自动匹配工具链前缀(用于 makefile 项目)

通过chroot生成的ubuntu使用以下命令修改软链接路径,

复制代码
#!/bin/bash
BASE_DIR="/work/ubuntu/binary"       # 需要添加的基础目录

fix_invalid_links() {
    local TARGET_DIR="$1"
    find "$TARGET_DIR" -type l | while read -r link; do
        target=$(readlink "$link")
        # 判断软链接是否有效(软链接指向的文件不存在)
        if [ -L "$link" ] && [ ! -e "$(readlink -f "$link" 2>/dev/null)" ]; then
            # 如果是绝对路径,则移除开头的斜杠
            if [[ "$target" == /* ]]; then
                rel_target="${target:1}"  # 移除开头的斜杠
                new_target="$BASE_DIR/$rel_target"
            else
                new_target="$BASE_DIR/$target"
            fi
            if [ -f $new_target ]; then
                echo "修复无效链接: $new_target $link"
                ln -sf "$new_target" "$link"
            fi
        fi
    done
}

TARGET_DIR="/work/ubuntu/binary/usr/lib/aarch64-linux-gnu"   # 需要检查的目录
TARGET_DIR1="/work/ubuntu/binary/etc/alternatives"   # 需要检查的目录
fix_invalid_links "$TARGET_DIR"
fix_invalid_links "$TARGET_DIR1"
fix_invalid_links "$TARGET_DIR"
fix_invalid_links "$TARGET_DIR1"

生成一个脚本:env_compile

source ./env_compile即可后续进行编译

复制代码
#!/bin/bash

# ✅ 基础路径设置(便于统一管理)
ROOT=/work/ubuntu/binary
ROS_HUMBLE=$ROOT/opt/ros/humble
SYSROOT=$ROOT
LIBDIR=$ROOT/usr/lib
AARCH64_LIBDIR=$LIBDIR/aarch64-linux-gnu

# ✅ LD_LIBRARY_PATH 检查
if [ ! -z "$LD_LIBRARY_PATH" ]; then
  echo "[⚠️ 警告] 检测到 LD_LIBRARY_PATH 已设置,可能影响 SDK 正常运行。"
  echo "建议执行: unset LD_LIBRARY_PATH"
  echo "参考:"
  echo "  http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html#AEN80"
  echo "  http://xahlee.info/UnixResource_dir/_/ldpath.html"
  return 1
fi

# ✅ 路径设置
export PATH=$ROS_HUMBLE:$PATH
export PATH=$ROS_HUMBLE/lib:$PATH
export PATH=$AARCH64_LIBDIR:$PATH
export PATH=$ROOT/lib:$PATH
export PATH=$ROOT/usr:$PATH

export PYTHONPATH=$ROS_HUMBLE/lib/python3.10/site-packages
export PKG_CONFIG_PATH=$ROS_HUMBLE/lib:$SYSROOT/usr/share/pkgconfig
export AMENT_PREFIX_PATH=$ROS_HUMBLE

# ✅ 编译相关变量
export BUILDSYSROOT=$SYSROOT
export CMAKE_INCLUDE_PATH=$SYSROOT/usr/include:$CMAKE_INCLUDE_PATH
export LIBRARY_PATH=$LIBDIR:$AARCH64_LIBDIR:$LIBRARY_PATH
export LD_LIBRARY_PATH=$LIBDIR:$AARCH64_LIBDIR

# ✅ CMake 依赖路径
export CMAKE_PREFIX_PATH=$LIBRARY_PATH
export spdlog_DIR=$AARCH64_LIBDIR/cmake/spdlog
export fmt_DIR=$AARCH64_LIBDIR/cmake/fmt

# ✅ 交叉编译工具链配置
export LD="aarch64-linux-gnu-ld --sysroot=$SYSROOT"
export CC="aarch64-linux-gnu-gcc --sysroot=$SYSROOT"
export CXX="aarch64-linux-gnu-g++ --sysroot=$SYSROOT"
export CPP="aarch64-linux-gnu-gcc -E --sysroot=$SYSROOT"
export STRIP="aarch64-linux-gnu-strip"

# ✅ 加载 ROS 环境
source $ROS_HUMBLE/setup.bash

echo "[✅ 环境设置完成]"

最后需要注意的是ARm ubuntu的版本要与X86 ubuntu版本要一致,才能进行编译。否则版本问题导致太多问题。

需要注意,使用的是x86上面的gcc工具链,只是使用了arm ubuntu上面的lib 库

X86平台

复制代码
aarch64-linux-gnu-
aarch64-linux-gnu-addr2line  aarch64-linux-gnu-cpp        aarch64-linux-gnu-gprof      aarch64-linux-gnu-nm         aarch64-linux-gnu-readelf
aarch64-linux-gnu-ar         aarch64-linux-gnu-cpp-9      aarch64-linux-gnu-ld         aarch64-linux-gnu-objcopy    aarch64-linux-gnu-size
aarch64-linux-gnu-as         aarch64-linux-gnu-dwp        aarch64-linux-gnu-ld.bfd     aarch64-linux-gnu-objdump    aarch64-linux-gnu-strings
aarch64-linux-gnu-c++filt    aarch64-linux-gnu-elfedit    aarch64-linux-gnu-ld.gold    aarch64-linux-gnu-ranlib     aarch64-linux-gnu-strip
相关推荐
阿里小阿希31 分钟前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神36 分钟前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员1 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java1 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
问简1 小时前
ubuntu24 主题经验
ubuntu
一个天蝎座 白勺 程序猿1 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
杨云龙UP1 小时前
从0到1快速学会Linux操作系统(基础),这一篇就够了!
linux·运维·服务器·学习·ubuntu·centos·ssh
HXQ_晴天1 小时前
Ubuntu 设置中文输入法
linux·运维·ubuntu
不知名的老吴1 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存
YOU OU1 小时前
三大范式和E-R图
数据库