gz-math icon indicating copy to clipboard operation
gz-math copied to clipboard

Python bindings + Windows/Conda: dependent libraries of the *.pyd library cannot be found

Open peci1 opened this issue 3 years ago • 1 comments

Environment

  • OS Version: Windows 10 Conda
  • Source or binary build? Source gz-math7 built according to the tutorial

Continuation of discussion from https://github.com/gazebosim/sdformat/pull/1165#issuecomment-1252967167 .

Python 3.8+ no longer looks into PATH when looking for dependencies of external binary modules. Paths to the dependencies have to be added by calling os.add_dll_directory(). Normally, gz-math7.dll is installed in install/bin, while the *.pyd module is installed in install/lib/python. Therefore, Python doesn't examine install/bin for the dependencies and import gz.math7 fails with error:

ImportError: DLL load failed while importing gz.math7: module not found

Unfortunately, Windows cannot tell which library failed to load, but experimentally, copying everything from install/bin to install/lib/python resolves the issue. However, that is not a suitable solution. If I manually call os.add_dll_directory(abs_path+"/install/bin"), importing the module works.

Now the question is where to put the add_dll_directory() call and what kind of path to pass to it. The most practical way I see is creating wrapper pure python modules which would just call the add_dll_directory() and the load the binary module. This would need some renaming around, but should be the most straight-forward way.

Regarding the path to add, I've seen people on the internet to just add all directories from PATH via add_dll_directory(), but I'd say this kind of goes against the direction set by Python 3.8 (looking in PATH was discarded to increase security; although I'm a bit hesitant if it actually helps if an attacker can still push a malicious .pyd file).

Things to resolve:

  • [ ] Where to add os.add_dll_directory()?
  • [ ] What kind of path (hardcoded/relative/...) should be passed to the above call?

peci1 avatar Sep 21 '22 09:09 peci1

What kind of path (hardcoded/relative/...) should be passed to the above call?

Related to that, I checked what ROS2-related code does, and in several point it calls:

add_dll_directories_from_env('PATH')

effectively reverting to pre-Python 3.8 behaviour.

traversaro avatar Sep 21 '22 10:09 traversaro