Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Statically link google protobuf lib into a dll library

On the instructional page for installing and using the google protobuf library (Install Protobuf On Windows) it states:

If your project is itself a DLL intended for use by third-party software, we recommend that you do NOT expose protocol buffer objects in your library's public interface, and that you statically link protocol buffers into your library.

I am wondering how this can be accomplished. As far as i know, you can build google protobuf in 2 ways: Statically and dynamically.

If you build it dynamiclly you will face the aformentioned problems. If you build it statically then you are using the Code generation type in Visual studio of Multi-threaded (/MT). Which means in my dll lib (where it is built with Multi-threaded DLL (/MD)) you will get the following linker error:

error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in Emulator.obj

Now there are a few questions covering how to solve this:

  • error LNK2038: mismatch detected for '_MSC_VER': value '1600' doesn't match value '1700' in CppFile1.obj
  • Mismatch Detected for 'RuntimeLibrary'
  • (Very similar) Errors when linking to protobuf 3 on MSVC 2013

But the answer is commonly, change your lib to match the build type of the other library. The issue is, I don't want to do that, I want a DLL. And i want to link google protobuf statically, as described in their documentation. How can i achieve this?

like image 669
Fantastic Mr Fox Avatar asked Dec 20 '17 06:12

Fantastic Mr Fox


People also ask

Is Protobuf a library?

Protocol Buffers is a library from Google. It provides efficient and language-independent ways to serialize the data. It supports serialization and deserialization from languages like Java, Python, Go, Dart, etc.

Does Google use Protobuf?

Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler.


2 Answers

As pointed out by @MSalters, in the answer here the configuration of code generation does not indicate the type of lib that is built, but the type of c++ std lib that is used. In order to modify this on the command line build, it is required that you use the -Dprotobuf_MSVC_STATIC_RUNTIME switch (Credit for advice about this parameter comes from @Ation answer here). In order to set up the build to use Multi-threaded DLL (/MD)) specifically for google protobuf, when generating the makefiles from CMAKE you must do the following, for debug:

cmake -G "NMake Makefiles" ^
-DCMAKE_BUILD_TYPE=Debug  -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ^
-DCMAKE_INSTALL_PREFIX=../../../install/debug ^
../..

Or for release:

cmake -G "NMake Makefiles" ^
-DCMAKE_BUILD_TYPE=Release -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ^
-DCMAKE_INSTALL_PREFIX=../../../install/release ^
../..

The code generated by the following nmake command will have code generation of type Multi-threaded DLL (/MD)).

See protobuf/README.md for more information.

like image 66
Fantastic Mr Fox Avatar answered Nov 18 '22 07:11

Fantastic Mr Fox


You need to build your own protobuf:

  • make sure that you have CMake
  • download your protobuf version source code from protobuf github
  • open this folder in VS developer command line
  • run cmake

    cmake -G "Visual Studio 14" -Dprotobuf_MSVC_STATIC_RUNTIME=ON

You might want to change VS version, check cmake help message to get correct generator name.

After that - everything should be easy for you. Open generated solution, check upon runtime lib settings, build a release and debug versions.

And include those files ( or dirs ) into your project linkage settings ( for release and debug there should be different lib files ).

like image 4
Ation Avatar answered Nov 18 '22 07:11

Ation