If you have ever had to py2exe a Python program using pyOpenGL, you know that it’s a painful, tedious, but above all unclean process. (Even back with 2.x, that “version” file was so troublesome, but here we have one of py2exe’s worst enemies: funky import hooks.)
I actually figured this out some time ago and have been using it in many of my projects; I first did it for Frets on Fire X (FoFiX), and now, upon finding a certain lack of this information elsewhere on the Internet, I’m bringing it to you here.
Other documents advocate excluding the OpenGL package from your distribution and manually adding it back in after you actually run py2exe. However, it’s actually quite trivial to work around the weird import hooks. The hooks don’t care whether
import (well, really,
__import__…) is operating the standard CPython way (loading modules and packages directly from the filesystem) or through zipimport, just as long as it returns something useful and doesn’t raise
ImportError. So we can just force the stuff that gets indirectly imported to be included when py2exe does its thing.
It’s a case of passing the necessary module names to py2exe via the py2exe includes option. To do that, pass a dictionary as a keyword argument named
setup. In that dictionary, assign the key
py2exe to another dictionary. In that sub-dictionary, set
includes to a list that contains (at least) the following strings:
OpenGL.platform.win32 OpenGL.arrays.ctypesarrays OpenGL.arrays.numpymodule OpenGL.arrays.lists OpenGL.arrays.numbers OpenGL.arrays.strings
(Note that you probably won’t need all of those array converters, and you may in fact need extra ones. Those should cover practically all use cases, though. FoFiX, which is a quite involved codebase, only needs those.)
If all goes well, everything that pyOpenGL 3.x needs to run should end up actually in the distribution (cleanly!) once py2exe is invoked with the new includes.
If you need to see an example of this in action, see FoFiX’s setup.py script, and all will become clear to you.
Happy py2exeing with pyOpenGL 3.x!