Sitemap

Running Installer
Python Archives
Standalones
The MEInc.Dist package
Frequently Asked Questions
Extensions

Self-extracting executables

The COFF executable format (Windows and Linux) allows arbitrary data to be concatenated to the end of the executable without disturbing it's functionality. For this reason, a CArchive's Table of Contents is at the end of the archive. The executable can then look at argv[0] to get it's file name, open that file, seek to the end and 'open' the CArchive (see figure 3). This trick is used on both Windows and Linux.


Windows

For Windows, I have created enhanced versions of python.exe and pythonw.exe that do precisely this (and a bit more).

  • They extract all the binary (.dll or .pyd) members of the CArchive into the exe's directory, (or the user's temp directory if the exe's directory is not writable).
  • They set PYTHONPATH and PYTHONHOME to empty and then dynamically load python.
  • They remove all but the first entry from sys.path.
  • They manipulate sys.argv so that sys.argv[0] is the executable's name and other command line args are passed through (except -v, which is passed to Python).
  • They then add all the modules in the CArchive to sys.modules, (normally this is just those modules required for the next step).
  • They install all the ZLibArchives in the CArchive (so the modules in the ZLibArchives are available for import).
  • They then run all the script entries, (in particular, your main script, but you can run other scripts first, to set up the environment).
  • They then attempt to clean up after themselves. Unfortunately, Python does not use FreeLibrary on dynamically loaded extensions, so clean up may leave some .dlls or .pyds hanging around.
This means that python's dll can be one of the things in the CArchive, and that even if another version of python is installed, it should be this python dll that is loaded. Command line arguments to the exe are passed on to Python.

figure 3 - Self Extracting Executable

Linux

Loading an .so on Linux is a much more sophisticated process than loading a .dll on Windows. For this reason, Linux does not support self-extracting executables (also, it's not culturally appropriate). So all the shared modules your executable will use need to be available in the executable's directory when it starts.

On Windows, all of Python lives in python's dll, so I felt it important to have the Windows version use a completely stock python dll. On Linux, much more (maybe even all) of Python tends to be statically linked to the executable. Also, compilers tend to be readily available on Linux.

For these reasons, the embedding app is built (just once) based on your Python configuration. Since we're rebuilding anyway, I took the liberty of overriding getpath.c to prevent hunting for an existing Python installation. I also froze in exceptions.py. This makes the Linux version completely independent of any existing installations.

Other than that, what happens at runtime is very similar to the Windows process outlined above.

copyright 1999-2001
McMillan Enterprises, Inc.