Thursday, January 22, 2015

Back on the job, debugging Nuitka and PyInstaller

Back from a rush trip to Seattle and trying to get one of PyInstaller or Nuitka to do something useful.

PyInstaller: I had reported quite incorrectly that the feature of creating a Mac OS app bundle was not working. In fact it is working just fine. What had happened was a rather subtle mistake on my part.

When you run pyinstaller many-options-here myscript.py, besides writing the bundle of code and libraries into the "dist" folder, it also writes a file myscript.spec that summarizes the possibly many options you used. So the next time you can just run pyinstaller myscript.spec and skip all the options.

So stupidly, when I wanted to attempt to make a proper Mac OS app bundle I just ran pyinstaller -w myscript.spec, passing the -w argument requesting a "windowed" app bundle, but giving it the spec file, not the original code file. So it happily ignored the -w argument and built the non-windowed bundle as before—and I reported that Mac OS app bundling wasn't working.

Realized this while I was traveling. So today I properly ran the command to make an app bundle and it did so exactly as it should. It even installed my icon file, so the app has the smiley-face icon I want! But also, the app when executed, terminates with SIGABRT because, just as before, it can't find module "cocoa". That was the original issue that was keeping me from using PyInstaller to bundle Cobro, and here it still is.

So I wrote a note to the pyinstaller list, apologizing for being wrong about the Mac OS thing, but continuing with detailed and I hope helpful info on the absence of anything called *oco* anywhere in the output bundle or any of the build files and logs it writes.

Nuitka: Where were we? Oh yeah. Nuitka built a working (yay!) compiled Cobro but the output folder includes, besides the cobro.exe, a whole bunch of the DLLs it depends on, and many of these have hard links to other DLLs. The Qt ones, for example, have links to other Qt DLLs in the form of hard links to /Developer/5.4/clang_64/lib/, the location where Qt is installed on this system. The PyQt5 modules have hard links to /Library/Frameworks/Python.framework/Versions/Current/lib/python3.4/site-packages/PyQt5. As a result, the compiled program can only execute on a system with those features installed at those locations.

So Kay Hayer, aware of this, updated Nuitka to try to "relativize" these links. This is done by calling the install_name_tool utility from XCode, using it to change hard prefixes to the relative one of @executable_path. (Note that PyInstaller changes them to @loader_path which amounts to the same thing.)

So I tested the new compiler version and it terminates with an assertion error because it is passing install_name_tool an invalid path. I have already been in that part of the compiler code, so I immediately went in and added a debugging print statement. And collected the output and sent that off to the nuitka mailing list.

And here it is 4pm and that's all I've managed to do, help debug two other packages. Meanwhile my own code mildews on the disk. Tomorrow I will by golly get something productive done.

No comments: