Using google protobuf with libraries in cmake on Windows, Visual Studio 2013

一个人想着一个人 提交于 2020-08-08 06:38:50

问题


I have a CMake project with several sub-directories and library modules that eventually get built into client and server libraries, and those libraries are used from executable to test them. I am trying to use Google's protobuf library inside one of those libraries. I am creating my sub-library as follows:

include_directories(
    .
    ../rendering_backend
    ../shared
    ${MY_THIRDPARTY_DIR}/protobuf/include
)

add_library(Client STATIC
    client.cpp
    client.hpp
    ../common.hpp
    ../shared/protobufs/my_bufs.pb.cc
    ../shared/protobufs/my_bufs.pb.h
)

target_link_libraries(Client
    RenderingBackend
    ${MY_THIRDPARTY_DIR}/protobuf/lib/libprotobufd.lib
)

The executable is declared as follows:

add_executable(TEST_Client
    client_tester.cpp
    ../src/rendering_backend/rendering_backend.hpp)

target_link_libraries(TEST_Client Client)

All these files seem to be generating properly, but when I build, I get the following error (and many just like it):

libprotobufd.lib(zero_copy_stream_impl.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in client_tester.obj

I have gone back to the protobuf solution and verified that all projects are set to use /MDd in their Runtime Library setting. It was generated following the guide at https://github.com/google/protobuf/tree/master/cmake.

I have seen many questions and answers about protobufs, but none seem to address this problem. I don't know what could be trying to build /MTd when everything is set to /MDd inside Visual Studio.

Assuming that this process would work if I were doing it correctly, I can only assume I'm doing something wrong. What is the intended way to do something like this?

[EDIT] I was trying to use protobuf 3.0.0 here.


回答1:


In order for find_package to identify the correct paths, you must edit the CMAKE_PREFIX_PATH variable to search for libraries. This code allows it to find the path correctly, assuming that you have correctly set up THIRDPARTY_DIR and you downloaded the release version of protobuf (2.6.1 as of this writing):

set(CMAKE_PREFIX_PATH
    ${CMAKE_PREFIX_PATH}
    ${THIRDPARTY_DIR}/protobuf-2.6.1
)

Protobuf3 can also be used but in addition to setting the install path in CMAKE_PREFIX_PATH, you must also supply the CONFIG argument to find_package as follows:

find_package(Protobuf CONFIG REQUIRED)

...assuming Protobuf is required.

In my case, I configured Protobuf 3.0.0 beta 2 to install to a folder "install" within its own directory:

set(CMAKE_PREFIX_PATH
    ${CMAKE_PREFIX_PATH}
    ${THIRDPARTY_DIR}/protobuf-3.0.0-beta-2/install
)

find_package(Protobuf CONFIG REQUIRED)

(Thanks to tamas.kenez for correcting me on this.)

Note that I had to build the release library before find_package(Protobuf) would return without errors. I originally only build the debug libraries.

I also had to be cautious of which MSVC runtime I build with. Dynamic seems to be the default for most projects, but Protobuf3 builds with the static runtime unless you configure it to do otherwise (there's a checkbox if you're using the GUI). Linking static runtime libraries to dynamic runtime executables causes all kinds of linker problems and redefinitions, so be careful of that.

Lastly, CMake GUI seems to retain some information about directory structures until you reload the project (or possibly restart the program entirely); so I hit a snag in trying to change which version of protobuf I used when CMake kept finding a directory structure I had already deleted, even after clearing the whole build directory. (Solved by clearing the build directory and relaunching CMake GUI and reloading the base project.)




回答2:


You can use git-subtree or git-submodule to make google protobuf sources part of your solution and build it with your project.

Add to your top-level CMakeLists.txt

add_subdiretory("third-party/protobuf/cmake")
include_directories("third-party/protobuf/src")

to get all protobuf targets. Then you can add dependency to protobuf with

target_link_libraries(YourLibrary libprotobuf libprotobuf-lite libprotoc)

Hope this helps.



来源:https://stackoverflow.com/questions/34738616/using-google-protobuf-with-libraries-in-cmake-on-windows-visual-studio-2013

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!