Thursday, January 1, 2015

Hacking at Nuitka

Nuitka is a Python compiler. It processes Python source code and, where the CPython interpreter would byte-compile to a byte-code, Nuitka compiles to C++ source code. The generated source code relies on the Python/C API. It implements the same program, including calls into the built-in CPython interpreter functions, but as a compilable source module—or, what interests me, as a complete, standalone, compiled and linked executable.

And it works! Well, almost. When I feed cobro.py into Nuitka, the output is in two folders. In cobro.dist is a set of all the modname.so modules that the program relies upon, including a whole subfolder of PyQt5 modules. In cobro.build is a set of .cpp source files. When I browse in these, they are clearly based on compiling my code. So that's all good as far as it goes.

Unfortunately Nuitka under Python 3.4 does not run to completion. Nuitka has a strong dependency on SCons, a make replacement. Unfortunately, SCons is written in Python 2.x. Support for Python 3 is in process but not available. So Nuitka compiles my code as described, but then fails because it tries to invoke SCons to (presumably) perform the compile and link step, and SCons fails.

Yet Nuitka claims Python 3 compatibility. It knows that SCons depends on Python 2, so when it is time to execute SCons, Nuitka tries to find a Python 2 executable under which to run it. On my system it couldn't. I tried various ways to get around this and so far have failed. Kay Hayen, the creator of Nuitka, has been very responsive to my emails thus far, and perhaps he will yet figure something out.

But here I am, with some lovely .cpp source files and bunch of .so files, and all I need to do is run a compile and link. Tantalizing! So I tried, several times, without success.

Just now I got note from Kay, saying in part,

That mode of operation [manual compilation] is unfortunately not workable anymore. Nuitka generated source does want to get defines sent, and stuff. I think I couldn't do it myself without a lot of work. That is what we use Scons for So we can have complex arguments...

As a workaround, create a script "/usr/bin/python2" and make it set your environment variables correctly and export them, and then execute Python2 with its arguments. Then Nuitka will pick it up.

I may try this next. Nuitka is frustratingly close to being a complete solution to the issues of packaging. Just imagine being to make a compiled binary executable with no external dependencies. And it runs on Windows, Linux, and Mac OS. If I can get past this SCons hurdle, it could work.

Edit: I did in fact try the above, and it worked, in the sense that it allowed SCons to run without error. The Nuitka compile command now ran much, much longer, 30 seconds or so where before it ended after about 10 seconds.

Unfortunately it then ended with the error, "FileNotFoundError: [Errno 2] No such file or directory: 'ldd'" which is quite correct, there is no "ldd" in Mac OS. It is replaced by "otool -L". So another email to the patient Kay. Tomorrow maybe we get over this hurdle.

No comments: