Saturday, January 10, 2015

Bundle blues

I am now deep into trying to find a way to bundle either of my apps. To "bundle" a Python app is to wrap the main script, all its Python and library dependencies, and a Python interpreter, into a single, self-contained, executable thing. That thing can be given to a user who may not have PyQt, or Qt, or a compatible Python, or any Python at all, and will still run.

Lots of people have tackled the problem of making a Python app-bundler. It is a highly non-trivial problem. Just figuring out what Python modules a script depends on is non-trivial, even setting aside the ability of a Python program to introspect the import-mechanism and direct it to different targets at run-time.

Another issue is, which platform does a bundler support? There is py2app which bundles Python on Mac OS for Mac OS. There is py2exe which bundles Python on Windows, for Windows.

I know of three possible cross-platform solutions. Both cx_Freeze and PyInstaller run on Windows, Mac, or Linux and create bundles for the platform on which they run. And Nuitka runs on all three platforms and compiles a Python app (via C++) to an executable.

In recent days I've tried all three for Cobro with failures in every case. Different, unique failures. Sigh.

With Nuitka, as noted in the prior post, a tiny PyQt5 program dies with a segfault. I'm in an email conversation with Nuitka's developer Kay. It appears the problem may be that Nuitka bundles a different "pickle" module than the built-in module. PyQt5 uses "pickle" to store and retrieve QSettings values. So that may be the conflict, although it is not clear yet. Kay claims it doesn't fail except on Mac OS. I think my next move with Nuitka would be to finish setting up my Ubuntu 14.10 dev system, put Nuitka on it, and try it there.

I tried cx_Freeze and as described yesterday, its generated bundle dies looking for zlib in a nonexistent location. It has been 36 hours since I posted that to the cx_Freeze mailing list with no replies.

I am most familiar with PyInstaller. I contributed a major rewrite of its documentation early in 2014, and also spent some weeks doing a preliminary job of coding its Python3 support. Since then the Python3 support has advanced to a beta-ish level, so I downloaded it and tried it.

I quickly found a couple of minor bugs, and posted them as issues on github. After patching them on my local copy, I was able to get a complete bundle, but this dies with a different mesage:

    This application failed to start because it could not find or load the Qt platform plugin "cocoa".
    Reinstalling the application may fix this problem.
    Abort trap: 6

Searching on this messsage text turns up many hits. Only one offers some kind of solution which is extraordinarily complex, involving use of the XCode utility install_name_tool. Give me a break...

So at the moment I am stymied on three bundling fronts. There is one more approach to try, one that I've been putting off because it looks like a steep learning curve: using pyqtdeploy to create a file that can be processed by QMake. I guess that will be my next step. Sigh. Maybe monday.

No comments: