Encountered on Visual Studio 2013, but it's reproducible with any version.
I cloned the protocol buffer library from github, ran CMake-gui on it (I left everything to default, so it's the static version), only built libprotobuf (other project failed for some reason, cmd.exe error, might have something to do with tests, but libprotobuf builds fine).
My project uses headers generated with the .proto file found on the mapbox vector tiles spec's github.
When I link, I first have this error
Error 1 error C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' s:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility
I tried disabling it with -D_SCL_SECURE_NO_WARNINGS
in additional command line arguments, but then I have other errors:
Error 1 error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in main.obj S:\eiogit3\misc-projs\mapload\mapload\libprotobufd.lib(common.obj)
The main goal of protobufs is optimization. By removing many responsibilities done by data formats and making it focus only on performing serialization and deserialization, we can ensure that the data is transmitted as fast as possible and in the most compact way.
Protobuf strings are always valid UTF-8 strings. See the Language Guide: A string must always contain UTF-8 encoded or 7-bit ASCII text.
The textual order is largely irrelevant, although it may impact some code generation tooling - but most languages don't care about declaration order, so even that: won't matter. The fields are still defined semantically equivalent - the numbers match the existing meaning (name) and type.
It's a mismatch of how the VStudio C (and C++) RunTime Library (VCRTLib or UCRT - check [SO]: How to circumvent Windows Universal CRT headers dependency on vcruntime.h (@CristiFati's answer)) is used by your project and by libprotobuf project. Let me detail:
Let's say there's some C (C++) code. The purpose of that code is to be run. Than can be achieved:
You can check [SO]: LNK2005 Error in CLR Windows Form (@CristiFati's answer) for details of how C (C++) code gets to be transformed in executable format. Also Google is full of articles about differences between static and dynamic libraries, when to use one or the other, an example can be found on [SO]: When to use dynamic vs. static libraries.
As you guessed, the CRT or C RunTime library (that contains the underlying system that makes C code able to run - one example are memory management functions: malloc, free) makes no exception - it's the equivalent of Nix's libc.a (static or archive) vs. libc.so (dynamic or shared object) - but in VStudio it's a little bit more complicated:
Notes:
Now, UCRT parts, are not included in the project like any other lib (Project Properties -> Linker -> Input -> Additional Dependencies), but because their nature (static or dynamic) is required at compile time they are configured from: [MS.Docs]: /MD, /MT, /LD (Use Run-Time Library), where there are 4 available choices:
Obviously, the ones that contain "Debug" are when building for Debug configuration while the other ones for Release; the key point is that the ones that have DLL are using the dynamic runtime version, while the other ones the static version.
Back to your error: the linker complains that main.obj (part of your project) has MDd_DynamicDebug (linking against the dynamic debug version), while common.obj (part of libprotobuf project) has MTd_StaticDebug (linking against the static debug version), so you link against 2 runtimes in the same executable (or .dll) - which is not possible.
In order to fix it, you should make sure that both libprotobuf and your main project have the same value for UCRT.
Of course it's simpler to change your main project setting to match libprotobuf's one, but it's recommended to use the dynamic runtime version (things can get messy in larger projects that have .dlls involved) even if this requires to recompile libprotobuf (well, if changing that option generates errors that make libprotobuf very hard to build, and your project is going to stay this simple, you can use the static UCRT).
Note: Not to mistake UCRT type (static / dynamic) with the way libprotobuf is being built (static at this point, but I'm sure that it can be built as dynamic too).
Adding some additional info on the above note, as some comments requested it, and it might be useful to other users.
There are 2 aspects about a library (including libprotobuf), that are totally unrelated:
So, there are 4 perfectly valid combinations:
For libprotobuf, each of the aspects is controlled by a boolean cmake option:
The 2 flags can be set by either:
-Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF
)The above 4 combinations are thus possible (at least in v3.5), but #2. is disabled by default (specifying -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_MSVC_STATIC_RUNTIME=ON
will build a .dll which will link to the dynamic UCRT), in order to avoid possible runtime problems, and enabling it requires manual intervention.
For more details regarding build instructions (via cmake), check: [GitHub]: protocolbuffers/protobuf - (master) protobuf/cmake/README.md.
#1: The .lib file will only be created if the library exports symbols, as it wouldn't make sense otherwise (nothing needed at link time, and the .dll will be created, but pretty much unusable)
#2: For newer VStudio versions (starting with v2015), the msvcr(t) part has been replaced by vcruntime (or at least this is the entrypoint, as it was split in smaller logical pieces (check the URL at the beginning))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With