概述
前情提要,之前配置了比较低版本的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: dependencies between targets and files and custom commands