ROS之交叉编译配置(树莓派)
注意,本文只是树莓派交叉编译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<char> const& std::use_facet<std::__cxx11::messages<char> >(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
更多推荐
所有评论(0)