无法在ROS中使用本地安装的协议缓冲区

时间:2017-12-13 06:29:14

标签: c++ cmake protocol-buffers ros

我已在本地安装了Protocol Buffers。以下是ROS包的目录结构:

.
├── CMakeLists.txt
├── package.xml
├── include
│   ├── addressbook.pb.cc
│   ├── addressbook.pb.h
│   └── addressbook.proto
├── lib
│   └── protobuf-3.5.0
└── src
    └── main.cpp
使用./configure --prefix=$PWD目录中的lib/protobuf-3.5.0在本地安装了

Protocol Buffers

使用catkin_make编译ROS包时,似乎是指旧版的Protocol Buffers安装并显示版本不兼容错误。

[  0%] Building CXX object local_protobuf_ros_example/CMakeFiles/addressbook_protobuf.dir/include/addressbook.pb.cc.o
In file included from /home/bgplvm/ros_ws/src/local_protobuf_ros_example/include/addressbook.pb.cc:4:0:
/home/bgplvm/ros_ws/src/local_protobuf_ros_example/include/addressbook.pb.h:12:2: error: #error This file was generated by a newer version of protoc which is
 #error This file was generated by a newer version of protoc which is
  ^
/home/bgplvm/ros_ws/src/local_protobuf_ros_example/include/addressbook.pb.h:13:2: error: #error incompatible with your Protocol Buffer headers. Please update
 #error incompatible with your Protocol Buffer headers.  Please update
  ^
/home/bgplvm/ros_ws/src/local_protobuf_ros_example/include/addressbook.pb.h:14:2: error: #error your headers.
 #error your headers.
  ^
In file included from /home/bgplvm/ros_ws/src/local_protobuf_ros_example/include/addressbook.pb.cc:4:0:
/home/bgplvm/ros_ws/src/local_protobuf_ros_example/include/addressbook.pb.h:23:35: fatal error: google/protobuf/arena.h: No such file or directory
 #include <google/protobuf/arena.h>
                                   ^
compilation terminated.

虽然,我在message(STATUS "Using Protocol Buffers ${Protobuf_VERSION}")中放了CMakeLists.txt语句,发现它正在使用Protocol Buffers 3.5.0。请参阅下面的CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(local_protobuf_ros_example)

find_package(catkin REQUIRED COMPONENTS roscpp)

set(PROTOBUF_FOLDER ${PROJECT_SOURCE_DIR}/lib/protobuf-3.5.0)

set(CMAKE_PREFIX_PATH
    ${CMAKE_PREFIX_PATH}
    "${PROTOBUF_FOLDER}/cmake/build/release/lib/x86_64-linux-gnu/cmake/protobuf"
)

find_package(Protobuf CONFIG REQUIRED)
message(STATUS "Using Protocol Buffers ${Protobuf_VERSION}")

catkin_package()
include_directories(include ${catkin_INCLUDE_DIRS} ${PROTOBUF_INCLUDE_DIRS})

add_library(addressbook_protobuf include/addressbook.pb.cc)

add_executable(main src/main.cpp)
target_link_libraries(main ${catkin_LIBRARIES} addressbook_protobuf ${PROTOBUF_LIBRARIES})

这里缺少什么?由于我指的是本地安装,它应该工作而不会显示错误。不是吗?

2 个答案:

答案 0 :(得分:1)

您的CMAKE_PREFIX_PATH集不正确。它应该指向安装protobuf的前缀,而不是包的cmake配置文件的位置。

所以尝试改变:

set(CMAKE_PREFIX_PATH
    ${CMAKE_PREFIX_PATH}
    ${PROTOBUF_FOLDER}/cmake/build/release/lib/x86_64-linux-gnu/cmake/protobuf
)

对此:

set(CMAKE_PREFIX_PATH
    ${CMAKE_PREFIX_PATH}
    ${PROTOBUF_FOLDER}
)

即,假设${PROTOBUF_FOLDER}指向给定./configure --prefix=<INSTALL_PREFIX>

请参阅find_package here.的搜索路径文档(大约在页面的一半处)

我相信如果您使用的是Windows,那么<prefix>/就是该平台的搜索路径之一。但是在基于Unix的操作系统上你有这些作为搜索路径(根据上面链接的文档):

<prefix>/(lib/<arch>|lib|share)/cmake/<name>*/
<prefix>/(lib/<arch>|lib|share)/<name>*/
<prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/

此处还需要注意区分大小写。请注意,在上述路径中,他们搜索的最后一个路径元素是<name>*。从我在你的问题中可以看到,看起来protobuf安装自己的名称  &#39; protobuf&#39;,但您的find_package电话要求提供“Protobuf&#39;”。因此,请尝试将您的呼叫更改为:

find_package(protobuf CONFIG REQUIRED)

最后,据我所知,protobuf在通过./configure ...进行构建时不会安装CMake配置。为了安装CMake配置,我必须通过以下方式构建CMake:

cd protobuf-3.5/cmake
cmake -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> .
make
make install

答案 1 :(得分:0)

我找到了一种使用本地安装的协议缓冲区的解决方法。

我只需要将以下两个变量设置为本地安装的协议缓冲区:

  1. Protobuf_INCLUDE_DIRS
  2. Protobuf_LIBRARIES
  3. 请参阅下面的CMakeLists.txt

    cmake_minimum_required(VERSION 2.8.3)
    project(local_protobuf_ros_example)
    
    find_package(catkin REQUIRED COMPONENTS roscpp)
    
    set(PROTOBUF_FOLDER ${PROJECT_SOURCE_DIR}/lib/protobuf-3.5.0)
    
    set(Protobuf_INCLUDE_DIRS ${PROTOBUF_FOLDER}/include)
    set(Protobuf_LIBRARIES ${PROTOBUF_FOLDER}/lib/libprotobuf.so)
    
    catkin_package()
    include_directories(include ${catkin_INCLUDE_DIRS} ${Protobuf_INCLUDE_DIRS})
    
    add_library(addressbook_protobuf include/addressbook.pb.cc)
    
    add_executable(main src/main.cpp)
    target_link_libraries(main ${catkin_LIBRARIES} addressbook_protobuf ${Protobuf_LIBRARIES})
    

    它现在有效。但是,我不确定,如果这是一个好的做法。任何有更好解决方案的人都非常欢迎。