《转》
https://www.cnblogs.com/objectDetect/p/5223029.html
ROS运行环境:ARM ubuntu14.04 + ROS indigo
在arm环境下编译ros应用程序,速度极慢,无法忍受,尝试在x86机器上搭建docker+ros交叉编译环境。
交叉编译环境的搭建主要参考:
http://answers.ros.org/question/191070/compile-roscore-for-arm-board/
1 ARM ubuntu环境上安装arm-indigo版本,后面需要将这个arm版本copy到交叉编译环境上
2 x86环境上安装docker
3 下载docker-ros镜像, 加载启动docker-ros镜像
4 安装 sudo apt-get install g++-arm-linux-gnueabihf
5 将docker环境中中x86版本的indigo替换成arm版本的indigo,
替换之前需要备份x86版本indigo的lib,因为这些库文件在运行ros时是需要的。
将x86版本indigo的lib保存到localpath目录下,设置export LD_LIBRARY_PATH=localpath,
实现运行ros命令时使用x86的lib库。
6 将arm环境下的库文件/头文件 copy到docker环境中,目录可以自己设定比如:/$ENV{HOME}/cross-compiling/ubuntu-rootfs
7 配置rostoolchain.cmake文件
#File rostoolchain.cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc) set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++) set(CMAKE_FIND_ROOT_PATH /opt/ros/indigo $ENV{HOME}/cross-compiling/ubuntu-rootfs) set(CMAKE_LIBRARY_PATH $ENV{HOME}/cross-compiling/ubuntu-rootfs/usr/lib/arm-linux-gnueabihf $ENV{HOME}/cross-compiling/ubuntu-rootfs/usr/lib $ENV{HOME}/cross-compiling/ubuntu-rootfs/lib $ENV{HOME}/cross-compiling/ubuntu-rootfs/usr/local/lib) set(CMAKE_INCLUDE_PATH $ENV{HOME}/cross-compiling/ubuntu-rootfs/usr/include $ENV{HOME}/cross-compiling/ubuntu-rootfs/usr/local/include) set(LD_LIBRARY_PATH $ENV{HOME}/cross-compiling/ubuntu-rootfs/usr/lib/arm-linux-gnueabihf $ENV{HOME}/cross-compiling/ubuntu-rootfs/usr/lib $ENV{HOME}/cross-compiling/ubuntu-rootfs/lib $ENV{HOME}/cross-compiling/ubuntu-rootfs/usr/local/lib) set(PYTHON_EXECUTABLE /usr/bin/python) set(PCL_ROOT $ENV{HOME}/cross-compiling/ubuntu-rootfs/usr) 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 ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
8 修改/opt/ros/indigo/share/catkin/cmake/tools/rt.cmake
该文件的第34行
if(NOT (APPLE OR WIN32 OR MINGW OR ANDROID))修改为if(NOT (APPLE OR WIN32 OR MINGW OR ANDROID OR UNIX))
9 个人理解cmake交叉编译过程就是修改cmake搜索链接库文件位置的过程,正常编译会搜索x86库文件做在位置,
交叉编译需要将搜索位置切换到目标架构需要的库文件存放位置,比如/$ENV{HOME}/cross-compiling/ubuntu-rootfs
实现方法:
修改catkin_INCLUDE_DIRS catkin_LIBRARY_DIRS,将这两个变量中指向x86系统的位置,修改为指向交叉编译依赖文件存放位置
/opt/ros/indigo/share/catkin/cmake/catkinConfig.cmake
这个文件末增加如下处理:
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-compiling/ubuntu-rootfs/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()
10 编译命令
catkin_make -DCMAKE_TOOLCHAIN_FILE=/$filepath/rostoolchain.cmake
终于搞定了,分享我遇到的主要两个问题(其它还有就是我本地连接问题临了)
1.set(CMAKE_FIND_ROOT_PATH “/opt/ros/indigo /opt/ros_arm/rootfs”)==我多用了引号,正确应该为
set(CMAKE_FIND_ROOT_PATH /opt/ros/indigo /opt/ros_arm/rootfs)
2.
/opt/ros/indigo/share/catkin/cmake/catkinConfig.cmake
替换路径的脚本,由于我的路径时/usr/lib 需要对应修改(注意里面对应的字符串长度是8了,我没注意到,跌坑里了)
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 7)
string(SUBSTRING ${catkinlib} “/” 8 result)
string(COMPARE EQUAL ${result} “/usr/lib” compareResult)
if (${compareResult})
string(REPLACE “/usr/lib” “/opt/ros_arm/rootfs/usr/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()