首页 文章

CMake不适用于Google Protobuf

提问于
浏览
2

无法使用CMake链接protobuf库 . 我的CMakeLists是

cmake_minimum_required(VERSION 3.6)
project(addressbook)

set(CMAKE_CXX_STANDARD 11)
set(PROJECT_NAME addressbook)

ADD_SUBDIRECTORY(proto)

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
ADD_EXECUTABLE(main main.cpp)
TARGET_LINK_LIBRARIES(main proto ${PROTOBUF_LIBRARY})

在proto子目录中还有另一个CMakeLists.txt(这样就可以在github repo https://github.com/shaochuan/cmake-protobuf-example中完成)

INCLUDE(FindProtobuf)
FIND_PACKAGE(Protobuf REQUIRED)
INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER message.proto)
ADD_LIBRARY(proto ${PROTO_HEADER} ${PROTO_SRC})

但是我的IDE仍然会输出很多行

CMakeFiles / main.dir / main.cpp.o:在函数main中:/home/camille/ClionProjects/protobuf/main.cpp:42:未定义引用togoogle :: protobuf :: internal :: VerifyVersion(int,int, char const )'/ home / camille / ClionProjects /protobuf / main.cpp:49:未定义的教程参考:: AddressBook :: AddressBook()'/ home / camille / ClionProjects /protobuf / main.cpp:54:undefined reference togoogle :: protobuf的::消息:: ParseFromIstream(标准:: istream的)”

我的错误在哪里?我如何使其工作?

3 回答

  • 2

    您需要传递给 target_link_libraries 的变量是 Protobuf_LIBRARIES . 见documentation .

  • 0

    您的程序无法链接,因为 ${PROTOBUF_LIBRARY} 在您的顶级 CMakeLists.txt 范围内为空 . 发生这种情况是因为调用 add_subdirectory 会创建子范围, find_package(Protobuf REQUIRED) 设置的 Protobuf_XXX 变量仅在该子范围内 .

    解决此问题的一种好方法是将以下内容添加到 proto/CMakeLists.txt

    target_link_libraries(proto INTERFACE ${Protobuf_LIBRARIES})
    

    这指示链接到 proto 的目标也链接到 ${Protobuf_LIBRARIES} . 现在,您可以在顶级 CMakeLists.txt 中简化 target_link_libraries

    target_link_libraries(addressbook proto)
    

    另外,您也可以使用例如

    target_link_libraries(${PROJECT_NAME} INTERFACE ... )
    

    ${PROJECT_NAME} 解析为您在 CMakeLists.txt 文件中的 project(...) 语句中设置的任何内容 .

    最后,请注意,这链接到 Protobuf_LIBRARIES 而不是 PROTOBUF_LIBRARY . Protobuf_LIBRARIES 包括Protocol Buffers库和依赖的Pthreads库 .

  • 2

    注意变量名称的情况:使用CMake 3.6及更高版本, FindProtobuf 模块的输入和输出变量都从 PROTOBUF_ 重命名为 Protobuf_ (参见release notes),因此使用 Protobuf_ 可以与CMake 3.6一起使用,但是使用早期版本的未定义引用失败 .

    为了安全起见,要么使用旧式

    target_link_libraries(${PROJECT_NAME} INTERFACE ${PROTOBUF_LIBRARIES}))
    

    或强迫每个人至少使用CMake 3.6

    cmake_minimum_required(VERSION 3.6)
    

    此外,Kitware cmake问题跟踪器中有一个resolved bug report,其中包含有关如何诊断此类问题的更多信息 .

相关问题