場景總結:
-
平臺: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; dotarget=$(readlink "$link")# 判斷軟鏈接是否有效(軟鏈接指向的文件不存在)if [ -L "$link" ] && [ ! -e "$(readlink -f "$link" 2>/dev/null)" ]; then# 如果是絕對路徑,則移除開頭的斜杠if [[ "$target" == /* ]]; thenrel_target="${target:1}" # 移除開頭的斜杠new_target="$BASE_DIR/$rel_target"elsenew_target="$BASE_DIR/$target"fiif [ -f $new_target ]; thenecho "修復無效鏈接: $new_target $link"ln -sf "$new_target" "$link"fifidone
}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" ]; thenecho "[?? 警告] 檢測到 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:$PATHexport 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.bashecho "[? 環境設置完成]"
最后需要注意的是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