Sitemap

Getting Started
Utilities
Spec Files
When Things Go Wrong
Standalone Executables
Python Archives
Analyzing Python Modules
An Import Framework

Bug Tracker

Self-extracting executables

The ELF executable format (Windows, Linux and some others) 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 open itself as a binary file name, seek to the end and 'open' the CArchive (see figure 3).

On other platforms, the archive and the executable are separate, but the archive is named executable.pkg, and expected to be in the same directory. Other than that, the process is the same.

One Pass Execution

In a single directory deployment (--onedir, which is the default), all of the binaries are already in the file system. In that case, the embedding app:

  • opens the archive
  • starts Python (on Windows, this is done with dynamic loading so one embedding app binary can be used with any Python version)
  • imports all the modules which are at the top level of the archive (basically, bootstraps the import hooks)
  • mounts the ZlibArchive(s) in the outer archive
  • runs all the scripts which are at the top level of the archive
  • finalizes Python

Two Pass Execution

There are a couple situations which require two passes:

  • a --onefile deployment (on Windows, the files can't be cleaned up afterwards because Python does not call FreeLibrary; on other platforms, Python won't find them if they're extracted in the same process that uses them)
  • LD_LIBRARY_PATH needs to be set to find the binaries (not extension modules, but modules the extensions are linked to).

The first pass:

  • opens the archive
  • extracts all the binaries in the archive (in 5b5, this is always to a temporary directory).
  • sets a magic environment variable
  • sets LD_LIBRARY_PATH (non-Windows)
  • executes itself as a child process (letting the child use his stdin, stdout and stderr)
  • waits for the child to exit (on *nix, the child actually replaces the parent)
  • cleans up the extracted binaries (so on *nix, this is done by the child)

The child process executes as in One Pass Execution above (the magic environment variable is what tells it that this is pass two).

figure 3 - Self Extracting Executable

There are, of course, quite a few differences between the Windows and Unix/Linux versions. The major one is that because all of Python on Windows is in pythonXX.dll, and dynamic loading is so simple-minded, I can use one binary with any version of Python. There's much in common, though, and that C code can be found in source/common/launch.c.

The Unix/Linux build process (which you need to run just once for any version of Python) makes use of the config information in your install (if you installed from RPM, you need the Python-development RPM). It also overrides getpath.c since we don't want it hunting around the filesystem to build sys.path.

In both cases, while one Installer download can be used with any Python version, you need to have separate installations for each Python version.

copyright 1999-2002
McMillan Enterprises, Inc.