ROS交叉编译——protobuf/yaml-cpp/opencv

Posted 怡宝2号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ROS交叉编译——protobuf/yaml-cpp/opencv相关的知识,希望对你有一定的参考价值。

ros, pcl, 交叉编译, protobuf, yaml, opencv

  1. VTK路径
    set(VTK_DIR “/home/darknet/CM/28_ros/nx_cross_compile/usr/lib/cmake/vtk-6.3” CACHE PATH “The directory containing VTKConfig.cmake”)
  2. stdlib.h
aarch64-linux-gnu/libc/usr/include/stdlib.h:57:1: 错误: ‘__BEGIN_NAMESPACE_STD’ does not name a type; did you mean ‘__BEGIN_DECLS’?
__BEGIN_NAMESPACE_STD
^~~~~~~~~~~~~~~~~~~~~
__BEGIN_DECLS
/home/darknet/CM/profile/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/usr/include/stdlib.h:63:5: 错误: ‘div_t’ does not name a type; did you mean ‘__id_t’?
} div_t;

解决方案

将host的gcc升级到了8.2,下载地址:​​https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads​

或者使用清华源:​​https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/​

  1. ​catkin build protobuf_catkin -DCMAKE_TOOLCHAIN_FILE=/opt/ros/melodic/share/ros/core/rosbuild/rostoolchain.cmake​​ 报错:
Errors     << protobuf_catkin:make /home/darknet/CM/28_ros/maplab_enhanced/logs/protobuf_catkin/build.make.005.log                                                               
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /home/darknet/CM/28_ros/maplab_enhanced/devel/lib/libprotobuf-lite.so when searching for -lprotobuf-lite
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /home/darknet/CM/28_ros/maplab_enhanced/devel/lib/libprotobuf-lite.a when searching for -lprotobuf-lite
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: cannot find -lprotobuf-lite
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /home/darknet/CM/28_ros/maplab_enhanced/devel/lib/libprotoc.so when searching for -lprotoc
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /home/darknet/CM/28_ros/maplab_enhanced/devel/lib/libprotoc.a when searching for -lprotoc
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: cannot find -lprotoc
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /home/darknet/CM/28_ros/maplab_enhanced/devel/lib/libprotobuf.so when searching for -lprotobuf
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /home/darknet/CM/28_ros/maplab_enhanced/devel/lib/libprotobuf.a when searching for -lprotobuf
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: cannot find -lprotobuf
collect2: 错误: ld 返回 1
make[2]: *** [/home/darknet/CM/28_ros/maplab_enhanced/devel/lib/libprotobuf_catkin.so] Error 1
make[1]: *** [CMakeFiles/protobuf_catkin.dir/all] Error 2
make: *** [all] Error 2
cd /home/darknet/CM/28_ros/maplab_enhanced/build/protobuf_catkin; catkin build --get-env protobuf_catkin | catkin env -si /usr/bin/make --jobserver-fds=6,7 -j; cd -
.................................................................................................................................................................................
Failed << protobuf_catkin:make [ Exited with code 2 ]
Failed <<< protobuf_catkin [ 0.1 seconds ]

Errors     << protobuf_catkin:make /home/darknet/CM/28_ros/maplab_enhanced/logs/protobuf_catkin/build.make.002.log                                                               
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: /home/darknet/CM/28_ros/maplab_enhanced/devel/lib/libprotobuf-lite.so: error adding symbols: file in wrong format

原因:需要先编译protobuf(这里应该编译成了host机器的,所以后面再链接的时候格式不对),再编译​​protobuf_catkin​​,需要交叉编译protobuf

我这里修改的cmakelists.txt为:

ExternalProject_Add(protobuf_src
URL file:///${PROJECT_SOURCE_DIR}/src/protobuf-2.6.1.tar.gz
UPDATE_COMMAND ""
PATCH_COMMAND patch -p0 < ${PROJECT_SOURCE_DIR}/unused_parameter_warnings.patch &&
patch -p0 < ${PROJECT_SOURCE_DIR}/unused_parameter_warnings_wire_format.patch
CONFIGURE_COMMAND cd ../protobuf_src && ./autogen.sh && ./configure --with-pic --prefix=${CATKIN_DEVEL_PREFIX} --host=arm-linux CC=/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc CXX=/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ --with-protoc=/usr/local/bin/protoc
BUILD_COMMAND cd ../protobuf_src && make -j8
INSTALL_COMMAND cd ../protobuf_src && make install -j8
)

交叉编译耗时:

catkin_make --only-pkg-with-deps protobuf_catkin 168.69s user 11.29s system 422% cpu 42.635 total

  1. 交叉编译​​yaml_cpp_catkin​​ 在编译yaml_cpp的时候指定c,c++编译器
    -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
[ 93%] Linking CXX executable parse
[ 93%] Built target parse
[ 95%] Linking CXX executable read
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: cannot find -lyaml-cpp
collect2: 错误: ld 返回 1
util/CMakeFiles/read.dir/build.make:83: recipe for target \'util/read\' failed
make[2]: *** [util/read] Error 1
CMakeFiles/Makefile2:438: recipe for target \'util/CMakeFiles/read.dir/all\' failed
make[1]: *** [util/CMakeFiles/read.dir/all] Error 2
Makefile:140: recipe for target \'all\' failed
make: *** [all] Error 2

原因: 在用​​ExternalProject_Add(yaml_cpp_src​​编译的时候,yaml_cpp_src在编译​​util​​子文件夹的时候,动态库的名字写错了。

解决:

# 原始
add_sources(read.cpp)
add_executable(read read.cpp)
target_link_libraries(read yaml-cpp) # 就是这行
set_target_properties(read PROPERTIES COMPILE_FLAGS "-std=c++11")

# 改为
add_sources(read.cpp)
add_executable(read read.cpp)
target_link_libraries(read yaml-cpp0.5)
set_target_properties(read PROPERTIES COMPILE_FLAGS "-std=c++11")

  1. 交叉编译​​opencv​​ 报错:
[ 45%] Linking CXX shared library ../../lib/libopencv_core.so
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: /usr/local/lib/libz.so: error adding symbols: file in wrong format
collect2: 错误: ld 返回 1
modules/core/CMakeFiles/opencv_core.dir/build.make:863: recipe for target \'lib/libopencv_core.so.3.2.0\' failed
make[2]: *** [lib/libopencv_core.so.3.2.0] Error 1
CMakeFiles/Makefile2:1775: recipe for target \'modules/core/CMakeFiles/opencv_core.dir/all\' failed
make[1]: *** [modules/core/CMakeFiles/opencv_core.dir/all] Error 2
Makefile:162: recipe for target \'all\' failed
make: *** [all] Error 2

原因: 应该是交叉编译opencv的时候依赖了x86的zlib动态库

报错:

​libippicv.a: error adding symbols: file in wrong format​

解决: 参考:​​https://zhuanlan.zhihu.com/p/381760569​​,参考以上博客,用其他的命令交叉编译opencv

  1. 交叉编译​​cv_bridge​​ 报错:
    错误: 不能将变量‘g_numpyAllocator’声明为具有抽象类型‘NumpyAllocator’

解决

cv_bridge中用了opencv,上面的错误是找了opencv4,所以重新找opencv3,再注释掉其中关于cuda部分的动态库

# if(NOT CUDA_FOUND)
# find_host_package(CUDA ${OpenCV_CUDA_VERSION} EXACT REQUIRED)
# else()
# if(NOT CUDA_VERSION_STRING VERSION_EQUAL OpenCV_CUDA_VERSION)
# message(FATAL_ERROR "OpenCV static library was compiled with CUDA ${OpenCV_CUDA_VERSION} support. Please, use the same version or rebuild OpenCV with CUDA ${CUDA_VERSION_STRING}")
# endif()
# endif()

# set(OpenCV_CUDA_LIBS_ABSPATH ${CUDA_LIBRARIES})

# if(${CUDA_VERSION} VERSION_LESS "5.5")
# list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_npp_LIBRARY})
# else()
# find_cuda_helper_libs(nppc)
# find_cuda_helper_libs(nppi)
# find_cuda_helper_libs(npps)
# list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nppc_LIBRARY} ${CUDA_nppi_LIBRARY} ${CUDA_npps_LIBRARY})
# endif()

  1. 报错/lib/ld-linux-aarch64.so.1: No such file or directory
    建立一个新的软连接就ok了。
    sudo ln -s /lib/aarch64-linux-gnu/ld-linux-aarch64.so.1 /lib/ld-linux-aarch64.so.1
  2. 报错/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/…/lib/gcc/aarch64-linux-gnu/8.3.0/…/…/…/…/aarch64-linux-gnu/bin/ld: cannot find -lreadline
    collect2: 错误: ld 返回 1
    /usr/lib/aarch64-linux-gnu/libreadline.so,在报错的地方用link_directories添加一下这个路径。
  3. static assertion failed: std::map must have the same value_type as its allocator required from ‘class common::TemporalBufferbackend::ResourceId’
    **原因:**应该不同版本的编译器导致的。
    解决: 参考:https://github.com/tum-vision/LDSO/issues/4

​https://github.com/tum-vision/LDSO/commit/38a5cab9b41948c5de42a672d9b33d9019a9c053​​在对应的报错位置的 std:pair, 前面的一个参数加上const。例如:

​std::allocator<std::pair<const int64_t, ValueType> >​

  1. ​-lpthread​​ 报错:
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libpthread.so when searching for -lpthread
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libpthread.a when searching for -lpthread
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libpthread.so when searching for -lpthread
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libpthread.a when searching for -lpthread
/home/darknet/CM/profile/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: /usr/lib/x86_64-linux-gnu/libfreetype.so: error adding symbols: file in wrong format
collect2: 错误: ld 返回 1

解决: 通过link_directories()添加动态库的路径。

2. 技巧

  1. 只编译一个项目
catkin build protobuf_catkin
catkin_make --only-pkg-with-deps protobuf_catkin

  1. 用​​ExternalProject_Add​​编译的项目,可以用cmake的方式单独编译能更精确的定位到问题的位置,cmake编译的流程
mkdir build && cd build
cmake ..
make -j4

以上是关于ROS交叉编译——protobuf/yaml-cpp/opencv的主要内容,如果未能解决你的问题,请参考以下文章

基于firefly rk3399 Android 7.1实现的ros服务小机器人

如何使用Qt插件在Qt中进行ROS开发

在ROS下建立编译链接PCL模块

ROS 工作空间、package 及 catkin 编译系统

[ros]编译ORBSLAM2时候,ros路径问题

ros 单独编译一个包