On Windows, when we try to import a .pyd
file, and a DLL that the .pyd
depends on cannot be found, we get this traceback:
Traceback (most recent call last):
...
ImportError: DLL load failed: The specified module could not be found.
When this happens, often one has to resort to a graphical tool like Dependencies to figure out what is the name of the missing module.
How can I obtain the missing module name via the command-line?
Context: often we get this error in CI, and it would be easier to login via SSH to find out the missing module name, rather than having to log via GUI.
First, let's chose a concrete example: NumPy's _multiarray_umath*.pyd (from Python 3.9 (pc064)). Note that I'll be reusing this console:
To make things as generic as possible, that .pyd depends on a custom .dll (OpenBLAS):
Here's a snapshot of the above (Python) process:
Notice where the dependent .dll was loaded from (2 rows below our (selected) .pyd).
Now, back to the question: there are a bunch of tools that can do that.
But it's important to mention that no matter what tool you use, will (most likely) depend on the PATH environment variable contents (in the 1st image, the dependent .dll (and others) was not found). Check [MS.Learn]: Dynamic-Link Library Search Order for more details about .dlls.
As a note, since (some) tools generate a lot of output, I'll be filtering it out (using commands like FindStr (Grep)), only showing the relevant parts, in order to avoid filling the answer with junk.
1. [GitHub]: lucasg/Dependencies
Besides the GUI application that you mentioned (DependenciesGui.exe), there's a command line tool as well next to it: Dependencies.exe:
Side note - as seen in [SO]: How to run a fortran skript with ctypes? (@CristiFati's answer), sometimes (for some reason unknown to me) it doesn't show the exports (the GUI, at least).
2. Dependency Walker
Although it's no longer maintained, it's a very nice tool and before Dependencies it was the best I could find. I also used it for [SO]: How to build a DLL version of libjpeg 9b? (@CristiFati's answer) (somewhere at the end).
The drawback is that it's spitting the output in a file, so an additional step is required:
3. [MS.Learn]: DUMPBIN Reference
Part of VStudio. I am only listing it as a reference, because it can display a .dll dependents, but not whether they can be loaded (and if yes, where from):
4. Nix emulators
Invoke [Man7]: LDD(1).
I guess this can be a favorite, since it's leaning towards Nix world (where these kind of things are easier) and you also mentioned SSH connection.
I'll be exemplifying on MSYS2, but same thing is achievable from others (Cygwin, maybe MinGW, ...).
Of course, there can be more tools that I am not aware of (or if .dlls coming from .NET are involved).
Related (more or less):
[SO]: Can't import dll module in Python (@CristiFati's answer)
[SO]: Python Ctypes - loading dll throws OSError: [WinError 193] %1 is not a valid Win32 application (@CristiFati's answer)
[SO]: How to check for DLL dependency?
[SO]: C DLL loads in C++ program, not in python Ctypes (@MarkTolonen's answer)