无法使用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 回答
您需要传递给
target_link_libraries
的变量是Protobuf_LIBRARIES
. 见documentation .您的程序无法链接,因为
${PROTOBUF_LIBRARY}
在您的顶级CMakeLists.txt
范围内为空 . 发生这种情况是因为调用add_subdirectory
会创建子范围,find_package(Protobuf REQUIRED)
设置的Protobuf_XXX
变量仅在该子范围内 .解决此问题的一种好方法是将以下内容添加到
proto/CMakeLists.txt
:这指示链接到
proto
的目标也链接到${Protobuf_LIBRARIES}
. 现在,您可以在顶级CMakeLists.txt
中简化target_link_libraries
:另外,您也可以使用例如
${PROJECT_NAME}
解析为您在CMakeLists.txt
文件中的project(...)
语句中设置的任何内容 .最后,请注意,这链接到
Protobuf_LIBRARIES
而不是PROTOBUF_LIBRARY
.Protobuf_LIBRARIES
包括Protocol Buffers库和依赖的Pthreads库 .注意变量名称的情况:使用CMake 3.6及更高版本,
FindProtobuf
模块的输入和输出变量都从PROTOBUF_
重命名为Protobuf_
(参见release notes),因此使用Protobuf_
可以与CMake 3.6一起使用,但是使用早期版本的未定义引用失败 .为了安全起见,要么使用旧式
或强迫每个人至少使用CMake 3.6
此外,Kitware cmake问题跟踪器中有一个resolved bug report,其中包含有关如何诊断此类问题的更多信息 .