Errors when linking to protobuf 3 on MS Visual C
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.0vcincludexutility
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:eiogit3misc-projsmaploadmaploadlibprotobufd.lib(common.obj)
c++ visual-studio visual-c++ visual-studio-2013 protocol-buffers
add a comment |
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.0vcincludexutility
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:eiogit3misc-projsmaploadmaploadlibprotobufd.lib(common.obj)
c++ visual-studio visual-c++ visual-studio-2013 protocol-buffers
So, you builtlibprotobufstatic version (.lib) using CMake, and now you are trying to link it in your VStudio app?
– CristiFati
Jan 31 '16 at 17:20
Yes, I built it with MSVC 2013, and am now linking it to my project, also using MSVC 2013
– jokoon
Jan 31 '16 at 17:22
here is the project file
– jokoon
Jan 31 '16 at 17:30
add a comment |
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.0vcincludexutility
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:eiogit3misc-projsmaploadmaploadlibprotobufd.lib(common.obj)
c++ visual-studio visual-c++ visual-studio-2013 protocol-buffers
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.0vcincludexutility
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:eiogit3misc-projsmaploadmaploadlibprotobufd.lib(common.obj)
c++ visual-studio visual-c++ visual-studio-2013 protocol-buffers
c++ visual-studio visual-c++ visual-studio-2013 protocol-buffers
edited Nov 25 '18 at 11:13
CristiFati
13.8k72436
13.8k72436
asked Jan 31 '16 at 16:49
jokoonjokoon
2,50993666
2,50993666
So, you builtlibprotobufstatic version (.lib) using CMake, and now you are trying to link it in your VStudio app?
– CristiFati
Jan 31 '16 at 17:20
Yes, I built it with MSVC 2013, and am now linking it to my project, also using MSVC 2013
– jokoon
Jan 31 '16 at 17:22
here is the project file
– jokoon
Jan 31 '16 at 17:30
add a comment |
So, you builtlibprotobufstatic version (.lib) using CMake, and now you are trying to link it in your VStudio app?
– CristiFati
Jan 31 '16 at 17:20
Yes, I built it with MSVC 2013, and am now linking it to my project, also using MSVC 2013
– jokoon
Jan 31 '16 at 17:22
here is the project file
– jokoon
Jan 31 '16 at 17:30
So, you built
libprotobuf static version (.lib) using CMake, and now you are trying to link it in your VStudio app?– CristiFati
Jan 31 '16 at 17:20
So, you built
libprotobuf static version (.lib) using CMake, and now you are trying to link it in your VStudio app?– CristiFati
Jan 31 '16 at 17:20
Yes, I built it with MSVC 2013, and am now linking it to my project, also using MSVC 2013
– jokoon
Jan 31 '16 at 17:22
Yes, I built it with MSVC 2013, and am now linking it to my project, also using MSVC 2013
– jokoon
Jan 31 '16 at 17:22
here is the project file
– jokoon
Jan 31 '16 at 17:30
here is the project file
– jokoon
Jan 31 '16 at 17:30
add a comment |
1 Answer
1
active
oldest
votes
It's a mismatch of how the VStudio C (and C++) Runtime Library (VCRTLib - 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 code. The purpose of that code is to be run. Than can be achieved:
- Directly: including that code in an VC Application type project - which will generate an .exe
- Indirectly: including the code in an VC Library type project - which will generate a library which will only be able to run when called from another .exe (that calls that library). The library can be:
static: all the C code will be compiled and stored in a .lib file. You will need that file when using the library in another project (whether it's an application or a library) - at link time. Note that all the needed code from your .lib will be "copied" into the other project
dynamic: you will have 2 files now: a .dll file which will contain the compiled (and linked) code, and a .lib file1 which will contain "pointers" (if you will) to the code in the .dll file. When using the library in another project, you will also need the .lib file at link time, but now it won't contain the code so it won't be copied in the other library (the other library will be smaller), but at runtime the other library will need the .dll file
You can check [SO]: LNK2005 Error in CLR Windows Form (@CristiFati's answer) for details of how 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 Ux's libc.a (static or archive) vs. libc.so (dynamic or shared object) - but in VStudio it's a little bit more complicated:
- Static CRT resides in libcmt.lib
- Dynamic CRT resides in msvcrt.lib which "points" to msvcr###.dll2 (msvcr120.dll for VStudio 2013)
Notes:
- A "d" at the end of the library name (msvcrd.lib), means that it's compiled with debug symbols
C++ runtime library is under the exact situation; the names have an extra p: libcpmt.lib, msvcprt.lib, msvcp120.dll
- For more details, check [MS.Docs]: CRT Library Features
Now, VCRTLib 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:
- Multi-threaded (/MT)
- Multi-threaded Debug (/MTd)
- Multi-threaded DLL (/MD)
- Multi-threaded Debug DLL (/MDd)
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 VCRTLib.
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 VCRTLib).
Note: Not to mistake VCRTLib 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).
@EDIT0:
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:
Library type (the way it is being built): dynamic / static
VCRTLib type (the way it uses VCRTLib): again, dynamic / static
So, there are 4 perfectly valid combinations:
- Dynamic library using dynamic VCRTLib
- Dynamic library using static VCRTLib
- Static library using dynamic VCRTLib
- Static library using static VCRTLib
For libprotobuf, each of the aspects is controlled by a boolean cmake option:
- Library type: protobuf_BUILD_SHARED_LIBS
VCRTLib type: protobuf_MSVC_STATIC_RUNTIME
The 2 flags can be set by either:
- cmake-gui
cmake cmdline (passing them as arguments - e.g.:-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 VCRTLib), 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 2015), the msvcr(t) part has been replaced by vcruntime (or at least this is the entrypoint, as it was split in smaller logical pieces)
Does this, by any chance, solve the problem github.com/google/protobuf/tree/master/cmake ?
– jokoon
Feb 1 '16 at 10:01
Thank you, it now builds (with the -D_SCL_SECURE_NO_WARNINGS in command line). I already knew the difference between static and dynamic, but I had no idea about that runtime library setting. And actually, the google protobuf doc states that it's advised to use the static version, not the dynamic version: github.com/google/protobuf/tree/master/…
– jokoon
Feb 1 '16 at 10:11
Glad to hear it works. I just read the comments on the link you provided. Now regarding your previous question, if it's about the template export at the end, then I don't think it does.
– CristiFati
Feb 1 '16 at 10:19
Question: Can I build a static library that uses dynamic runtime and the other way around?
– Lennart Rolland
Nov 12 '18 at 10:56
1
Yes. By default the way libprotobuf is built dictates the way VCRTLib is used. Build types are controlled by 2 flags. Here's how i built the static libprotobuf version using dynamic VCRTLib-Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF. I should add this piece of info into the answer.
– CristiFati
Nov 12 '18 at 11:06
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35116437%2ferrors-when-linking-to-protobuf-3-on-ms-visual-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It's a mismatch of how the VStudio C (and C++) Runtime Library (VCRTLib - 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 code. The purpose of that code is to be run. Than can be achieved:
- Directly: including that code in an VC Application type project - which will generate an .exe
- Indirectly: including the code in an VC Library type project - which will generate a library which will only be able to run when called from another .exe (that calls that library). The library can be:
static: all the C code will be compiled and stored in a .lib file. You will need that file when using the library in another project (whether it's an application or a library) - at link time. Note that all the needed code from your .lib will be "copied" into the other project
dynamic: you will have 2 files now: a .dll file which will contain the compiled (and linked) code, and a .lib file1 which will contain "pointers" (if you will) to the code in the .dll file. When using the library in another project, you will also need the .lib file at link time, but now it won't contain the code so it won't be copied in the other library (the other library will be smaller), but at runtime the other library will need the .dll file
You can check [SO]: LNK2005 Error in CLR Windows Form (@CristiFati's answer) for details of how 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 Ux's libc.a (static or archive) vs. libc.so (dynamic or shared object) - but in VStudio it's a little bit more complicated:
- Static CRT resides in libcmt.lib
- Dynamic CRT resides in msvcrt.lib which "points" to msvcr###.dll2 (msvcr120.dll for VStudio 2013)
Notes:
- A "d" at the end of the library name (msvcrd.lib), means that it's compiled with debug symbols
C++ runtime library is under the exact situation; the names have an extra p: libcpmt.lib, msvcprt.lib, msvcp120.dll
- For more details, check [MS.Docs]: CRT Library Features
Now, VCRTLib 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:
- Multi-threaded (/MT)
- Multi-threaded Debug (/MTd)
- Multi-threaded DLL (/MD)
- Multi-threaded Debug DLL (/MDd)
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 VCRTLib.
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 VCRTLib).
Note: Not to mistake VCRTLib 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).
@EDIT0:
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:
Library type (the way it is being built): dynamic / static
VCRTLib type (the way it uses VCRTLib): again, dynamic / static
So, there are 4 perfectly valid combinations:
- Dynamic library using dynamic VCRTLib
- Dynamic library using static VCRTLib
- Static library using dynamic VCRTLib
- Static library using static VCRTLib
For libprotobuf, each of the aspects is controlled by a boolean cmake option:
- Library type: protobuf_BUILD_SHARED_LIBS
VCRTLib type: protobuf_MSVC_STATIC_RUNTIME
The 2 flags can be set by either:
- cmake-gui
cmake cmdline (passing them as arguments - e.g.:-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 VCRTLib), 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 2015), the msvcr(t) part has been replaced by vcruntime (or at least this is the entrypoint, as it was split in smaller logical pieces)
Does this, by any chance, solve the problem github.com/google/protobuf/tree/master/cmake ?
– jokoon
Feb 1 '16 at 10:01
Thank you, it now builds (with the -D_SCL_SECURE_NO_WARNINGS in command line). I already knew the difference between static and dynamic, but I had no idea about that runtime library setting. And actually, the google protobuf doc states that it's advised to use the static version, not the dynamic version: github.com/google/protobuf/tree/master/…
– jokoon
Feb 1 '16 at 10:11
Glad to hear it works. I just read the comments on the link you provided. Now regarding your previous question, if it's about the template export at the end, then I don't think it does.
– CristiFati
Feb 1 '16 at 10:19
Question: Can I build a static library that uses dynamic runtime and the other way around?
– Lennart Rolland
Nov 12 '18 at 10:56
1
Yes. By default the way libprotobuf is built dictates the way VCRTLib is used. Build types are controlled by 2 flags. Here's how i built the static libprotobuf version using dynamic VCRTLib-Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF. I should add this piece of info into the answer.
– CristiFati
Nov 12 '18 at 11:06
add a comment |
It's a mismatch of how the VStudio C (and C++) Runtime Library (VCRTLib - 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 code. The purpose of that code is to be run. Than can be achieved:
- Directly: including that code in an VC Application type project - which will generate an .exe
- Indirectly: including the code in an VC Library type project - which will generate a library which will only be able to run when called from another .exe (that calls that library). The library can be:
static: all the C code will be compiled and stored in a .lib file. You will need that file when using the library in another project (whether it's an application or a library) - at link time. Note that all the needed code from your .lib will be "copied" into the other project
dynamic: you will have 2 files now: a .dll file which will contain the compiled (and linked) code, and a .lib file1 which will contain "pointers" (if you will) to the code in the .dll file. When using the library in another project, you will also need the .lib file at link time, but now it won't contain the code so it won't be copied in the other library (the other library will be smaller), but at runtime the other library will need the .dll file
You can check [SO]: LNK2005 Error in CLR Windows Form (@CristiFati's answer) for details of how 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 Ux's libc.a (static or archive) vs. libc.so (dynamic or shared object) - but in VStudio it's a little bit more complicated:
- Static CRT resides in libcmt.lib
- Dynamic CRT resides in msvcrt.lib which "points" to msvcr###.dll2 (msvcr120.dll for VStudio 2013)
Notes:
- A "d" at the end of the library name (msvcrd.lib), means that it's compiled with debug symbols
C++ runtime library is under the exact situation; the names have an extra p: libcpmt.lib, msvcprt.lib, msvcp120.dll
- For more details, check [MS.Docs]: CRT Library Features
Now, VCRTLib 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:
- Multi-threaded (/MT)
- Multi-threaded Debug (/MTd)
- Multi-threaded DLL (/MD)
- Multi-threaded Debug DLL (/MDd)
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 VCRTLib.
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 VCRTLib).
Note: Not to mistake VCRTLib 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).
@EDIT0:
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:
Library type (the way it is being built): dynamic / static
VCRTLib type (the way it uses VCRTLib): again, dynamic / static
So, there are 4 perfectly valid combinations:
- Dynamic library using dynamic VCRTLib
- Dynamic library using static VCRTLib
- Static library using dynamic VCRTLib
- Static library using static VCRTLib
For libprotobuf, each of the aspects is controlled by a boolean cmake option:
- Library type: protobuf_BUILD_SHARED_LIBS
VCRTLib type: protobuf_MSVC_STATIC_RUNTIME
The 2 flags can be set by either:
- cmake-gui
cmake cmdline (passing them as arguments - e.g.:-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 VCRTLib), 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 2015), the msvcr(t) part has been replaced by vcruntime (or at least this is the entrypoint, as it was split in smaller logical pieces)
Does this, by any chance, solve the problem github.com/google/protobuf/tree/master/cmake ?
– jokoon
Feb 1 '16 at 10:01
Thank you, it now builds (with the -D_SCL_SECURE_NO_WARNINGS in command line). I already knew the difference between static and dynamic, but I had no idea about that runtime library setting. And actually, the google protobuf doc states that it's advised to use the static version, not the dynamic version: github.com/google/protobuf/tree/master/…
– jokoon
Feb 1 '16 at 10:11
Glad to hear it works. I just read the comments on the link you provided. Now regarding your previous question, if it's about the template export at the end, then I don't think it does.
– CristiFati
Feb 1 '16 at 10:19
Question: Can I build a static library that uses dynamic runtime and the other way around?
– Lennart Rolland
Nov 12 '18 at 10:56
1
Yes. By default the way libprotobuf is built dictates the way VCRTLib is used. Build types are controlled by 2 flags. Here's how i built the static libprotobuf version using dynamic VCRTLib-Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF. I should add this piece of info into the answer.
– CristiFati
Nov 12 '18 at 11:06
add a comment |
It's a mismatch of how the VStudio C (and C++) Runtime Library (VCRTLib - 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 code. The purpose of that code is to be run. Than can be achieved:
- Directly: including that code in an VC Application type project - which will generate an .exe
- Indirectly: including the code in an VC Library type project - which will generate a library which will only be able to run when called from another .exe (that calls that library). The library can be:
static: all the C code will be compiled and stored in a .lib file. You will need that file when using the library in another project (whether it's an application or a library) - at link time. Note that all the needed code from your .lib will be "copied" into the other project
dynamic: you will have 2 files now: a .dll file which will contain the compiled (and linked) code, and a .lib file1 which will contain "pointers" (if you will) to the code in the .dll file. When using the library in another project, you will also need the .lib file at link time, but now it won't contain the code so it won't be copied in the other library (the other library will be smaller), but at runtime the other library will need the .dll file
You can check [SO]: LNK2005 Error in CLR Windows Form (@CristiFati's answer) for details of how 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 Ux's libc.a (static or archive) vs. libc.so (dynamic or shared object) - but in VStudio it's a little bit more complicated:
- Static CRT resides in libcmt.lib
- Dynamic CRT resides in msvcrt.lib which "points" to msvcr###.dll2 (msvcr120.dll for VStudio 2013)
Notes:
- A "d" at the end of the library name (msvcrd.lib), means that it's compiled with debug symbols
C++ runtime library is under the exact situation; the names have an extra p: libcpmt.lib, msvcprt.lib, msvcp120.dll
- For more details, check [MS.Docs]: CRT Library Features
Now, VCRTLib 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:
- Multi-threaded (/MT)
- Multi-threaded Debug (/MTd)
- Multi-threaded DLL (/MD)
- Multi-threaded Debug DLL (/MDd)
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 VCRTLib.
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 VCRTLib).
Note: Not to mistake VCRTLib 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).
@EDIT0:
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:
Library type (the way it is being built): dynamic / static
VCRTLib type (the way it uses VCRTLib): again, dynamic / static
So, there are 4 perfectly valid combinations:
- Dynamic library using dynamic VCRTLib
- Dynamic library using static VCRTLib
- Static library using dynamic VCRTLib
- Static library using static VCRTLib
For libprotobuf, each of the aspects is controlled by a boolean cmake option:
- Library type: protobuf_BUILD_SHARED_LIBS
VCRTLib type: protobuf_MSVC_STATIC_RUNTIME
The 2 flags can be set by either:
- cmake-gui
cmake cmdline (passing them as arguments - e.g.:-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 VCRTLib), 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 2015), the msvcr(t) part has been replaced by vcruntime (or at least this is the entrypoint, as it was split in smaller logical pieces)
It's a mismatch of how the VStudio C (and C++) Runtime Library (VCRTLib - 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 code. The purpose of that code is to be run. Than can be achieved:
- Directly: including that code in an VC Application type project - which will generate an .exe
- Indirectly: including the code in an VC Library type project - which will generate a library which will only be able to run when called from another .exe (that calls that library). The library can be:
static: all the C code will be compiled and stored in a .lib file. You will need that file when using the library in another project (whether it's an application or a library) - at link time. Note that all the needed code from your .lib will be "copied" into the other project
dynamic: you will have 2 files now: a .dll file which will contain the compiled (and linked) code, and a .lib file1 which will contain "pointers" (if you will) to the code in the .dll file. When using the library in another project, you will also need the .lib file at link time, but now it won't contain the code so it won't be copied in the other library (the other library will be smaller), but at runtime the other library will need the .dll file
You can check [SO]: LNK2005 Error in CLR Windows Form (@CristiFati's answer) for details of how 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 Ux's libc.a (static or archive) vs. libc.so (dynamic or shared object) - but in VStudio it's a little bit more complicated:
- Static CRT resides in libcmt.lib
- Dynamic CRT resides in msvcrt.lib which "points" to msvcr###.dll2 (msvcr120.dll for VStudio 2013)
Notes:
- A "d" at the end of the library name (msvcrd.lib), means that it's compiled with debug symbols
C++ runtime library is under the exact situation; the names have an extra p: libcpmt.lib, msvcprt.lib, msvcp120.dll
- For more details, check [MS.Docs]: CRT Library Features
Now, VCRTLib 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:
- Multi-threaded (/MT)
- Multi-threaded Debug (/MTd)
- Multi-threaded DLL (/MD)
- Multi-threaded Debug DLL (/MDd)
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 VCRTLib.
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 VCRTLib).
Note: Not to mistake VCRTLib 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).
@EDIT0:
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:
Library type (the way it is being built): dynamic / static
VCRTLib type (the way it uses VCRTLib): again, dynamic / static
So, there are 4 perfectly valid combinations:
- Dynamic library using dynamic VCRTLib
- Dynamic library using static VCRTLib
- Static library using dynamic VCRTLib
- Static library using static VCRTLib
For libprotobuf, each of the aspects is controlled by a boolean cmake option:
- Library type: protobuf_BUILD_SHARED_LIBS
VCRTLib type: protobuf_MSVC_STATIC_RUNTIME
The 2 flags can be set by either:
- cmake-gui
cmake cmdline (passing them as arguments - e.g.:-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 VCRTLib), 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 2015), the msvcr(t) part has been replaced by vcruntime (or at least this is the entrypoint, as it was split in smaller logical pieces)
edited Feb 14 at 1:42
answered Jan 31 '16 at 19:31
CristiFatiCristiFati
13.8k72436
13.8k72436
Does this, by any chance, solve the problem github.com/google/protobuf/tree/master/cmake ?
– jokoon
Feb 1 '16 at 10:01
Thank you, it now builds (with the -D_SCL_SECURE_NO_WARNINGS in command line). I already knew the difference between static and dynamic, but I had no idea about that runtime library setting. And actually, the google protobuf doc states that it's advised to use the static version, not the dynamic version: github.com/google/protobuf/tree/master/…
– jokoon
Feb 1 '16 at 10:11
Glad to hear it works. I just read the comments on the link you provided. Now regarding your previous question, if it's about the template export at the end, then I don't think it does.
– CristiFati
Feb 1 '16 at 10:19
Question: Can I build a static library that uses dynamic runtime and the other way around?
– Lennart Rolland
Nov 12 '18 at 10:56
1
Yes. By default the way libprotobuf is built dictates the way VCRTLib is used. Build types are controlled by 2 flags. Here's how i built the static libprotobuf version using dynamic VCRTLib-Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF. I should add this piece of info into the answer.
– CristiFati
Nov 12 '18 at 11:06
add a comment |
Does this, by any chance, solve the problem github.com/google/protobuf/tree/master/cmake ?
– jokoon
Feb 1 '16 at 10:01
Thank you, it now builds (with the -D_SCL_SECURE_NO_WARNINGS in command line). I already knew the difference between static and dynamic, but I had no idea about that runtime library setting. And actually, the google protobuf doc states that it's advised to use the static version, not the dynamic version: github.com/google/protobuf/tree/master/…
– jokoon
Feb 1 '16 at 10:11
Glad to hear it works. I just read the comments on the link you provided. Now regarding your previous question, if it's about the template export at the end, then I don't think it does.
– CristiFati
Feb 1 '16 at 10:19
Question: Can I build a static library that uses dynamic runtime and the other way around?
– Lennart Rolland
Nov 12 '18 at 10:56
1
Yes. By default the way libprotobuf is built dictates the way VCRTLib is used. Build types are controlled by 2 flags. Here's how i built the static libprotobuf version using dynamic VCRTLib-Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF. I should add this piece of info into the answer.
– CristiFati
Nov 12 '18 at 11:06
Does this, by any chance, solve the problem github.com/google/protobuf/tree/master/cmake ?
– jokoon
Feb 1 '16 at 10:01
Does this, by any chance, solve the problem github.com/google/protobuf/tree/master/cmake ?
– jokoon
Feb 1 '16 at 10:01
Thank you, it now builds (with the -D_SCL_SECURE_NO_WARNINGS in command line). I already knew the difference between static and dynamic, but I had no idea about that runtime library setting. And actually, the google protobuf doc states that it's advised to use the static version, not the dynamic version: github.com/google/protobuf/tree/master/…
– jokoon
Feb 1 '16 at 10:11
Thank you, it now builds (with the -D_SCL_SECURE_NO_WARNINGS in command line). I already knew the difference between static and dynamic, but I had no idea about that runtime library setting. And actually, the google protobuf doc states that it's advised to use the static version, not the dynamic version: github.com/google/protobuf/tree/master/…
– jokoon
Feb 1 '16 at 10:11
Glad to hear it works. I just read the comments on the link you provided. Now regarding your previous question, if it's about the template export at the end, then I don't think it does.
– CristiFati
Feb 1 '16 at 10:19
Glad to hear it works. I just read the comments on the link you provided. Now regarding your previous question, if it's about the template export at the end, then I don't think it does.
– CristiFati
Feb 1 '16 at 10:19
Question: Can I build a static library that uses dynamic runtime and the other way around?
– Lennart Rolland
Nov 12 '18 at 10:56
Question: Can I build a static library that uses dynamic runtime and the other way around?
– Lennart Rolland
Nov 12 '18 at 10:56
1
1
Yes. By default the way libprotobuf is built dictates the way VCRTLib is used. Build types are controlled by 2 flags. Here's how i built the static libprotobuf version using dynamic VCRTLib
-Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF. I should add this piece of info into the answer.– CristiFati
Nov 12 '18 at 11:06
Yes. By default the way libprotobuf is built dictates the way VCRTLib is used. Build types are controlled by 2 flags. Here's how i built the static libprotobuf version using dynamic VCRTLib
-Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF. I should add this piece of info into the answer.– CristiFati
Nov 12 '18 at 11:06
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35116437%2ferrors-when-linking-to-protobuf-3-on-ms-visual-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
So, you built
libprotobufstatic version (.lib) using CMake, and now you are trying to link it in your VStudio app?– CristiFati
Jan 31 '16 at 17:20
Yes, I built it with MSVC 2013, and am now linking it to my project, also using MSVC 2013
– jokoon
Jan 31 '16 at 17:22
here is the project file
– jokoon
Jan 31 '16 at 17:30