无法使用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: undefined reference to
中google :: protobuf :: internal :: VerifyVersion(int,int,char const *)' /home/camille/ClionProjects/protobuf/main.cpp:49:未定义的引用 到tutorial::AddressBook::AddressBook()' /home/camille/ClionProjects/protobuf/main.cpp:54: undefined reference to
google :: protobuf :: Message :: ParseFromIstream(std :: istream *)'
我的错误在哪里?我如何使它工作?
答案 0 :(得分:4)
您的程序无法链接,因为${PROTOBUF_LIBRARY}
在您的顶级CMakeLists.txt
范围内为空。发生这种情况是因为调用add_subdirectory
会创建子范围,而Protobuf_XXX
设置的find_package(Protobuf REQUIRED)
变量仅在该子范围内。
解决此问题的一种好方法是将以下内容添加到proto/CMakeLists.txt
:
target_link_libraries(proto INTERFACE ${Protobuf_LIBRARIES})
这会指示链接到proto
的目标也链接到${Protobuf_LIBRARIES}
。现在,您可以在顶级target_link_libraries
中简化CMakeLists.txt
:
target_link_libraries(addressbook proto)
另外,你也可以使用例如。
target_link_libraries(${PROJECT_NAME} INTERFACE ... )
${PROJECT_NAME}
解析为您在project(...)
文件中的CMakeLists.txt
语句中设置的任何内容。
最后,请注意,此链接指向Protobuf_LIBRARIES
而不是PROTOBUF_LIBRARY
。 Protobuf_LIBRARIES
包括Protocol Buffers库和依赖的Pthreads库。
答案 1 :(得分:2)
您需要传递给target_link_libraries
的变量是Protobuf_LIBRARIES
。请参阅documentation。
答案 2 :(得分:0)
注意变量名称案例:使用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,其中包含有关如何诊断此类问题的更多信息。
答案 3 :(得分:-1)
cmakeList.txt:
cmake_minimum_required(版本3.12) 项目(protobuf)
SET(CMAKE_CXX_FLAGS“ -g -Wall -Werror -std = c ++ 11”)
设置(CMAKE_CXX_STANDARD 11)
INCLUDE(FindProtobuf)
FIND_PACKAGE(需要Protobuf)
INCLUDE_DIRECTORIES($ {PROTOBUF_INCLUDE_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER地址簿.proto) ADD_LIBRARY(proto2 $ {PROTO_HEADER} $ {PROTO_SRC}) TARGET_LINK_LIBRARIES(proto2)
INCLUDE_DIRECTORIES($ {CMAKE_CURRENT_BINARY_DIR})
add_executable(protobuf main.cpp)
TARGET_LINK_LIBRARIES(protobuf proto2 $ {PROTOBUF_LIBRARY})