ROS之交叉编译配置


参考资料:

https://zhuanlan.zhihu.com/p/183819313

https://www.guyuehome.com/33759

1、原理

所谓的交叉编译,其实我们可以从编译原理上理解这个步骤,C++的编译大致可以分为预编译、编译和链接三个步骤,所以我们只要保证预编译和编译使用的编译工具是目标平台的配套工具,最后链接的库文件是目标平台的库文件,即可保证交叉编译的正确性。

下面以配置 x86 ubuntu 18.06 ROS melodic 交叉编译环境为例

2、环境

编译平台:x86_64 ubuntu 18.04

目标平台:arm ubuntu 18.04

ROS版本:ROS melodic for amd64

CPU架构:编译环境和运行环境都是64位

3、编译配置

首先在 目标平台编译平台 上全部装好 ubuntu 18.04 和 ROS melodic 的环境并且保证无误

3.1、在x86上安装arm的编译工具链

sudo apt install gcc-aarch64-linux-gnu
sudo apt install g++-aarch64-linux-gnu

此工具在后面用于编译

安装完成后,可以使用以下两条指令查看工具版本

aarch64-linux-gnu-gcc --version
aarch64-linux-gnu-g++ --version

3.2、复制ROS库

将 arm 平台中的 ROS 库拷贝到 x86 中,替换 x86 的 ROS 库文件(x86的最好先备份,用于后期),位置在 /opt/ros 目录下

执行后,该目录如下:

/opt/ros/melodic/  		#这个是arm cpoy过来的/opt/ros/melodic整个目录
/opt/ros/melodic_bak/  	#这个是x86原来的目录

之所以保留原先的目录,是因为 x86 的环境还需要使用的

下面这段和交叉编译无关

这时候,如果再次执行 roscore 会报错,原因是,现在的 roscore 执行的是 /opt/ros/melodic 目录下的环境,手动指定成 /opt/ros/melodic_bak/ 即可

source /opt/ros/melodic_bak/setup.bash

如果希望继续使用 x86 环境下的指令,需要指定 LD_LIBRARY_PATH 参数

export LD_LIBRARY_PATH=/opt/ros/melodic_bak/lib/

3.3、复制库

将下面三个目录复制到x86中,这两个目录下主要是 linux 平台的一些通用库

/lib
/usr/lib
/usr/include
/usr/local

路径任意,比如,本次放在 /home/robot/cross_compile 下,全路径为:

/home/robot/cross_compile/lib
/home/robot/cross_compile/usr/lib
/home/robot/cross_compile/usr/include
/home/robot/cross_compile/usr/local

该路径在后面编写工具链配置文件的时候会再用到

3.4、修改ROS编译链配置

编译文件 /opt/ros/melodic/share/catkin/cmake/tools/rt.cmake

if(NOT (APPLE OR WIN32 OR MINGW OR ANDROID))

修改为

if(NOT (APPLE OR WIN32 OR MINGW OR ANDROID OR UNIX))

3.5、编写ROS工具链配置

#File rostoolchain.cmake
INCLUDE(CMakeForceCompiler)
set(CMAKE_SYSTEM_NAME Linux)
message(STATUS "home path $ENV{HOME}")
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
set(CMAKE_CXX_FLAGS -fpermissive)
set(CMAKE_C_FLAGS -fpermissive)
# specify the cross compiler
#CMAKE_FORCE_C_COMPILER(aarch64-linux-gnu-gcc GNU)
#CMAKE_FORCE_CXX_COMPILER(aarch64-linux-gnu-g++ GNU)

set(CMAKE_FIND_ROOT_PATH  /opt/ros/melodic $ENV{HOME}/cross_compile)

set(CMAKE_LIBRARY_PATH  
# /opt/ros/melodic/lib/aarch64-linux-gnu
#$ENV{HOME}/cross_compile/opt/ros/melodic/lib 
$ENV{HOME}/cross_compile/lib
$ENV{HOME}/cross_compile/usr/lib
$ENV{HOME}/cross_compile/usr/local/lib
$ENV{HOME}/cross_compile/lib/aarch64-linux-gnu
$ENV{HOME}/cross_compile/usr/lib/aarch64-linux-gnu)

set(CMAKE_INCLUDE_PATH
$ENV{HOME}/cross_compile/usr/include
$ENV{HOME}/cross_compile/usr/include/freetype2
$ENV{HOME}/cross_compile/usr/include/aarch64-linux-gnu
$ENV{HOME}/cross_compile/usr/local/include)

set(LD_LIBRARY_PATH
# /opt/ros/melodic/lib/aarch64-linux-gnu
#$ENV{HOME}/cross_compile/opt/ros/melodic/lib 
$ENV{HOME}/cross_compile/lib
$ENV{HOME}/cross_compile/usr/lib
$ENV{HOME}/cross_compile/usr/local/lib
$ENV{HOME}/cross_compile/lib/aarch64-linux-gnu
$ENV{HOME}/cross_compile/usr/lib/aarch64-linux-gnu)
message(STATUS "rostoolchain LD_LIBRARY_PATH ${LD_LIBRARY_PATH}")

set(PYTHON_EXECUTABLE /usr/bin/python2.7)
#set(BOOST_ROOT $ENV{HOME}/cross_compile/usr)
#set(PCL_ROOT $ENV{HOME}/cross_compile/usr)
set(PCL_DIR $ENV{HOME}/cross_compile/usr/lib/aarch64-linux-gnu/cmake/pcl)


set(CMAKE_CROSSCOMPILING true)
message("${CMAKE_CROSSCOMPILING}")

# Have to set this one to BOTH, to allow CMake to find rospack
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)#FOR COMPILE TOOL WORKS
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

4、编译

使用 CMAKE_TOOLCHAIN_FILE 参数指定编译链配置文件,如:

catkin_make -DCMAKE_TOOLCHAIN_FILE=/home/robot/catkin_ws/rostoolchain.cmake

5、错误处理

5.1、roscpp 路径错误

修改 /opt/ros/melodic/share/roscpp/cmake/roscppConfig.cmake

set(libraries "roscpp;pthread;/home/robot/cross_compile/usr/lib/aarch64-linux-gnu/libboost_chrono.so;/home/robot/cross_compile/usr/lib/aarch64-linux-gnu/libboost_filesystem.so;/home/robot/cross_compile/usr/lib/aarch64-linux-gnu/libboost_system.so;/home/robot/cross_compile/usr/lib/aarch64-linux-gnu/libboost_signals.so;/home/robot/cross_compile/usr/lib/aarch64-linux-gnu/liblog4cxx.so")

5.2、链接过程中库文件错误

具体表现为,默认会从 /usr/lib/aarch64-linux-gnu 目录和 /lib/aarch64-linux-gnu 目录下寻找.so文件,实际上,我们需要从 /home/robot/cross_compile/usr/lib/aarch64-linux-gnu/home/robot/cross_compile/lib/aarch64-linux-gnu 下查找,解决方法是建立软链接即可

sudo ln -s /home/robot/cross_compile/lib/aarch64-linux-gnu /lib/aarch64-linux-gnu
sudo ln -s /home/robot/cross_compile/usr/lib/aarch64-linux-gnu /usr/lib/aarch64-linux-gnu

5.3、其他安装库错误

除了上述库外,一些后期安装库的链接错误(这些库可能是apt-get安装或者源码安装),具体表现在平台不匹配或者库找不到,这时候需要在对应平台的库copy到交叉编译环境下的指定目录(如 /home/robot/cross_compile )下,再统一在编译链文件中统一指定库路径即可

示例:

set(Qt5Gui_DIR /cross_compile/usr/lib/aarch64-linux-gnu/cmake/Qt5Gui)