Fantastic Mr Fox
Fantastic Mr Fox

Reputation: 33904

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:

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?

Upvotes: 9

Views: 16691

Answers (4)

Fantastic Mr Fox
Fantastic Mr Fox

Reputation: 33904

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.

Upvotes: 9

MSalters
MSalters

Reputation: 179981

". If you build it statically then you are using the Code generation type in Visual studio of Multi-threaded (/MT)"

No, that is your error right there.

/MT defines which CRT library you consume. It's not the switch for the type of library you produce.

Upvotes: 2

Ation
Ation

Reputation: 731

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 ).

Upvotes: 4

SoronelHaetir
SoronelHaetir

Reputation: 15172

Create a custom statically built protobuf library that uses the right library (you'll probably want to leave the default configuration alone for use with a release build of your DLL). That way your DLL would use a debug protobuf library in debug builds and a release protobuf library in release builds.

Upvotes: -1

Related Questions