I've spent the past couple of days trying to figure out how to build a dep-free application out of a bunch of Python3.4 scripts I have. These include an import of wand
, which requires ImageMagick
to be installed on the machine.
So far so good, the app ran from source code works fine both my dev environments (Debian8/Win10), finding all the necessary dependencies for the Wand module to properly operate.
Troubles come when I try to package the app with PyInstaller.
The build process works as expected, fetching the ImageMagick resources ( .dll
s etc) and including them in the output directory alongside the other binaries, but when I run the app on machines without the IM library installed the import fails.
So I went digging into the Wand source code, and realized that dependecies are looked for in global system paths (ie C:\\ProgramFiles). As a workaround, in my code I simply overridden the os.environ['MAGICK_HOME']
variable with './'
instructing the module to fetch the dependencies in place. And it worked, up to a point.
Now I can start the app: imports won't fail, the GUI is drawn and functionality is not affected. Not until I trigger any Wand-involving action at least, because whenever I do the app crashes raising the following exception:
wand.exceptions.ConfigureError: RegistryKeyLookupFailed `CoderModulesPath' @ error/module.c/GetMagickModulePath/666
It seems clear that the lack of a proper installation system-wide results in broken registry calls (now testing on win), but unfortunately I'm not quite familiar with CTypes (or whatever is being used to bind to the ImageMagick library) and I'm not sure how to proceed on properly building a no-deps app.
As always the first question popping into mind is: am I missing something obvious here?
If not, what would be your suggestions?
Thanks
This is more of a comment, and not really an answer, but I would suggest the following...
MAGICK_HOME
It's wise to set the MAGICK_HOME
environment variable. But I would suggest using os.path
to resolve the systems absolute path; as opposed to relative.
os.environ['MAGICK_HOME'] = os.path.abspath('.')
Very minor, but helps.
.dll's etc
Remember that IM is it's own ecosystem. It's true that wand
only needs MagickWand
& MagickCore
libraries to run, but IM needs all the delegates/coders to be useful. Ensure everything is present, and double check QuickStart.txt .
On your build system, it might be worth checking identify
utility to see other paths that should be included included during PyInstallers bundle stage.
identify -list Configure | grep PATH
On my Mac, I receive the following...
CODER_PATH /usr/local/lib/ImageMagick-6.9.5/modules-Q16/coders
CONFIGURE_PATH /usr/local/etc/ImageMagick-6/
DOCUMENTATION_PATH /usr/local/share/doc/ImageMagick-6
EXECUTABLE_PATH /usr/local/bin
FILTER_PATH /usr/local/lib/ImageMagick-6.9.5/modules-Q16/filters
INCLUDE_PATH /usr/local/include/ImageMagick-6
LIBRARY_PATH /usr/local/lib/ImageMagick-6.9.5
SHARE_PATH /usr/local/share/ImageMagick-6
SHAREARCH_PATH /usr/local/lib/ImageMagick-6.9.5/config-Q16
File policy.xml
under CONFIGURE_PATH
would be ideal to include to ensure your application protects against ImageTragick
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.