CMake找不到Protobuf`protobuf_generate_cpp`

时间:2018-09-27 09:10:01

标签: cmake protocol-buffers protobuf-c

使用

find_package(Protobuf REQUIRED
    PATHS ${PROTOBUF_SEARCH_PATH}
)

if (NOT ${Protobuf_FOUND})
    message( FATAL_ERROR "Could not find Protobuf!" )
endif()    

protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS Foo.proto)

我收到一条错误消息Unknown CMake command "protobuf_generate_cpp"。如果我检查Protobuff的安装文件夹,则存在一个包含功能定义的CMake文件<istall path>/cmake/protobuf-module.cmake

CMake    version: 3.10.2
Protobuf version: 3.6.1

这是什么问题?

3 个答案:

答案 0 :(得分:3)

现有的answers帮助了我,但错过了很多关于发生了什么的解释。

find_package可以在MODULE模式或CONFIG模式下工作。 在MODULE模式下,它搜索Find\<package\>.cmake(通常由cmake拥有)。 在CONFIG模式下,它搜索\<package\>Config.cmake(由程序包提供)。

cmake和协议缓冲区都可以为protobuf_generate_cpp()提供实现:

>grep -ri 'function(PROTOBUF_GENERATE_CPP' /opt/cmake-3.18.1/ 
/opt/cmake-3.18.1/share/cmake-3.18/Modules/FindProtobuf.cmake:function(PROTOBUF_GENERATE_CPP SRCS HDRS)
>grep -ri 'function(PROTOBUF_GENERATE_CPP' /opt/protobuf-3.5.0/
/opt/protobuf-3.5.0/lib64/cmake/protobuf/protobuf-module.cmake:function(PROTOBUF_GENERATE_CPP SRCS HDRS)

使用PATHS提示可使cmake进入CONFIG模式,以便在可以找到Config.cmake模块的情况下使用protobuf提供的实现。

在这种情况下,protobuf_generate_cpp()来自config.cmake,它需要:

set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "")

因为@HaxtraZ提到配置模块包含:

if(protobuf_MODULE_COMPATIBLE)
   include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake")
endif()

如果使用FindProtobuf模块,则不需要此操作,因此此处没有记录。

尽管并非如此,但它的过错可以警告可能发生的冲突。 如果在这里提出这个问题:

https://gitlab.kitware.com/cmake/cmake/-/issues/21228

我还向此处的协议缓冲区项目报告了由于缺少文档而引起的混乱:

https://github.com/protocolbuffers/protobuf/issues/7912

注意:在某些Linux安装上(至少是CentOS7和Debian9),默认设置通常是使用configure / make而不是完全不安装cmake配置文件的cmake来生成协议缓冲区。因此,find_package(protobuf 3.5.0必需)可以工作,但是find_package(protobuf 3.5.0必需的路径I / only / wand / to / help)将失败。

答案 1 :(得分:2)

看起来cmake API有所改变。尝试将其更改为

protobuf_generate(
 LANGUAGE cpp
 TARGET <YOUR_TARGET_NAME> 
 PROTOS Foo.proto)

这将直接将生成的文件添加到目标的源列表。 看看protobuf_generate中的protobuf-config.cmake函数中的新选项。

答案 2 :(得分:0)

您需要 protobuf_MODULE_COMPATIBLE

我正在使用CMake3.14。 protobuf-config.cmake的最后3行是:

if(protobuf_MODULE_COMPATIBLE)
  include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake")
endif()

protobuf_generate_cpp()protobuf-module.cmake中定义。

因此,要protobuf_generate_cpp(),人们必须在其CMakeLists.txt中打开protobuf_MODULE_COMPATIBLE

set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "")

记住清理以前生成的cmake缓存文件,然后再次调用cmake。