I made some games with Visual C++ 2015 and OpenGL. When I ran it on my machine there was no problem, but when I ran it on other machines it shows that some DLLs are missing. I want to know how to make sure that it won't happen next time and what things should I consider so that I can avoid file missing problems?
You need to install the redistributables for the version of Visual Studio you used on any machine that wants to run the executables, e.g. https://www.microsoft.com/en-us/download/details.aspx?id=48145 for VS2015. You may also need redists for DirectX or other components.
Applications' installers generally install all the redistributables for any of their dependencies. You can make such an installer with InnoSetup, NSIS, WIX, or various other tools.
It's possible to make executables that don't need any redistributables, but you're then limited to a subset of core Windows functionality, which generally is not enough to make any kind of meaningful game or large application. The installers themselves are an example of applications that don't need any dependencies to run.
I use Dependency Walker to track down missing DLL's:
Dependency Walker is also very useful for troubleshooting system errors related to loading and executing modules. Dependency Walker detects many common application problems such as missing modules, invalid modules, import/export mismatches, circular dependency errors, mismatched machine types of modules, and module initialization failures.
There is also a compile-time option in VS to statically link DLL's:
- Statically linking means the DLL's are included in the EXE file.
- Statically linking increases the size of the EXE file.
- Statically linking means this version of the DLL will always be used.
- However, statically linking also means you will never have a problem with missing DLL's.
For Visual C++, you have a few choices of how to handle the redistribution: run an EXE from your installer (with admin rights), use a MSM merge module with your MSI installer, or even side-by-side DLLs. See MSDN for the details.
The bigger issue is OpenGL. The only version of OpenGL that's included with Windows is a OpenGL 1.5 software renderer. Anything else requires a third party ICD to be installed.
Disclaimer: This is a workaround, not a solution to your answer, but still, a very viable possibility.
If you want to be absolutely sure there are no dependencies from VS itself - but it comes with its own drawbacks - in the code generation settings you can choose to go with Multi Threaded (MT) / Multi Threaded Debug (MD) (for debug builds) instead of MT DLL (MTd) / MT Debug DLL (MDd).
What are the drawbacks?
- It does increase your executable size and your binary (although if you are making a game this is probably negligible)
- compiled in this way won't benefit from the runtime dlls updates. (e.g. if Microsoft releases VC++ 2015 SP2, SP3, SP4 etc..) But that's up to you.
- More RAM usage (also negligible) because you don't re-use existing/loaded code (DLLs)
- You need to be sure all libraries you link are compiled against the same runtime, else linking might fail, or interesting runtime errors might occur (probably not, but it did happen to me once in a lifetime in a legacy project that has been updated to the newest VS)
And what are the pros?
- your executable won't have "external" dependencies from VS itself (no msvc*.dll requirement).
- some people see this as a performance increase because you are eliminating DLL call overhead, while this is theoretically true, the improvements are negligible in practice
Check this link for a more elaborate explanation and for the pit- and downfalls you might encounter with using a static runtime.
Another workaround would be to put all the required DLL's where your binary is. Your application won't benefit from updates (to the runtime libraries) but that's it.
The real solution is to distribute the application in release/non debug dll mode (MTd) and supply the correct VC++ redistributable installer (and any other library installers that you might use, e.g. OpenAL, DirectX9, PhysX), and let the user run that before running your application (as other answers pointed out).
Also make sure to let the user know he/she possibly needs to update his/her GPU drivers (as those contain multiple runtimes for many applications too, e.g. OpenGL, Vulcan).
My solution was to copy and paste the DLL that caused the error into the folder where the .sln file is located in visual studio. After the
#include section, I wrote
#pragma comment (lib, "lost DLL name with .dll") and resolved it!
Note: I solved the problem that I encountered with a third party library (vulkan api) DLL. Maybe it's not known but 90% will work good luck :)