交叉编译ROS至aarch64时链接器误找主机库而非目标根文件系统
ROS交叉编译至aarch64时链接器错误:在主机根路径而非目标rootfs查找库
问题现象
交叉编译ROS应用到aarch64系统时,链接器错误地在主机根目录下查找依赖库,而非指定的目标根文件系统(rootfs)。具体错误:
make[2]: *** No rule to make target '/usr/lib/aarch64-linux-gnu/libboost_date_time.so.1.71.0', needed by '~/build/devel/lib/libcv_bridge.so'. Stop. make[1]: *** [CMakeFiles/Makefile2:951: src/CMakeFiles/cv_bridge.dir/all] Error 2
实际库文件位于 ${ROOT_PATH}/usr/lib/aarch64-linux-gnu/libboost_date_time.so.1.71.0,但g++尝试在 /usr/lib/aarch64-linux-gnu/ 路径下查找。该问题并非仅针对Boost,rosconsole的liblog4cxx.so也存在同类问题。
已做配置
基于NVIDIA提供的交叉编译方案配置了工具链,已检查CMAKE_FIND_ROOT_PATH、CMAKE_FIND_ROOT_PATH_MODE_PROGRAM等变量,当前CMake工具链配置如下:
#---------------------------------------------------------------------------------- # CMake includes and configuration #---------------------------------------------------------------------------------- SET(CMAKE_SYSTEM_NAME Linux) SET(CMAKE_SYSTEM_PROCESSOR aarch64) SET(CMAKE_HOST_SYSTEM_PROCESSOR x86_64) #---------------------------------------------------------------------------------- # Complier configuration #---------------------------------------------------------------------------------- SET(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu) # Below call is necessary to avoid non-RT problem. SET(CROSSCOMPILE TRUE) SET(COMPILER_ROOT "$ENV{CROSS_COMPILE}") SET(TROOT_PATH $ENV{ROOTFS_ORIN}) # Specify the cross compiler set(CMAKE_CXX_COMPILER ${COMPILER_ROOT}/bin/aarch64-buildroot-linux-gnu-g++) set(CMAKE_C_COMPILER ${COMPILER_ROOT}/bin/aarch64-buildroot-linux-gnu-gcc) #---------------------------------------------------------------------------------- # ROS configuration #---------------------------------------------------------------------------------- SET(NOETIC_PATH ${ROOT_PATH}/opt/ros/noetic) SET(CMAKE_CROSS_COMPILE_PREFIX ${NOETIC_PATH}) # Library paths set(LD_PATH ${ROOT_PATH}/usr/lib/aarch64-linux-gnu) set(LD_PATH_EXTRA ${ROOT_PATH}/lib/aarch64-linux-gnu) set(LD_PATH_EXTRA2 ${ROOT_PATH}/lib/) set(LD_ROS_PATH ${NOETIC_PATH}) set(CMAKE_PATH ${LD_PATH}/cmake/) #---------------------------------------------------------------------------------- # Directory configuration #---------------------------------------------------------------------------------- SET(CMAKE_PREFIX_PATH ${LD_PATH} ${LD_PATH_EXTRA} ${LD_ROS_PATH} ${CMAKE_PATH}) SET(CMAKE_MODULE_PATH ${LD_PATH} ${LD_PATH_EXTRA} ${LD_ROS_PATH} ${CMAKE_PATH}) # setup compiler for cross-compilation SET(CMAKE_SYSROOT "${ROOT_PATH}" CACHE INTERNAL "" FORCE) SET(CMAKE_SYSROOT_COMPILE "${ROOT_PATH}" CACHE INTERNAL "" FORCE) SET(CMAKE_SYSROOT_LINK "${ROOT_PATH}" CACHE INTERNAL "" FORCE) SET(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -L${LD_PATH} -L${LD_PATH_EXTRA} -L ${LD_ROS_PATH}") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${LD_PATH} -L${LD_PATH_EXTRA} -L ${LD_ROS_PATH}") set(CMAKE_EXPORT_COMPILE_COMMANDS=ON) set(CMAKE_FIND_ROOT_PATH ${ROOT_PATH} ${NOETIC_PATH}) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # Set compiler flags set(CMAKE_SHARED_LINKER_FLAGS "-L${LD_PATH} -L${LD_PATH_EXTRA} -L ${LD_ROS_PATH} -Wl,-rpath,${LD_PATH} -Wl,-rpath,${LD_PATH_EXTRA} -Wl,-rpath,${LD_PATH_EXTRA} -Wl,-rpath,${LD_ROS_PATH} ${CMAKE_SHARED_LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "-L${LD_PATH} -L${LD_PATH_EXTRA} -L ${LD_ROS_PATH} -Wl,-rpath,${LD_PATH} -Wl,-rpath,${LD_PATH_EXTRA} -Wl,-rpath,${LD_PATH_EXTRA} -Wl,-rpath,${LD_ROS_PATH} ${CMAKE_MODULE_LINKER_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "-L${LD_PATH} -L${LD_PATH_EXTRA} -L ${LD_ROS_PATH} -Wl,-rpath,${LD_PATH} -Wl,-rpath,${LD_PATH_EXTRA} -Wl,-rpath,${LD_PATH_EXTRA} -Wl,-rpath,${LD_ROS_PATH} ${CMAKE_EXE_LINKER_FLAGS}") #---------------------------------------------------------------------------------- # Library Versions #---------------------------------------------------------------------------------- SET(OPENCV_VERSION 4.5) SET(BOOST_VERSION 1.71.0) SET(PKG_CONFIG_EXECUTABLE /usr/bin/pkg-config) SET(PYTHON_EXECUTABLE /usr/bin/python3.8) # Flags for libraries include_directories(BEFORE SYSTEM ${ROOT_PATH}/usr/include) include_directories("${ROOT_PATH}/usr/include/aarch64-linux-gnu")
解决方案
1. 修复PKG_CONFIG配置
当前使用主机的pkg-config会读取主机库配置,需指定目标rootfs的工具并设置相关路径:
SET(PKG_CONFIG_EXECUTABLE ${ROOT_PATH}/usr/bin/pkg-config) SET(PKG_CONFIG_SYSROOT_DIR ${ROOT_PATH}) SET(PKG_CONFIG_LIBDIR ${ROOT_PATH}/usr/lib/aarch64-linux-gnu/pkgconfig:${ROOT_PATH}/usr/share/pkgconfig:${NOETIC_PATH}/lib/pkgconfig)
2. 修正变量引用错误
工具链中TROOT_PATH定义为$ENV{ROOTFS_ORIN},但后续使用${ROOT_PATH},变量名不匹配,统一修正:
# 将TROOT_PATH改为ROOT_PATH SET(ROOT_PATH $ENV{ROOTFS_ORIN})
3. 修复链接器路径空格问题
CMAKE_C_FLAGS和链接器flags中-L ${LD_ROS_PATH}的空格会导致路径解析错误,改为:
SET(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -L${LD_PATH} -L${LD_PATH_EXTRA} -L${LD_ROS_PATH}") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${LD_PATH} -L${LD_PATH_EXTRA} -L${LD_ROS_PATH}")
链接器flags中的-L 空格也同步去掉。
4. 强制指定Boost根目录
若问题仍存在,手动指定Boost路径强制从目标rootfs查找:
SET(BOOST_ROOT ${ROOT_PATH}/usr) SET(Boost_NO_SYSTEM_PATHS ON) find_package(Boost ${BOOST_VERSION} REQUIRED COMPONENTS date_time)
内容的提问来源于stack exchange,提问作者matialmar
相关产品推荐
相关产品推荐

