CMake 找不到 Protobuf `protobuf_generate_cpp`
CMake can't find Protobuf `protobuf_generate_cpp`
正在使用
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
这里有什么问题?
看起来 cmake API 发生了一些变化。尝试将其更改为
protobuf_generate(
LANGUAGE cpp
TARGET <YOUR_TARGET_NAME>
PROTOS Foo.proto)
这会将生成的文件直接添加到目标的源列表中。
查看 protobuf-config.cmake
中的 protobuf_generate
函数以获得新选项。
你需要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。
现有的 帮助了我,但错过了很多关于正在发生的事情的解释。
find_package可以工作在MODULE模式或CONFIG模式。
在 MODULE 模式下,它搜索 Find\<package\>.cmake
(通常由 cmake 所有)。
在 CONFIG 模式下,它搜索 \<package\>Config.cmake
(由包提供)。
cmake和protocol buffers都可以为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 模块,则不需要这样做,因此此处没有记录。
虽然这不是它的错 cmake 可以警告可能的冲突。
如果在这里提出:
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 REQUIRED) 会工作但是 find_package(protobuf 3.5.0 REQUIRED PATH I/only/wanted/to/help) 会失败。
正在使用
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
这里有什么问题?
看起来 cmake API 发生了一些变化。尝试将其更改为
protobuf_generate(
LANGUAGE cpp
TARGET <YOUR_TARGET_NAME>
PROTOS Foo.proto)
这会将生成的文件直接添加到目标的源列表中。
查看 protobuf-config.cmake
中的 protobuf_generate
函数以获得新选项。
你需要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。
现有的
find_package可以工作在MODULE模式或CONFIG模式。
在 MODULE 模式下,它搜索 Find\<package\>.cmake
(通常由 cmake 所有)。
在 CONFIG 模式下,它搜索 \<package\>Config.cmake
(由包提供)。
cmake和protocol buffers都可以为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 模块,则不需要这样做,因此此处没有记录。
虽然这不是它的错 cmake 可以警告可能的冲突。 如果在这里提出:
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 REQUIRED) 会工作但是 find_package(protobuf 3.5.0 REQUIRED PATH I/only/wanted/to/help) 会失败。