如何兼容多版本protoc

兼容多版本protoc,一度让我崩溃。

文章由来:在进行文章“gazebo11+px4联合仿真测试”时,由于gazebo11需要protobuf3.6.1,而之前系统又已安装其它版本。
特别是,在进行“多传感器融合定位”学习时,前后也需要不同版本protoc,为了让多个系统顺利运行,不至于反复安装、卸载,一度让我崩溃,这里简单记录下该过程。

一、兼容多版本protoc方法

## 1. git protobuf源码
git clone https://github.com/google/protobuf.git
cd protobuf
## 2. 修改protobuf版本为v3.6.1,安装时会自动安装3.6.1
git checkout tags/v3.6.1
git checkout -b v3.6.1
./autogen.sh
## 3. 修改安装路径
./configure --prefix=/home/yours/local_install/google/protocbuff/ ##yours是你对你计算机取的名字
## 4. 编译protobuf源码
make -j8
##### 6.安装protobuf3.6.1
make install

上述安装以protobuf版本为v3.6.1为例,很自然就可以想到在自定义安装路径中可以安装你需要的任何版本protoc。也就是说,这样在你的系统中就存在,安装默认路径版本和自定义安装路径版本的protoc。接下来的关键是如何使用自定义安装的protoc。
以进行“gazebo11+px4联合仿真测试”为例,在.bashrc文件末尾添加如下内容:

####编译PX4时,将如下内容注释掉,编译sensor-fusion-for-localization-and-mapping时,将如下内容打开
####### add protobuf lib path ########/home/.../local_install/lib
export PATH=/home/.../protoc/local_install/protoc_3_15x/bin/:$PATH
#(动态库搜索路径) 程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/.../protoc/local_install/protoc_3_15x/lib/
#(静态库搜索路径) 程序编译期间查找动态链接库时指定查找共享库的路径
export LIBRARY_PATH=$LIBRARY_PATH:/home/.../protoc/local_install/protoc_3_15x/lib/
#执行程序搜索路径
export PATH=$PATH:/home/.../protoc/local_install/protoc_3_15x/bin/
#c程序头文件搜索路径
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/home/.../protoc/local_install/protoc_3_15x/include/
#c++程序头文件搜索路径
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/home/.../protoc/local_install/protoc_3_15x/include/
#pkg-config 路径
export PKG_CONFIG_PATH=/home/.../protoc/local_install/protoc_3_15x/lib/pkgconfig/

另外在sensor-fusion-for-localization-and-mapping,camke中protobuf.cmake调用protoc。
下面是protobuf.cmake挣扎过程:

二、多传感器融合定位兼容多版本protoc

多传感器融合定位中调用protoc,参看protobuf.cmake

原:

find_package (Protobuf REQUIRED)
include_directories(${
    
    Protobuf_INCLUDE_DIRS})
list(APPEND ALL_TARGET_LIBRARIES ${
    
    Protobuf_LIBRARIES})

修改后:

INCLUDE_DIRECTORIES(/.../protoc/local_install/protoc_3_15x/include/)
LINK_DIRECTORIES(/.../protoc/local_install/protoc_3_15x/lib/)
find_package (Protobuf REQUIRED)
list(APPEND ALL_TARGET_LIBRARIES ${
    
    Protobuf_LIBRARIES} libprotobuf.a libprotobuf-lite.a libprotoc.a)

测试验证list(APPEND ALL_TARGET_LIBRARIES ${Protobuf_LIBRARIES}也可以编译成功
尝试了N种方式,终于成功了。

感想:首先你要确定需要的版本,在这个基础上就是搞清楚cmake怎么引用自定义安装路径的protobuf。

最重要的还是在前find_package (Protobuf REQUIRED) 增加

INCLUDE_DIRECTORIES(/.../protoc/local_install/protoc_3_15x/include/)
LINK_DIRECTORIES(/.../protoc/local_install/protoc_3_15x/lib/)

近来编译lidar_localization 第四章,用如上方法,发现编译出现问题。
过程如下:

通过查阅相关资料,lidar_localization 第四章采用的是protoc3.14.0,于是按照如上的方法,进行编译,发现出错。经过多种尝试终究不能解决。
于是通过对比代码中与protoc相关部分代码,想通过修改代码中调用protoc相关部分改成protoc3.15.0相关(因为lidar_localization 后续章节protoc3.15.0能够编译通过)。但是通过对比发现除了 .proto 文件生成部分不同外,其它和protoc相关代码完全相同,于是直接用protoc3.15.0生成文件用于lidar_localization 第四章,惊喜发现编译可以通过,大喜!!!
遗憾的是,运行launch文件时节点会死掉,简直崩溃。
查阅无数资料,尝试各种无果。

皇天不负有心人,终于通过查看orbslam3的cmakelist文件获得灵感,哈哈哈。
orbslam3的cmakelist target_link_libraries 如下:

target_link_libraries(${
    
    PROJECT_NAME}
${
    
    OpenCV_LIBS}
${
    
    EIGEN3_LIBS}
${
    
    Pangolin_LIBRARIES}
${
    
    PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so
${
    
    PROJECT_SOURCE_DIR}/Thirdparty/g2o/lib/libg2o.so
-lboost_serialization
-lcrypto
)

发现链接库只要库的 .so文件即可,如g2o ${PROJECT_SOURCE_DIR}/Thirdparty/g2o/lib/libg2o.so,于是突发奇想,

INCLUDE_DIRECTORIES(/.../protoc/local_install/protoc_3_15x/include/)
LINK_DIRECTORIES(/.../protoc/local_install/protoc_3_15x/lib/)
find_package (Protobuf REQUIRED)
list(APPEND ALL_TARGET_LIBRARIES ${
    
    Protobuf_LIBRARIES} libprotobuf.a libprotobuf-lite.a libprotoc.a)

以上是修改后的protobuf.cmake,既然find_package (Protobuf REQUIRED)总是不能链接到自定义安装的库,那就把它去掉,直接在list(APPEND ALL_TARGET_LIBRARIES ${Protobuf_LIBRARIES} libprotobuf.a libprotobuf-lite.a libprotoc.a)这一步链接上 .so文件即可,尝试后,问题全部解决。
现在回过头想想,通过find_package (Protobuf REQUIRED)查找只是让你省去了自己链接的麻烦,如果你知道你所编译的代码需要的动态/静态库,直接用绝对目录链接上,也是可以的。
所以最终protobuf.cmake文件如下:

INCLUDE_DIRECTORIES(/.../protoc/local_install/protoc_3_15x/include/)
LINK_DIRECTORIES(/.../protoc/local_install/protoc_3_15x/lib/)
LINK_DIRECTORIES(/.../protoc/local_install/protoc_3_15x/bin/)
list(APPEND ALL_TARGET_LIBRARIES /.../protoc/local_install/protoc_3_15x/lib/libprotobuf.so)

参考:
https://blog.csdn.net/qq_41847318/article/details/105677603

猜你喜欢

转载自blog.csdn.net/u010196944/article/details/133018701