栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

ROS之交叉编译配置(树莓派)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ROS之交叉编译配置(树莓派)

1、环境

编译平台:x86_64 ubuntu 16.04
目标平台:arm ubuntu 16.04(树莓派3b)
ROS版本:ROS kinetic for amd64
CPU架构:编译环境64位和运行环境32位

2在PC上安装arm(树莓派)的交叉编译工具链
git clone git://github.com/raspberrypi/tools.git

拷贝gcc-linaro-arm-linux-gnueabihf-raspbian 文件夹到/opt目录下

3复制树莓派上的ROS库和一些树莓派上通用库到PC机

打包复制ROS库,主要有kinetic文件夹。

sudo tar -czvf kinetic.tar.gz kinetic/

打包复制树莓派上通用库,主要包括

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

压缩文件太大就直接拷贝到u盘中。

4.编写交叉编译的cmake文件

rostoolchain.cmake文件如下:

set(CMAKE_SYSTEM_NAME Linux)
# Have to set this one to BOTH, to allow CMake to find rospack
#set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
#set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
#set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
#set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
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(LINUX_COMPILER_FLAGS)
set(LINUX_COMPILER_FLAGS_CXX)
set(LINUX_COMPILER_FLAGS_DEBUG)
set(LINUX_COMPILER_FLAGS_RELEASE)
set(LINUX_linkER_FLAGS)
set(LINUX_linkER_FLAGS_EXE)

# STL.
set(RASPBERRYPI_32_TOOLCHAIN /opt/raspberrypi/tools/arm-bcm2708)
set(LINUX_TOOLCHAIN_PATH ${RASPBERRYPI_32_TOOLCHAIN}/gcc-linaro-arm-linux-gnueabihf-raspbian)

# Sysroot.
set(CMAKE_SYSROOT ${RASPBERRYPI_32_TOOLCHAIN}/arm-linux-gnueabihf/arm-linux-gnueabihf/sysroot)

# Toolchain.
set(LINUX_C_COMPILER   "${LINUX_TOOLCHAIN_PATH}/bin/arm-linux-gnueabihf-gcc")
set(LINUX_CXX_COMPILER "${LINUX_TOOLCHAIN_PATH}/bin/arm-linux-gnueabihf-g++")
set(LINUX_ASM_COMPILER "${LINUX_TOOLCHAIN_PATH}/bin/arm-linux-gnueabihf-as")
set(LINUX_Fortran_COMPILER  "${LINUX_TOOLCHAIN_PATH}/bin/arm-linux-gnueabihf-gfortran")



INCLUDE(CMakeForceCompiler)
message(STATUS "home path $ENV{HOME}")
# 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/kinetic $ENV{HOME}/cross_compile)
set(CMAKE_LIBRARY_PATH  
$ENV{HOME}/cross_compile/lib
$ENV{HOME}/cross_compile/usr/lib
$ENV{HOME}/cross_compile/usr/local/lib
$ENV{HOME}/cross_compile/usr/lib/arm-linux-gnueabihf
$ENV{HOME}/cross_compile/lib/arm-linux-gnueabihf

)

set(CMAKE_INCLUDE_PATH
$ENV{HOME}/cross_compile/usr/include
$ENV{HOME}/cross_compile/usr/include/freetype2
$ENV{HOME}/cross_compile/usr/local/include
$ENV{HOME}/cross_compile/usr/include/arm-linux-gnueabihf

)

set(LD_LIBRARY_PATH 
$ENV{HOME}/cross_compile/lib
$ENV{HOME}/cross_compile/usr/lib
$ENV{HOME}/cross_compile/usr/local/lib

$ENV{HOME}/cross_compile/usr/lib/arm-linux-gnueabihf
$ENV{HOME}/cross_compile/lib/arm-linux-gnueabihf


)
message(STATUS "rostoolchain LD_LIBRARY_PATH ${LD_LIBRARY_PATH}")

set(PYTHON_EXECUTABLE /usr/bin/python2.7)
set(CMAKE_CROSSCOMPILING true)
message("${CMAKE_CROSSCOMPILING}")


set(CMAKE_C_COMPILER_ID_RUN TRUE)
set(CMAKE_CXX_COMPILER_ID_RUN TRUE)
set(CMAKE_C_COMPILER_ID GNU)
set(CMAKE_CXX_COMPILER_ID GNU)
set(CMAKE_C_COMPILER_VERSION 5.4.0)
set(CMAKE_CXX_COMPILER_VERSION 5.4.0)
set(CMAKE_C_STANDARD_COMPUTED_DEFAULT 11)
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT 98)
set(CMAKE_CXX_STANDARD 11)
# Generic flags.


# Debug and release flags.
list(APPEND LINUX_COMPILER_FLAGS_DEBUG
	-g
	-O0)

list(APPEND LINUX_COMPILER_FLAGS_RELEASE
    -O2)

list(APPEND LINUX_COMPILER_FLAGS_RELEASE
    -DNDEBUG)
    
# Toolchain and ABI specific flags.
# Configuration specific flags.
# if(LINUX_PIE)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
list(APPEND LINUX_linkER_FLAGS_EXE
	-pie
	-fPIE)
# endif()

list(APPEND LINUX_linkER_FLAGS
-Wl,--no-undefined)

# Convert these lists into strings.
string(REPLACe ";" " " LINUX_COMPILER_FLAGS         "${LINUX_COMPILER_FLAGS}")
string(REPLACE ";" " " LINUX_COMPILER_FLAGS_CXX     "${LINUX_COMPILER_FLAGS_CXX}")
string(REPLACE ";" " " LINUX_COMPILER_FLAGS_DEBUG   "${LINUX_COMPILER_FLAGS_DEBUG}")
string(REPLACE ";" " " LINUX_COMPILER_FLAGS_RELEASE "${LINUX_COMPILER_FLAGS_RELEASE}")
string(REPLACE ";" " " LINUX_linkER_FLAGS           "${LINUX_linkER_FLAGS}")
string(REPLACE ";" " " LINUX_linkER_FLAGS_EXE       "${LINUX_linkER_FLAGS_EXE}")

set(CMAKE_C_COMPILER        "${LINUX_C_COMPILER}")
set(CMAKE_CXX_COMPILER      "${LINUX_CXX_COMPILER}")
set(CMAKE_Fortran_COMPILER      "${LINUX_Fortran_COMPILER}")

# Set or retrieve the cached flags.
# This is necessary in case the user sets/changes flags in subsequent
# configures. If we included the Android flags in here, they would get
# overwritten.
set(CMAKE_C_FLAGS ""
	CACHE STRING "Flags used by the compiler during all build types.")
set(CMAKE_CXX_FLAGS ""
	CACHE STRING "Flags used by the compiler during all build types.")
set(CMAKE_ASM_FLAGS ""
	CACHE STRING "Flags used by the compiler during all build types.")
set(CMAKE_C_FLAGS_DEBUG ""
	CACHE STRING "Flags used by the compiler during debug builds.")
set(CMAKE_CXX_FLAGS_DEBUG ""
	CACHE STRING "Flags used by the compiler during debug builds.")
set(CMAKE_ASM_FLAGS_DEBUG ""
	CACHE STRING "Flags used by the compiler during debug builds.")
set(CMAKE_C_FLAGS_RELEASE ""
	CACHE STRING "Flags used by the compiler during release builds.")
set(CMAKE_CXX_FLAGS_RELEASE ""
	CACHE STRING "Flags used by the compiler during release builds.")
set(CMAKE_ASM_FLAGS_RELEASE ""
	CACHE STRING "Flags used by the compiler during release builds.")
set(CMAKE_MODULE_linkER_FLAGS ""
	CACHE STRING "Flags used by the linker during the creation of modules.")
set(CMAKE_SHARED_linkER_FLAGS ""
	CACHE STRING "Flags used by the linker during the creation of dll's.")
set(CMAKE_EXE_linkER_FLAGS ""
	CACHE STRING "Flags used by the linker.")

set(CMAKE_C_FLAGS             "${LINUX_COMPILER_FLAGS} ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS           "${LINUX_COMPILER_FLAGS} ${LINUX_COMPILER_FLAGS_CXX} ${CMAKE_CXX_FLAGS}")
set(CMAKE_ASM_FLAGS           "${LINUX_COMPILER_FLAGS} ${CMAKE_ASM_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG       "${LINUX_COMPILER_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}")
set(CMAKE_CXX_FLAGS_DEBUG     "${LINUX_COMPILER_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_DEBUG}")
set(CMAKE_ASM_FLAGS_DEBUG     "${LINUX_COMPILER_FLAGS_DEBUG} ${CMAKE_ASM_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_RELEASE     "${LINUX_COMPILER_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_RELEASE   "${LINUX_COMPILER_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_ASM_FLAGS_RELEASE   "${LINUX_COMPILER_FLAGS_RELEASE} ${CMAKE_ASM_FLAGS_RELEASE}")
set(CMAKE_SHARED_linkER_FLAGS "${LINUX_linkER_FLAGS} ${CMAKE_SHARED_linkER_FLAGS}")
set(CMAKE_MODULE_linkER_FLAGS "${LINUX_linkER_FLAGS} ${CMAKE_MODULE_linkER_FLAGS}")
set(CMAKE_EXE_linkER_FLAGS    "${LINUX_linkER_FLAGS} ${LINUX_linkER_FLAGS_EXE} ${CMAKE_EXE_linkER_FLAGS}")

set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-builtin-macro-redefined -D'__FILE__="./$(subst $(realpath ${CMAKE_SOURCE_DIR})/,,$(abspath $<))"'")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-builtin-macro-redefined -D'__FILE__="./$(subst $(realpath ${CMAKE_SOURCE_DIR})/,,$(abspath $<))"'")

编译的时候执行

catkin_make -DCMAKE_TOOLCHAIN_FILE=/home/qian/cross_compile/rostoolchain.cmake
5 修改/opt/ros/kinetic/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))
6.修改/opt/ros/kinetic/share/catkin/cmake/catkinConfig.cmake

个人理解cmake交叉编译过程就是修改cmake搜索链接库文件位置的过程,正常编译会搜索x86库文件做在位置,
交叉编译需要将搜索位置切换到目标架构需要的库文件存放位置,比如/$ENV{HOME}/cross-compiling/ubuntu-rootfs
实现方法:
修改catkin_INCLUDE_DIRS catkin_LIBRARY_DIRS,将这两个变量中指向x86系统的位置,修改为指向交叉编译依赖文件存放位置

list(APPEND catkin_INCLUDE_DIRS ${CMAKE_INCLUDE_PATH})
list(APPEND catkin_LIBRARY_DIRS ${CMAKE_LIBRARY_PATH})

set(catkin_LIBRARIES_tmp ${catkin_LIBRARIES})

set(catkin_LIBRARIES "")

foreach(catkinlib ${catkin_LIBRARIES_tmp})

string(LENGTH ${catkinlib} lengths)

if (${lengths} GREATER 12)

string(SUBSTRING ${catkinlib} "/" 12 result)

string(COMPARE EQUAL ${result} "/usr/lib/lib" compareResult)

if (${compareResult})

string(REPLACE "/usr/lib/lib" "$ENV{HOME}/cross_compile/usr/lib/lib" result_tem ${catkinlib})

list(APPEND catkin_LIBRARIES ${result_tem})

else()

list(APPEND catkin_LIBRARIES ${catkinlib})

endif()

else()

list(APPEND catkin_LIBRARIES ${catkinlib})

endif()

endforeach()

5错误处理

(1)错误1 头文件错误

from /opt/ros/kinetic/include/ros/time.h:55,
                 from /opt/ros/kinetic/include/ros/ros.h:38,
                 from /home/qian/test/showpath/src/showpath/src/showpath.cpp:1:
/usr/include/math.h:31:30: fatal error: bits/math-vector.h: No such file or directory

解决:
使用命令查找一下

sudo find / -name "math-vector.h"

发现这个文件在目录

/home/qian/cross_compile/usr/include/arm-linux-gnueabihf/bits/math-vector.h

下,而上面的CMAKE_INCLUDE_PATH没有包含include/arm-linux-gnueabihf路径
所以报找不到头文件 bits/math-vector.h

要将/home/qian/cross_compile/usr/include/arm-linux-gnueabihf/加入到头文件中

在.cmake中修改所有的有arm-linux-gnueabihf文件夹的路径加入进去

(2)错误2 链接过程中库文件错误

*** No rule to make target '/usr/lib/arm-linux-gnueabihf/libboost_filesystem.so',

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

sudo ln -s /home/qian/cross_compile/lib/arm-linux-gnueabihf /lib/arm-linux-gnueabihf 
sudo ln -s /home/qian/cross_compile/usr/lib/arm-linux-gnueabihf /usr/lib/arm-linux-gnueabihf 

(3)错误3 链接的时候报错

warning: libuuid.so.1, needed by /home/qian/cross_compile/usr/lib/arm-linux-gnueabihf/libapr-1.so.0, not found (try using -rpath or -rpath-link)

/usr/lib/arm-linux-gnueabihf/libboost_regex.so: undefined reference to `std::__cxx11::messages const& std::use_facet >(std::locale const&)@GLIBCXX_3.4.21

还没有找到原因,树莓派交叉编译ros无法成功。

https://www.cnblogs.com/sherlock-lin/p/15916143.html
https://blog.csdn.net/RobotLife/article/details/105899602

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/751505.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号