参考资料:

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)

ROS之交叉编译配置的更多相关文章

  1. CMake交叉编译配置

    很多时候,我们在开发的时候是面对嵌入式平台,因此由于资源的限制需要用到相关的交叉编译.即在你host宿主机上要生成target目标机的程序.里面牵扯到相关头文件的切换和编译器的选择以及环境变量的改变等 ...

  2. ubuntu16.04 ROS环境下配置和运行SVO

    ubuntu16.04 ROS环境下配置和运行SVO https://blog.csdn.net/nnUyi/article/details/78005552

  3. ROS 环境变量配置

    unbantu16.04 linux 版本,  ros系统 kinetic版本 1. ros系统可以通过rospack find  package_name  /   rosrun package_n ...

  4. ROS vpn (pptp) 配置及端口绑定配置

    网络搜集 一. 按VPN的协议分类 VPN的隧道协议主要有三种,PPTP,L2TP和IPSec,其中PPTP和L2TP协议工作在OSI模型的第二层,又称为二层隧道协议:IPSec是第三层隧道协议,是最 ...

  5. SVO在ROS下的配置与运行

    最近在做实验的时候,需要配置SVO,下面讲讲其中的过程以及遇到的问题: 首先说明配置环境:Ubuntu 14.04 + ROS indigo,ROS的安装我参考了ROS的官网上给出的教程:http:/ ...

  6. QT插件+ROS 1 安装配置

    测试环境: 系统版本:Ubuntu14.04 ROS版本:indigo QT版本:5.8.0 QtCreator安装 1 安装前准备,安装相应的GNU开发工具集和OpenGL开发库, 请注意安装软件都 ...

  7. ROS安装,配置

    ROS最好安装在Ubuntu系统,因为ROS目前在其他的系统中都是试验性的 ! <Learning ROS for Robotics Programming-- second Edition&g ...

  8. CodeTyphon跨平台交叉编译的配置

    CodeTyphon和Lazarus的关系相当于就是ubuntu和linux的关系 不过CodeTyphon提供了很多一键配置即可使用的交叉编译配置,而Lazarus就比较麻烦了,我也没用Lazaru ...

  9. Ubuntu虚拟机+ROS+Android开发环境配置笔记

    Ubuntu虚拟机+ROS+Android开发环境配置笔记 虚拟机设置: 1.本地环境:Windows 7:VMWare:联网 2.虚拟环境 :Ubuntu 14.04. 比較稳定,且支持非常多ROS ...

  10. ROS入门笔记(二):ROS安装与环境配置及卸载(重点)

    ROS入门笔记(二):ROS安装与环境配置及卸载(重点) [TOC] 1 ROS安装步骤 1.1 ROS版本 ROS目前只支持在Linux系统上安装部署, 它的首选开发平台是Ubuntu. 发布时间 ...

随机推荐

  1. Codeforces Round #664 题解(A ~ C)

    1395A - Boboniu Likes to Color Balls 如果在r,b,g,w中小于或等于一个奇数,则可以将其定为回文. 否则,请进行一次操作(如果可以),然后检查上述情况. 进行多次 ...

  2. Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题)

    补题链接:Here 1535A. Fair Playoff 四名选手参加了季后赛.比赛按以下方案进行:第一名选手与第二名选手比赛,第三名选手与第四名选手比赛,然后两人中的获胜者进入决赛. 众所周知,在 ...

  3. 工作中使用Redis的10种场景

    前言 Redis作为一种优秀的基于key/value的缓存,有非常不错的性能和稳定性,无论是在工作中,还是面试中,都经常会出现. 今天这篇文章就跟大家一起聊聊,我在实际工作中使用Redis的10种场景 ...

  4. 服务降级,限流等--sentinel(SpringCloud Alibaba)

    一. 介绍Sentinel,中文翻译为哨兵,是为微服务提供流量控制.熔断降级的功能,它和Hystrix提供的功能一样,可以有效的解决微服务调用产生的"雪崩"效应,为微服务系统提供了 ...

  5. 【收藏】Stable Diffusion 制作光影文字效果

    大家对于最近 Stable Diffusion 不断出新的视觉"整活"印象都很深刻,很多人对最近比较流行的制作光影文字很感兴趣,制作光影文字可以作为进阶 Stable Diffus ...

  6. js md5 和java md5后的值不一样

    开发发现js 对字符串md5 和 java对字符串md5 计算的结果居然不一样,后来找了一个匹配的这里记录一下 注:加密的对象中不能有空格,有空格md5后的结果就不一致,都是眼泪.. js md5算法 ...

  7. 嵌入式Linux必读经典书籍(含下载方式)

    最近,在知乎看到一个问题,"嵌入式Linux有哪些好书推荐".我读研期间也喜欢收藏一些书籍,每次看到京东有活动,总是忍不住想买一些书籍回来. 随着时间越来越久,我买的书越来越多,但 ...

  8. SpringBoot 动态数据源

    SpringBoot 实现动态数据源切换 Spring Boot + Mybatis Plus + Druid + MySQL 实现动态数据源切换及动态 SQL 语句执行. 项目默认加载 applic ...

  9. C#设计模式03——简单工厂的写法

    什么是C#简单工厂? C#简单工厂是一种创建对象的设计模式,它定义一个工厂类来创建指定类型的对象,而不是在客户端代码中直接创建对象.简单工厂模式通常使用静态方法来生成对象,并且这些静态方法通常被称为工 ...

  10. 每天学五分钟 Liunx 0100 | 服务篇:进程状态

    多任务和 CPU 时间片 前面说了 Liunx 是多用户多任务的,所谓的多任务就是多个进程"同时"执行.比如,同时开多个软件(进程),对于用户来说好像每个软件(进程)都在工作,但是 ...