MSVC17 Linking application with runtime statically, still getting missing dll error - visual-studio

I set /MT flag to have my c++ application statically linked with C runtime, so I don't have to worry about redistributing the runtime, however, upon launch I get an error message saying missing "Api-ms-win-core-version-l1-1-0.dll". How do I compile my application so that its completely independent of any runtime etc?
Build Environment: MSVC 2017, windows 10 SDK
Compile and Test machine: 64-Bit Windows 7

The selected answer here helped me solve my problem. In short, you can't link with any of the api-ms-win-core* libraries, you should link with appropriate libraries listed for APIs in the msdn. The api-ms-win-core* libraries are used indirectly by the OS, that's why they show up as missing - when in reality the appropriate windows .lib need to be linked.
In my case, I used depends to figure out which API libraries were missing then looked up the appropriate .lib files in msdn and added those in "additional dependencies". Problem solved.
FYI, /MT flag is working as expected, I don't have to redistribute c-runtime etc.

Related

Portable installation for windows desktop app compiled with msvc 2015

Recently I switched from mingw to msvc compiler for my Qt app.
I am using Qt5.8. The msvc debugger is from the windows 10 kit (though I develop on Win7 and Win8.1) and the compiler from the vc++2015 build tools.
I can run the app locally, but I can't run it on a different, clean computer.
I know that I have to copy the compiler specific dll's to the application's executable directory. All the other dlls are found by windeployqt. Still I don't get it to work. I can't ship vc_redist packages the user has to install, due to the requirement to be able to load the app from a pendrive. On the dev machine there are several dlls of the same name, how can I figure out which ones are actually used by the compiled app?
Questionable dlls is especially api-ms-win-crt-runtime-l1-1-0.dll.
On the deployment I got those errors:
I also tried Dependency Walker and showed the full paths. I assume the first hierarchy level is the important one, that's why I've hidden deeper hierarchies. I am wondering why the full path shows the dir System32 because isn't this the 64-bit files folder?? I did not target any specific one but my app must be running on x86. Is this a misunderstanding?
EDIT
According to another question and this Microsoft blog update it worked for me when I additionally included all dlls from this folder C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86. There is also a file named ucrtbase.dll. I have no idea why DependencyWalker showed different ones.
You can use tools such as Dependency Walker to see which DLL is used by any other DLL or exe file.
Edit: You can also take a look at Determining Which DLLs to Redistribute on MSDN
Also you could use static linkage to link against the MSVC runtime (i.e use /MT switch instead of /MD (see https://msdn.microsoft.com/en-US/library/2kzt1wy3.aspx). However this would also mean rebuilding Qt, but it would also give you the opportunity to build a static version of Qt, meaning that you would not need to ship any DLL alongside your exe. You can find more info on Qt wiki: Build Standalone Qt Application for Windows

How can I check the LIB file version?

After reinstalling Visual Studio 2010, I recompiled the code and encountered the following error:
Error 'LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt'
A solution mentioned that the lib file is incompatible and I need to install Visual Studio 2010 SP1. I did that, and now it has been solved.
I am wondering how can I check whether a lib file is created by SP1 or not?
I tried dumpbin, but I cannot find the version in its result.
It was not an incompatibility with your LIB file that caused the problem here, so checking the version of the linker that created it would not be a solution anyway.
The issue is that cvtres.exe (used internally by the linker toolchain) depends on a particular DLL (msvcr100_clr0400.dll) shipped with VS 2010 RTM. When you update to a later version of the .NET Framework (e.g., by installing .NET 4.5 or installing a later version of VS), this DLL is replaced. That stops cvtres.exe from working.
The reason why installing VS 2010 SP1 fixes it is because it actually modifies the cvtres.exe application to break the dependency. And now that all pieces of the linker toolchain work, you can compile and link the code without error.
Of course, there are other problems you can have when you start mixing libraries created by different versions of the compiler and/or linker. They aren't guaranteed to create 100% compatible output, so mixing them is not supported (at least not between major versions, I'm uncertain about how this rule applies to service packs).
In general, it's best to just recompile all libraries whenever you update your build system. The only time you wouldn't do this is if you didn't have the source code, in which case, you need to be very careful about updating your build system, lest you introduce gratuitous incompatibilities.
As far as determining the version of the linker that prepared a particular binary, using dumpbin.exe (included with the SDK) is exactly the correct approach. For static libraries, run the following command from the Visual Studio SDK Command Prompt:
dumpbin /rawdata:1 MyLibrary.lib
You'll see the assembly manifest, which will include the full path to the compiler used to build the library as well as the version of the CRT that it depends upon.
For dynamic libraries (i.e., DLLs) and executables, run the following command:
dumpbin /headers MyApp.exe
Look under the "Optional Header Values" section (not actually optional) for the version of the linker, along with a timestamp of when it was generated.
Note that you're very unlikely to find this information in release builds of a library or binary.

Building a correctly linked executable to avoid error 0xc000007b

I am building a 32-bit executable with VS 2012's default build settings. It works correctly on one 64-bit computer (development machine); on another 64-bit computer, the program crashes with error 0xc000007b.
A bit of study and using a dependency walker indicates the problem is that the executable is loading 64-bit dlls rather than 32-bit dlls.
I am reasonably sure that this is solvable by configuring the build to statically link required code rather than calling out to the DLLs.
1). Is this solution a reasonably correct and portable solution?
2). How do I configure VS 2012 to link statically as above?
N.b: this is a C++ native program.
While this is not per se the answer to the "reasonably correct and portable" question #1 above, the answer to #2 I found from How do I make a fully statically linked .exe with Visual Studio Express 2005?. If the compiler /MD option is changed to /MT, it switches from linking in the DLL to linking it in statically and the problem goes away[1].
[1]. Just because the problem goes away doesn't mean it's solved.

remove dependency on CRT in dll

I'm building a dll on Visual Studio 2010, and I'm using some simple C functions like fprintf and fread, and it's linking to msvcr100.dll by default.
This dll is going to be loaded into an app that may be using a different CRT version (eg. msvcr90.dll, msvcrt.dll).
Since I know the app's going to load a CRT before my dll gets loaded, can I remove the dependency on msvcr100.dll and use the C functions in the CRT loaded by the app?
In the end, I decided to build the DLL against the lowest common denominator CRT version used by the target app, msvcr90.dll.
I did this by using the MSVC toolchain, available with Visual C++ 2008 Express (free).
I did try the mingw/gcc toolchain, which allows you to specify which CRT version to link against (see mingw-rt and gcc -specs=msvcr**), however, msvcr90.dll is a new-style SxS assembly so I couldn't get the produced executable to run properly.
It may be worth considering skipping linking against msvcr**.dll entirely; see this post and VC/include/delayhlp.cpp.

Which runtime libraries to ship?

I work on C/C++ using Visual Studio 2008. I believe that I am not concerned about which runtime libraries are being used by my code as I have the developer setup. But when the executable is shipped, the runtime libraries being used need to be shipped alongwith. Am I right?
If yes, how can I identify which shared libraries are actually getting used? Or are there any libraries that we can ship without having to know this?
You're correct, you need to ship a version of the C runtime libraries that matches the version you linked your application against. If you're compiling with Visual Studio 2008, then you want to use the Microsoft Visual C++ 2008 Redistributable Package. As other folks mentioned, you can inspect your application's manifest file to see exactly which version of the C runtime libraries it's linked against.
Before shipping, it's always best to install your product on a clean (i.e., non-developer) virtual machine and run Microsoft's Dependency Walker utility to verify that your application uses the correct C runtime libraries.
you need to ship dll files with you.
you can guess most of them and for the rest you can use a program "Dependency Walker" which shows you dependencies of the executable.
Look at the generated manifest file to see which version of the CRT you need to ship with. It's possible to change which version of the CRT you link to as seen here but it doesn't seem to be recommended.

Resources