Is /nodefaultlib:msvcr100 the proper approach to handling msvcr100.dll vs msvcr100d.dll defaultlib issue - visual-c++

For a cross-platform software project that builds on Linux and Windows we have distinct ways to handle third-party libraries. On Linux we build and link against the versions distributed with the CentOS/RHEL distribution, which means we link against release builds, whereas on Windows we maintain our own third-party library "packages" and on Windows we build two versions of every library - a release version that links msvcr100 and msvcp100 and a debug version that links msvcr100d and msvcp100d.
My question is simply whether it is necessary to build the debug version of the third-party dependencies on Windows or can we simply use /nodefaultlib:msvcr100 when building debug builds of our own software.
A follow up question: Where can I learn about good practices in this regard. I've read the MSDN pages about the msvc runtime, but there is very little there in terms of recommendations.
EDIT:
Let me rephrase the question more concisely. With VS2010, what is the problem with using /nodefaultlib:msvcr100 to link an executable build with /MDd when linking with libraries that are compiled with /MD.
My motivation for this is to avoid to have to build both release and debug version of third party libraries that I use. Also I want my debug build to run faster.
From the document for /MD, /MT, /LD (Use Run-Time Library):
MD: Causes your application to use the multithread- and DLL-specific version of the run-time library. Defines _MT and _DLL and causes the compiler to place the library name MSVCRT.lib into the .obj file.
Applications compiled with this option are statically linked to MSVCRT.lib. This library provides a layer of code that allows the linker to resolve external references. The actual working code is contained in MSVCR100.DLL, which must be available at run time to applications linked with MSVCRT.lib
/MDd: Defines _DEBUG, _MT, and _DLL and causes your application to use the debug multithread- and DLL-specific version of the run-time library. It also causes the compiler to place the library name MSVCRTD.lib into the .obj file.
So there is no documentation for any difference done to the generated code other than _DEBUG being defined.

You only use the Debug build of the CRT to debug your app. It contains lots of asserts to help you catch mistakes in your code. You never ship the debug build of your project, always the Release build. Nor can you, the license forbids shipping msvcr100d.dll. So building your project correctly automatically avoids the dependency on the debug version of the CRT.
The /nodefaultlib linker option was intended to allow linking your program with a custom CRT implementation. Quite rare but some programmers care a lot about building small programs and the standard CRT isn't exactly small.
Some programmers use the /nodefaultlib has a hack around a link problem. Induced when they link code that was built with Debug configuration settings with code built with Release configuration settings. Or link code that has incompatible CRT choices, /MD vs /MT. This can work, no guarantee, but of course only sweeps the real problem under the floor mat.
So no, it is not the proper choice, fixing the core problem should be your goal. Ensure that all your .obj and .lib files are built with the same compiler options and you won't have this problem. If that means that you have to pester a library owner for a proper build then pester first, hack around it only when you've discovered that you don't want to have a dependency on that .lib anymore but don't yet have the time to find an alternative.

Related

Changing compiler from MSVC to clangCL

We have a project, that has lots of dependencies - third party libraries. We get the source code and build them ourselves. Currently we are using MSVC compiler, but looking into transitioning to using clang-cl (so the one installed through Visual Studio installer). We use CMake to generate build files.
I tried rebuilding just the project with clang-cl, but got linking errors (did not find functions of third party libraries). So I imagine ABIs are not compatible. Do I need to rebuild all the libs with clang-cl, Or is there another way? I tried the solution to call vcvarsall.bat like explained on https://clang.llvm.org/docs/UsersManual.html#clang-cl, but got the same linking errors.
What I am basically looking is your experience regarding changing compiler used to build a project.

Under what circumstances on Windows can non-incremental linking result in a thrown exception, while incremental linking does not?

I have read that incremental linking and non-incremental linking should be functionally equivalent, but I have recently found a situation where this is not the case, and it's kind of baffling me. It that out that my project's build is unable to explicitly load one DLL (out of many) that contains a wxWidgets GUI element during runtime without incremental linking (/INCREMENTAL) enabled.
To give a little context, I have the following targets built by my project:
main.exe
core.dll
foo.dll
bar.dll
core.dll contains general functions that are used by all other projects. main.exe is a desktop GUI application (using wxWidgets) that explicitly loads foo.dll and bar.dll at runtime via "LoadLibraryW". "GetProcAddress" is then used to request GUI elements from within the DLLs to be displayed, which is all done asynchronously via wxEvent. This has worked as intended for the most part. However, I have found that an issue arises when the main.exe is not incrementally linked.
Specifically, when main.exe is not linked with a core.dll that was linked with /INCREMENTAL, and when my project is implicitly linked to the release build of wxWidgets (which is not incrementally linked), foo.dll crashes at runtime on allocation of a new wxPropertyGrid, or wxPropertyGridManager (have tried both). The exception is thrown within "wxmsw30u_propgrid_vc_x64_custom.dll", which is clearly the property grid DLL. Since the debug version of wxWidgets is incrementally linked and does not crash, I was unable to get further information than this.
That is to say, when using the Release DLL version of wxWidgets, my project works if and only if a core.dll is linked with /INCREMENTAL and then linked into main.exe, regardless of whether or not main.exe is linked incrementally. foo.dll can be linked with a core.dll that was linked with /INCREMENTAL:NO and still be opened correctly by main.exe so long as that condition is satisfied. There are no problems with the Debug DLL version of wxWidgets, which is built with /INCREMENTAL.
That summarizes my specific problem. Since the actual code spans several files long, I've decided to reduce this question to the fundamental problem: how could incremental linking enable what I presume to be a faulty build to run successfully? I'd like some insight into this question in particular since it is truly baffling to me.
EDIT: Specifically, I am using wxWidgets-3.0.4 on Visual Studio 2019 targeting the latest Windows 10 SDK. The machine architecture is x64. I am building the project with CMake and have experienced no such issues on Linux when linking with g++-6.3.0 and using dllopen in place of LoadLibraryW.

Mingw-w64, what's the purpose of libgcc_s_seh.dll?

Libraries built with Mingw-w64 require those dll:
libwinpthread-1.dll
libstdc++-6.dll
libgcc_s_seh-1.dll
I wonder what's up with that, what each dll does? Especially libgcc_s_seh, is that structured exception handling? I thought mingw couldn't work with seh.
Why mingw requires to always bring those dll with your exe?
I wonder if I'm just wasting my time by not just using visual studio as a windows compiler. It's so bloated though, 9 gb for installation.
Especially libgcc_s_seh, is that structured exception handling? I thought mingw couldn't work with seh.
Newer versions of GCC (4.8+ if I'm correct) should support SEH on MinGW.
I wonder what's up with that, what each dll does?
They provide the runtime and standard library.
libwinpthread: PThreads implementation on Windows (Threading)
libstdc++: C++ Standard Library (C/C++ library functions etc.)
libgcc_s_seh: Exception handling (SEH)
Why mingw requires to always bring those dll with your exe?
Because your program uses them. If you write a program without threads, standard library and exception and any OS interaction you wont need them.
These DLL's bring everything you need to run your program. Btw. this is not a MinGW only thing, and happens on other systems / compilers too. Often you just don't note this because the OS already ships the libraries, eg. MSVC libraries are very likely on a Windows machine. Dynamic linking always requires some sort of library files, that are .dll on Windows and .so on Linux.
If you have it available on your system use ldd <your application> to see what libraries are dynamically linked.
You can install these MinGW libraries into the system libraries or somewhere where the OS can find it. This enables your programs to use it and you no longer have to ship it with every application (what avoids duplication).
On the other side another option is to static link them. Unlike dynamic linking, you don't need any DLL; on the downside is a increase of you applications size (as now the three libraries are baked into the exe now).
I wonder if I'm just wasting my time by not just using visual studio as a windows compiler.
This depends on your situation. But probably my answer will give you some more insight.

Build MinGW Console application without CRT?

I can build apps with MSVC without the CRT as directed here:
http://www.mvps.org/user32/nocrt.html
But how can this be done with MinGW? It seems to always pull in the CRT (msvcrt.dll) by default.
Edit: To be clear I'm trying to NOT link the CRT at ALL, not statically link it which I know isn't possible due to copyright issues.

Linker warning C++ Visual Studio

I have run into this problem, which although is a warning, I suspect is a sign of something wrong under the hood. When I build in release mode I get this warning:
MSVCRT.lib(cinitexe.obj) : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
I'm building a dynamic DLL in Visual Studio C++ Express Edition. When I do it in debug mode no warning arises. I've googled a bit and it looks like msvcrt and msvcrtd are both for multithreading, one for debugging and the other not. I could use /NODEFAULTLIB with MSVCRT.lib, but I don't think that avoiding symptoms really helps with the problem.
I really don't know if this is a huge problem. The DLL and .lib files are generated correctly.
Check that your runtime library settings are correct in the Release configuration of your project. Basically it should be the same as your Debug build, but without the word 'Debug' in the description. Visual Studio docs on this issue are here.
Check your settings as follows:
in Solution Explorer right click the Project and select Properties
make sure the Configuration (at the top of the Properties window) is Active (Release)
go to Configuration Properties -> C/C++ -> Code Generation
check that Runtime Library for Release is not a Debug version of the CRT.
The problem is related to your libraries.
They are linked differently than your program.
Your program may be single-threaded, while your libraries may be linked as multithreaded, for example.
Look under
Project Properties
Configuration Properties
C/C++
Code Generation
Runtime Library
to see the setting (e.g. "Multi-threaded Debug DLL (/MDd)").
This is a huge problem, since it can lead to many unexpected crashes of your application, AND you can't distribute an application which links msvcrtd.lib, since you are not allowed to distribute the debug C++ runtimes of Visual Studio.
Though /NODEFAULTLIB should fix those, you should fix the issue itself.
Like casablanca said, msvcrtd.lib is linked in release mode, but it should only be linked in debug mode.
This does not mean that your own application has wrong linker settings. Any of the libraries you use in your project could have incorrect settings as well.
What I usually do to fix this is, to open all the release .lib files which your application links, with a text editor which can open such large binary files (like SciTE), and then I search them for e.g. VC80.DebugCRT (VC80 == Visual Studio 2005 in this case), and if I find this string in one of those libraries, that library should be recompiled with /MD.
If you are linking dynamic libraries, you can use a tool called Dependency Walker on the .dll files instead of manually searching the .lib files.
If Dependency Walker shows the dependency on one of the debug crt DLL files like e.g. MSVCP80D.dll (note the trailing D), recompile that library using /MD.

Resources