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

幽沉谢世事,俯默窥唐虞。这篇文章主要讲述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】

    推荐阅读