PDA

View Full Version : Linking protocol buffers library statically



yagabey
3rd January 2017, 00:06
Hi,
I am trying to statically link Google Protocol Buffers to my application. I tried every combination i could; but unfortunatelly i couldnt manage to compile...

I am using MSVC2015 compiler with Qt 5.7.1 on Qt Creator.

I compiled the protocol buffers library with the same compiler in statically release mode.

And added it to .pro file:


LIBS += -L$$PWD/libs/ -llibprotobuf

But i am getting hundres of error messages like that:


libprotobuf.lib(common.cc.obj):-1: error: LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MD_DynamicRelease' in drivermessage.pb.obj

It complains for a mismatch. But i think, i am adding the static library as it should be. Am i missing something ? Any idea?
Here is a test project containing static probuf libraries:

https://dl.dropboxusercontent.com/u/3790845/Messaging.rar

Thanks in advance..

d_stranz
3rd January 2017, 01:18
Don't confuse compiling with linking. Your code compiles just fine, it is the linking that is failing. It looks like when you built the library, you used a flag that said it should be linked statically to the Windows runtime library (MT), but the rest of your code is linking dynamically via DLLs (MD). See this StackOverflow article (http://stackoverflow.com/questions/28887001) or this one (http://stackoverflow.com/questions/14714877) for the explanation and solution.

yagabey
3rd January 2017, 01:33
Thanks for reply,

Yes you are right. Actually i mean, the binary is incomplete since I am trying to statically link the library. I followed google's instruction for compiling on their website here (https://github.com/google/protobuf/blob/master/cmake/README.md) . If I had used -Dprotobuf_BUILD_SHARED_LIBS=ON flag for CMake, it would have compiled the shared libraries. But I didn't. The default behaviour is static library.

And another clue for the type of library is its size. It has a quite big size, 31 MBs. Its shared lib version is about 3 MBs. So i think there is not a problem with the compiled static library.

yagabey
3rd January 2017, 14:28
I just realised something, when i change the compile mode to debug, the warning changes to:


libprotobuf.lib(generated_message_util.obj):-1: error: LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MDd_DynamicDebug' in drivermessage.pb.obj

"MD_DynamicRelease" changed to "MDd_DynamicDebug".

I think it says: "Ok the library is static but your build is "MDd_DynamicDebug" or "MD_DynamicRelease"

The question is "why is qmake configuring my project as :"MD_Dynamic" "

d_stranz
3rd January 2017, 22:36
I think it says: "Ok the library is static but your build is "MDd_DynamicDebug" or "MD_DynamicRelease"

Partly right - changing your project build to "Debug" changes the runtime library linkage to Debug also.

The problem is that CMake has been told to build your library to link to the C++ "Static Release" runtime library. This has nothing to do with your library itself - your library was built as a static release library. The problem is that the library has been told that to resolve the runtime library symbols it uses, it needs to look for the C++ static release library. The rest of your project has been told to look for the C++ dynamic release (or debug) library. You can't have both at the same time.

So you probably need to run CMake again to generate your library's build tree and make sure the options including linking against the dynamic release runtime. You can do this by adding "/MD" to the CMAKE_CXX_FLAGS variable (and removing "/MT" if you see it). You will probably find this variable somewhere in the top-level CMakelists.txt file for the library. You will need to delete the old build tree to make sure the Makefiles / vcxproj files are regenerated (depending on which CMake generator you use).


The question is "why is qmake configuring my project as :"MD_Dynamic" "

Because that is the default, and that is the one you want, because Qt is built to link that way. You would have to rebuild all of Qt if you want to change it. Better to change your library instead.