如何在Linux下让grpc与protobuf多版本共存


概述

前情提要,之前配置了比较低版本的protobuf,当时我就有预感肯定有伏笔,没想到伏笔来得这么快,因为grpc是需要配合protobuf使用的,也就是你单独弄的protobuf和grpc大概率版本是不统一的,这时候你去使用两者都会有问题,并且如果你按照前情提要配置的话大概率会遇到这个问题,其实这个问题只要不在全局配置问题都不大。

grpc

安装过程就不必多说了,配置完后为了方便给加到了.zshrc里(不推荐,但是经常使用的话可以加,去掉也简单)。这时候因为protobuf版本冲突会导致有一者无法正常编译(版本出问题)。这时候我选择的是留下grpc而把老的protobuf版本去掉,因为grpc其实里面包含了protobuf,还有很多其他三方库(re2,abseil等等),在使用上可以用grpc里带的protobuf代替。当然,如果像我一样遇到这种问题要给解决,可以尝试一下。

配置好后的grpc使用:

方便?下面就有伏笔了

find_package(Protobuf CONFIG REQUIRED)
find_package(gRPC CONFIG REQUIRED)

message(STATUS "Using protobuf-${Protobuf_VERSION}")
message(STATUS "Using gRPC-${gRPC_VERSION}")

set(PROTO_PATH ${PROJECT_SOURCE_DIR}/proto)

file(GLOB_RECURSE PROTO_FILES ${PROTO_PATH}/*.cc)
file(GLOB_RECURSE all_srcs CONFIGURE_DEPENDS *.cpp)

include_directories(${PROTO_PATH})

add_executable(main ${all_srcs} ${PROTO_FILES})

target_link_libraries(main PUBLIC gRPC::grpc++ protobuf)

猜猜直接找到了配套的老的会怎么样

版本冲突

当版本冲突时候的报错让人头皮发麻:

头皮发麻

如果像下面一样两个都留着的话,按照添加path的递归方式会选择使用grpc的,那么自然老的protobuf就不能够编译,那么如果我想使用前文提到过的直接手动指定行不行?

也就是将CMakeLists这样编写手动指定应该就行了吧?

set(Protobuf_PREFIX_PATH
  "/home/joytsing/makeInstall/protobuf3.21.12/include"
  "/home/joytsing/makeInstall/protobuf3.21.12/lib"
  "/home/joytsing/makeInstall/protobuf3.21.12/bin")

list(APPEND CMAKE_PREFIX_PATH "${Protobuf_PREFIX_PATH}")

find_package(Protobuf 3.21.12 REQUIRED)

很遗憾,答案是不行,因为在我们全局配置完后,你只要使用target_link_libraries(main PUBLIC protobuf),那么它默认会使用我们添加在全局PATH里的路径(而且我们已经在全局配置完lib和include,也就是说只需要link就能使用),只有当它在全局路径中找不到的时候它才会使用我们指定的路径,就是这么霸道。也就是说,在link的时候的protobuf都是默认指的grpc的(这取决于你),那么在把留在.zshrc老的protobuf去掉后我们还需要做什么,其实需要做的并不多,只需要稍稍修改就行。

再提一嘴为什么要把老的protobuf配置给去掉(很重要,不去掉的话一样会报错),因为现在版本有冲突,留着不仅没有用还会造成命名空间污染。所以现在相当于要配置一个安在其他地方的第三方库,仅此而已,稍稍配置就行了(除了库名因为被grpc污染不能使用)。

set(Protobuf_PREFIX_PATH
  "/home/joytsing/makeInstall/protobuf3.21.12/include"
  "/home/joytsing/makeInstall/protobuf3.21.12/lib"
  "/home/joytsing/makeInstall/protobuf3.21.12/bin")

list(APPEND CMAKE_PREFIX_PATH "${Protobuf_PREFIX_PATH}")

find_package(Protobuf 3.21.12 REQUIRED)

include_directories(${Protobuf_INCLUDE_DIRS})

include_directories(${PROJECT_SOURCE_DIR}/pb)

file(GLOB_RECURSE all_srcs ${PROJECT_SOURCE_DIR}/src/*.cpp ${PROJECT_SOURCE_DIR}/pb/*.cc)

add_executable(server ${all_srcs})

target_link_libraries(server PUBLIC ${Protobuf_LIBRARIES})

把需要链接的库名protobuf改成对应cmake变量就行,同时加上对应的include,和正常使用三方库没区别(其实就是)。

好了,可喜可贺,一些可能有用的文档:

多个Protobuf版本时让find_package正确选择

后记

另外在运行的时候发现一件事情,顺便还把k8s在最后kubeadm init时最后的通信连接不上的问题给解决了。

无响应

因为之前在配置minikube的时候,官方推荐添加NO_PROXY,于是我图方便写了个脚本又给加入了全局环境中

孩子们,又是我

所以现在的情况就是grpc依然走的代理,但是实际上我们把对应的代理地址给关闭了,自然也就连接不上,解决方法很简单,再写个脚本用unset,有同样的情况直接取消代理就行。

第六行

资料

CMake add_custom_command 使用

CMake: dependencies between targets and files and custom commands

stackoverflow: CMake add_custom_command not being run


文章作者: JoyTsing
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 JoyTsing !
评论
  目录