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

Unable to use locally installed Protocol Buffers inside ROS

本文关键字:安装 协议 缓冲区 ROS      更新时间:2023-10-16

我在本地安装了协议缓冲区。以下是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目录。

使用catkin_make编译ROS软件包时,它似乎是指旧安装协议缓冲区并显示版本不兼容错误。

[  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中,并发现它使用协议缓冲器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})

这里缺少什么?由于我指的是本地安装,因此它应该在不显示错误的情况下工作。不是吗?

您的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>

的-prefix参数的相同位置

此处查看find_package的搜索路径文档。(大约在页面下方)

我相信,如果您在Windows上,您本来可以用来的,因为<prefix>/是该平台的搜索路径之一。但是在基于Unix的OS'E中,您将其作为搜索路径(根据上述链接上的文档):

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

您还必须在此处谨慎对待病例敏感性。请注意,在上述路径中,他们搜索的最后一个路径元素是<name>*。从我在您的问题中看到的内容,它看起来像Protobuf以其名称安装 " Protobuf",但是您的find_package呼叫要求" Protobuf"。因此,请尝试将您的呼叫更改为:

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. Protobuf_INCLUDE_DIRS
  2. Protobuf_LIBRARIES

请参阅下面的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})

现在起作用。但是,我不确定是否是一个好习惯。任何拥有更好解决方案的人都是最欢迎的。