x86交叉编译ros 工程给jetson nano运行
声明: 交叉编译的方式为 : jetson的工具链+导出nano的环境的方式
一、 nano部分
1.在nano上安装 ros-melodic ,以及所有要用的库,这里看个人的代码需要用什么。
2. 导出nano里的库,目前我还没有用到nvidia显卡部分,如果有缺漏后续会补
当前导出的部分为: /lib 及lib 下目录, /usr 及 /usr下的lib 、include 、aarch64-linux-gnu,以及/opt、/opt/ros 部分,导出到 /home/robot/jetson-nano-sysroot 这个目录自定义就行
sudo rsync -aAXz --numeric-ids --include="/lib/" --include="/lib/***" --include="/usr/" --include="/usr/include/" --include="/usr/include/***" --include="/usr/lib/" --include="/usr/lib/***" --include="/usr/lib/aarch64-linux-gnu/" --include="/usr/lib/aarch64-linux-gnu/***" --include="/opt/" --include="/opt/ros/" --include="/opt/ros/***" --exclude="*" / /home/robot/jetson-nano-sysroot
3. 拷贝这部分(/home/robot/jetson-nano-sysroot )出来到自己的x86上
二、x86环境部分
1.先看下对应nano的jetson linux版本,
cat /etc/nv_tegra_release
# R32 (release), REVISION: 7.1, GCID: 29818004, BOARD: t210ref, EABI: aarch64, DATE: Sat Feb 19 17:05:08 UTC 2022
然后去下载对应的工具链 地址为Jetson Linux Archive | NVIDIA Developer
我的版本是R32.7.1,因此去 Jetson Linux R32.7.1 Release Page | NVIDIA Developer ,点击下图进行下载
我是解压到 /home/robot/jetson-nano/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu
目录下结构为
2. 挂载 nano导出部分到opt下
sudo mount --bind /home/robot/jetson-nano-sysroot /opt/sysroot-fake
3. 由于本来x86下没有 aarch64-linux-gnu
因此从nano文件夹内做个软连接到 /usr/lib下
sudo ln -s /opt/sysroot-fake/usr/lib/aarch64-linux-gnu /usr/lib/aarch64-linux-gnu
到这一步基础的环境就设置完成了,后续要去增加toolchain.cmake了
三、代码改动部分
1.增加 toolchain-jetson-ros.cmake
# Toolchain file for cross-compiling to Jetson Nano
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)# 你的 Linaro 交叉编译器路径
set(TOOLCHAIN_PATH /home/robot/jetson-nano/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu)# 设置交叉编译器
set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/bin/aarch64-linux-gnu-g++)# sysroot 路径,挂载点
set(CMAKE_SYSROOT /opt/sysroot-fake) # 已 mount --bind 的那个
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})# 限制 cmake 仅从 sysroot 查找库/头文件
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)# 支持 pkg-config 找 ROS 包
set(ENV{PKG_CONFIG_DIR} "")
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
set(ENV{PKG_CONFIG_PATH} ${CMAKE_SYSROOT}/opt/ros/melodic/lib/pkgconfig:${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig)set(CMAKE_PREFIX_PATH "${CMAKE_SYSROOT}/opt/ros/melodic")
2. 改动cmakelist,下面贴我自己的cmakelist来做说明
cmake_minimum_required(VERSION 3.0.2) project(filter_side_camera)# 加入 --sysroot 和 include 路径 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --sysroot=${CMAKE_SYSROOT} -I${CMAKE_SYSROOT}/usr/include -I${CMAKE_SYSROOT}/usr/include/pcl-1.8")set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --sysroot=${CMAKE_SYSROOT} -I${CMAKE_SYSROOT}/usr/include")set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} \-Wl,-rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu \-Wl,-rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/tegra \-Wl,-rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/blas \-Wl,-rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/lapack \-Wl,-rpath-link=${CMAKE_SYSROOT}/lib/aarch64-linux-gnu \-Wl,-rpath-link=${CMAKE_SYSROOT}/opt/ros/melodic/lib \")set(SYSROOT /opt/sysroot-fake)# ROS 包find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgssensor_msgspcl_rospcl_conversionstf2tf2_rostf2_sensor_msgs)# 强制替换 catkin_INCLUDE_DIRS 中的路径set(catkin_INCLUDE_DIRS_MODIFIED "")foreach(dir IN LISTS catkin_INCLUDE_DIRS)string(REPLACE "/usr/include" "${SYSROOT}/usr/include" dir_mod "${dir}")list(APPEND catkin_INCLUDE_DIRS_MODIFIED "${dir_mod}")endforeach()# 强制替换 catkin_LIBRARIES 中的路径set(catkin_LIBRARIES_MODIFIED "")foreach(lib IN LISTS catkin_LIBRARIES)# lib 可能是库文件名或者带路径,尝试替换路径部分string(REPLACE "/opt/ros/melodic" "${SYSROOT}/opt/ros/melodic" lib_mod "${lib}")list(APPEND catkin_LIBRARIES_MODIFIED "${lib_mod}")endforeach()# 使用修改后的变量替代原来的message(STATUS "catkin_INCLUDE_DIRS replaced: ${catkin_INCLUDE_DIRS_MODIFIED}")message(STATUS "catkin_LIBRARIES replaced: ${catkin_LIBRARIES_MODIFIED}")# catkin 包信息catkin_package(INCLUDE_DIRS includeLIBRARIES filter_side_cameraCATKIN_DEPENDS roscpp rospy std_msgs sensor_msgs pcl_ros pcl_conversions tf2 tf2_ros tf2_sensor_msgs)# 头文件路径include_directories(include${catkin_INCLUDE_DIRS_MODIFIED})include_directories(SYSTEM${CMAKE_SYSROOT}/usr/include${CMAKE_SYSROOT}/usr/include/eigen3# ${CMAKE_SYSROOT}/opt/sysroot-fake/opt/ros/melodic${CMAKE_SYSROOT}/usr/include/pcl-1.8#${catkin_INCLUDE_DIRS})# 库add_library(${PROJECT_NAME}src/filter_side_camera.cpp)# 可执行程序add_executable(${PROJECT_NAME}_nodesrc/main.cppsrc/filter_side_camera.cpp)link_directories(/opt/sysroot-fake/usr/lib/aarch64-linux-gnu)find_library(UUID_LIB uuid PATHS /opt/sysroot-fake/usr/lib/aarch64-linux-gnu)# 链接库target_link_libraries(${PROJECT_NAME}_node# ${catkin_LIBRARIES}${catkin_LIBRARIES_MODIFIED}${UUID_LIB}${M_LIB})
接下来对以上cmakelist进行说明,声明只针对我的工程,你自己的对照着去做修改
1)
# 加入 --sysroot 和 include 路径 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --sysroot=${CMAKE_SYSROOT} -I${CMAKE_SYSROOT}/usr/include -I${CMAKE_SYSROOT}/usr/include/pcl-1.8")
这里主要是重新设置include路径,防止直接去找x86下的 /usr/include
2)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} \
-Wl,-rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu \
-Wl,-rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/tegra \
-Wl,-rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/blas \
-Wl,-rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/lapack \
-Wl,-rpath-link=${CMAKE_SYSROOT}/lib/aarch64-linux-gnu \
-Wl,-rpath-link=${CMAKE_SYSROOT}/opt/ros/melodic/lib \
")
这里是为了导出可执行用,因为x86下files类型和arm 下不一样,链接不过去,所以要按以上设置rpath,目前有一个问题我没法解决,就是像tegra 是${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu的下级目录,没有办法不写,如果有办法解决的话,请大佬指正,后续我也会想办法来解决这一块。
3)
# 强制替换 catkin_LIBRARIES 中的路径
set(catkin_LIBRARIES_MODIFIED "")
foreach(lib IN LISTS catkin_LIBRARIES)
# lib 可能是库文件名或者带路径,尝试替换路径部分
string(REPLACE "/opt/ros/melodic" "${SYSROOT}/opt/ros/melodic" lib_mod "${lib}")
list(APPEND catkin_LIBRARIES_MODIFIED "${lib_mod}")
endforeach()
以上是为了不去直接找 /opt/ros/melodic下的include和lib,在前面加上${SYSROOT}地址,来使用我们之前mount过去的/opt/sysroot-fake/opt/ros/melodic地址