Should i use MinGW for C++/CMake project to minimize dependencies of MS's DLLs? - c++

When i use Visual Studio, my executables depends on microsoft redistributable package - the package that deploys MS's runtime DLLs. That is annoying to me. What disatwantages my executable would have if i would use MinGW?
I also want to try link with lib- avcodec/avformat, that are built by MinGW and i have no my own mind power to build them in VS from src.

In case of using MinGW you will depend on DLLs that are shipped with mingw. It is not big deal to change one vendor to another.
If you already have MS project, review possibility to statically link MS libraries (it is option is provided for some of VisualStudio projects on creation time in project options)

You can link everything statically with MinGW. Use the -static linker flag.
No need for redistributing any DLL's, but you have to make sure that in the c++, there's no exceptions being passed over DLL boundaries (so make sure every C++ library is linked statically in this case).

Related

Building a static lib without C/C++ runtime in Visual Studio

Is there a way to build a static library without specifying the version of C/C++ runtime?
I'm using Visual Studio 2017 to build a static lib, and I have to specify a version for "Runtime Library" in the "Code Generation" option page (\MD or \MT). If I choose one version and the application using my lib chooses another, Visual Studio will spit out the error: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease'.
I know, when building an EXE, I can use the linker switch \NODEFAULTLIB to not include C/C++ runtime, but I'm building a static lib here which doesn't even have the Linker option page in its Properties window.
It seems that Simple DirectMedia Layer found a way to do.
Update: I later realized that I could actually turn on \NODEFAULTLIB switch in the Librarian option page in the static lib's Properties window.
You do it by NOT using any Runtime libraries. If you don't use any of the runtime libraries then the "Code Generation" option is meaningless as the runtime stubs are not pulled into obj file.
SDL basically say this on there web site:
On Windows, SDL does not depend on a C runtime at all, not even for
malloc().
As soon as you use any system include supplied by Microsoft VS then you are using there runtime library.
So if you only use the Windows SDK and the API supplied by the Win32 API then you don't need the VC runtime.
If you build a static library, it refers to your own library and not to the application as a whole. If you want to distribute the application, it just means that you will not need to distribute a separate dll. So do not set NODEFAULTLIB.
If you run the application on a machine where there is no Visual Studio 2017 installed, you might get an error message. The missing dlls are system libraries that are needed to run vs applications that are compiled with VS2017. You can get the missing libraries from: https://support.microsoft.com/en-gb/help/2977003/the-latest-supported-visual-c-downloads (this link is not guaranteed to be correct in the future). The redistributable dlls can be distributed freely. They are called vc_redist.x86.exe and vc_redist.x64.exe. Choose vc_redist.x86.exe if you have compiled you code for 32-bits. It does not refer to the machine on which the app is run.

Statically linking Visual Studio dlls to dynamically linked sfml project

I have an SFML, Visual Studio project that needs to be linked using the /MT option in the runtime library settings because I want to avoid having to install the microsoft redistributable to every computer that runs the program.
When I added sfml to the project, it appeared to work fine in its dynamic form. However, when I tried the program on another computer, it told me that I had missing visual studio dlls.
I understand that in order to link sfml statically to the project I would have to rebuild it with different runtime libraries. My question is why would it be able to correctly compile with sfml dynamically linked to the project and have the project set to /MT at the same time if it failed to statically link the necessary visual studio dlls to the project?
After discussions in the comments, we agreed on this:
It is not uncommon to link some libraries statically and still link dynamically to others, like the language runtime. So the compiler should not complain about this.
To get a single executable containing everything, the program must link all libraries statically and they must, in turn, also link statically to all their dependencies.
Otherwise, if we have one dynamic library, like SFML, that library will likely in turn link dynamically to the runtime library. And that will still require the runtime DLLs.
This is possible, you'll just have to build SFML yourself (which isn't that hard to do).
Just make sure that you set the CMake variable SFML_USE_STATIC_STD_LIBS to TRUE so SFML uses the static runtime, no matter whether you're actually creating static or shared libraries.
In short:
Clone the official repository.
Install CMake. (If you're using Visual Studio 2017, you can also directly open the source directory as a Folder, but setting the variables is a bit more tricky this way.)
Create a build directory, go there and run CMake: cmake -DSFML_USE_STATIC_STD_LIBS=TRUE -DCMAKE_INSTALL_PREFIX=C:/path/where/to/install/SFML C:/path/to/the/cloned/source/repository
Once done you'll find a Visual Studio solution and projects.
Just build the INSTALL project for the Debug/Release targets and you'll get your shared SFML using the static runtime.

I cant link against opengl32 in Windows

I am working on porting an app of mine that I made in OS X to Windows 10. I'm using visual studio 2015 Community Edition.
To get the project running, I need to link against GLFW and, in Windows as I understand, GLEW, since I am targeting GL 4.5.
So I have the glfw and glew libs. I also use Cygwin so I have the libs installed in usr/local/(bin | lib | include) to mimic the folder structure I'd use in OS X for these libs.
The issue I'm having is with the opengl lib itself.
Until yesterday, I had managed to get my project compiling and initializing the glfw window with the following visual studio settings:
Project->Properties-> :
C++->General:
Additional Include Directories:
C:\cygwin64\usr\local\include
Linker->General:
Additional Library Directories:
C:\cygwin64\usr\local\lib
C:\cygwin64\usr\local\bin
Linker->Input:
opengl32.dll
glew32s.lib
glfw3.lib
The first thing to notice is that I was linking against opengl32.dll, not .lib. I saw a bunch of questions / posts online that state that when you install Windows SDK you have a opengl32.lib in Program Files/Microsoft SDKs/Windows (x86 or otherwise). This is not the case for me. I have even reinstalled the Windows 10 SDK and it does not install any opengl lib, static nor dynamic, anywhere.
So I'm pretty sure that my opengl dll was coming from Windows/System32 because that is the only place in the whole machine where there is any sort of opengl lib.
Which makes me think I might have also had C:\Windows\System32 in the linker's additional library directories section. I say makes me think, because I had set this up with a lot of struggle about a week ago. Since then I was able to develop just fine.
Last night all I did was commit my work to a git branch, switch to another branch and merge to that branch. After the merge, all Visual Studio linker/C++ settings were wiped. So I had to recreate them, as I showed above.
Now what happens is that if I include C:\Windows\System32 and the opengl32.dll VS spits out:
LNK1107 invalid or corrupt file: cannot read at 0x2E0 OpenVRTest C:\Windows\System32\opengl32.dll
And if I don't include it obviously half the stuff in glfw is unresolved.
Any hints as to how to get this working again?
It makes no sense to me... It was working just fine and it has to have been working fine with this opengl32.dll
Also as a side note, I'm not sure why people insist that installing the Windows SDK installs a static version of the gl lib; at least it does not for me.
Linker->Input:
opengl32.dll
glew32s.lib
glfw3.lib
That opengl32.dll is wrong. In Windows development the linker always takes .lib files. In case of static libraries the .lib contains the actual library binary. In case of DLLs the corresponding .lib informs the linker about which DLL to use and which symbols it offers.
The main reason for this particular choice of how things are to be done was, that in Windows development it shall be possible to link against a DLL without having the actual DLL around.
Also system libraries always are suffixed …32 even on 64 bit systems.
The issue was that among the VS configuration settings that got wiped, were a couple things related to x86 vs x64 platform settings. So the project was now trying to build for 64bit linking against the 32bit dll in System32.
So that's that.
A separate issue is why a lot of answers speak of an opengl32.lib (static) that theoretically comes with the Windows SDK but I have not seen it anywhere. I just link against the dynamic one.

C++ executable - MSVCR100.dll not found error

I've downloaded and compiled an open-source C++ application, Frhed.
When I run the version I've compiled, it demands MSVCR100 and few other dll files (part of Visual C++ redistributable). However, when I run the original precompiled Frhed executable, it runs without any C++ redistributable package installed.
Do I have to modify any compilation options in order to unlink the program from the C++ redistributable libraries?
The original program is probably statically linked, whereas you are trying to dynamically link your executable, which results in a smaller file, but a dependency on functions inside MSVCR100.dll (v10 of the Microsoft C Runtime Library), which would have been included inside the executable if you were statically linking.
To statically link DLLs, go into your project properties and change the build mode from MD to MT. In Visual Studio 2010/2012, that project property is C/C++ -> Code Generation -> Runtime Library.
The short answer is yes, the longer answer is, well, longer.
The library msvcr100.dll is the 10.0 version (i.e., Visual Studio 2010 version) of the DLL implementation of the C run-time which you probably requested by using the /MD compile option. To avoid using the dynamically linked version of the run-time you can use the /MT option instead and statically link the run-time.
Alternatively, you can redistribute msvcr100.dll (and other files) along with your program.

How do you pack a visual studio c++ project for release?

I'm wondering how to make a release build that includes all necessary dll files into the .exe so the program can be run on a non-development machine without it having to install the microsoft redistributable on the target machine.
Without doing this you get the error message that the application configuration is not correct and to reinstall.
Choose Project -> Properties
Select Configuration -> General
In the box for how you should link MFC, choose to statically link it.
Choose Linker -> Input. Under Additional Dependencies, add any libraries you need your app to statically link in.
You need to set the run-time library (Under C/C++ -> Code Generation) for ALL projects to static linkage, which correlates to the following default building configurations:
Multithreaded Debug/Release
Singlethreaded Debug/Release
As opposed to the "DLL" versions of those libraries.
Even if you do that, depending on the libraries you're using, you might have to install a Merge Module/framework/etc. It depends on whether static LIB versions of your dependencies are available.
Be aware that Microsoft do not recommend that you static link the runtime into your project, as this prevents it from being serviced by windows update to fix critical security bugs. There are also potential problems if you are passing memory between your main .exe and .dll files as if each of these static links the runtime you can end up with malloc/free mismatch problems.
You can include the DLLs with the executable, without compiling them into the .exe and without running the redist tool - this is what I do and it seems to work fine.
The only fly in the ointment is that you need to include the files twice if you're distributing for a wide range of Windows versions - newer OSs need the files in manifest-defined directories, and older ones want all the files in the program directory.
You'd be looking to static link (as opposed to dynamically link)
I'm not sure how many of the MS redistributables statically link in.
If you are looking to find out which dll's your target machine is missing then use depends.exe which used to come with MSDev, but can also be found here. Testing this on a few target machines should tell you which dll's you need to package with your application.
You should use a static link and add all libraries you need under additional dependencies.