I've spent some time troubleshooting missing DLL problems and I have some questions as well as some experiences to share.
Point 1. First of all, when you don't have the right dlls on your system, you get an error like "allegro-5-monolith.dll not found". Then you copy that dll into your game.exe directory and all is well.
But I noticed that the error you get is not always the same. Sometimes the error looks more like this:
Error: the application was unable to start correctly (0xc0000142)
Which was something that threw me off. But it turned out that also in this case the solution was to add a missing dll. Why is the error sometimes explicit about which dll is missing, and sometimes so cryptic?
Point 2. (This is more a tip than a question) Adding DLLs one by one gets tedious. I was looking for a way to scan for all dependencies. The ldd command is available with MSYS2, but for me it only shows the resolved dlls. I.e. it shows the location of the dlls it uses, but it doesn't help you find missing dlls. And on the system where I compiled things, it didn't resolve those dlls so I didn't even have one working example to start from. So ldd appears to be rather useless for this task.
$ ldd mexica.exe ntdll.dll => /c/windows/SYSTEM32/ntdll.dll (0x77130000) kernel32.dll => /c/windows/system32/kernel32.dll (0x76f10000) KERNELBASE.dll => /c/windows/system32/KERNELBASE.dll
After some trial an error I settled upon the following method. I created a script named gather-dlls.sh, and repeatedly run it on windows from msys2.
First it tries to copy a set of dlls from various locations, and then it checks the list (with objdump -p) for dependencies. If a dll is missing, edit the list of copy commands, and repeat. If a newly copied dll has more dependencies, then they will show up as missing on the next invocation.
Sample output:
If you have any suggestions on better ways to do this then please let me know.
Point 3: So my final question is, do I need to include the system dlls? The previous code snippet is exactly how I'm now bundling my game, e.g. libvorbis-0.dll included, but USER32.dll not. I've included everything that is part of msys2, and excluded everything that is the windows system directory. Is that generally the thing to do? Can I expect e.g. msvcrt.dll to be present on every Windows installation out there?
amarillion,
There is a much easier way to find out which dlls your program depends on. Use Dependency Walker. It will tell you exactly which dlls it needs.
Point 2 - Remember Windows can load DLLs at runtime using LoadLibrary and others. That's why you need DependencyWalker as Edgar suggests, in the general case. I can't remember whether Allegro does or doesn't load DLLs at run-time, it seems to be something that happens for OpenGL quite a bit.
Point 3 - You can rely on User32 being there. MSVCRT (or whatever it's called this week) will probably be there but it's versioned and the user may not have the same version as you. The correct version that you used is installed as a 'redistributable' somewhere in your SDK directory so strictly you should bundle it with your program (or use the merge module in your installer if you're being fancy)
MSVCRT.DLL which mingw compiled .exes depend on is not versioned I think, only MSVCRT100.DLL and so on which MSVC compiled .exes depend on.
I don't think DependencyWalker knows anything about DLLs loaded at runtime - it will have the same information as objdump only.
Dependecy Walker has a profile mode which you use for detecting DLLs that are run-time linked.
I'm trying dependency walker too and it's a handy tool. My ultimate goal is to check the compiled binaries automatically on a CI server. I see that dependency walker can work as a command-line utility too, so I will experiment with that.
I'm still not completely clear exactly which dependencies I can assume to be there. Elias is right in that I'm compiling with Mingw so I don't depend on any versioned msvc libraries. I'm currently taking this list for granted:
I haven't noticed any problems with run-time DLL loading yet.