Sitemap

McMillan Enterprises, Inc.
Python Pages
  Sockets HOWTO
  Distributing Python Programs
    Download
    Python Archives
    Standalone Executables
    Installer Release 5
    Installer Release 4
      Getting Started
      Installer - Creating Distributions
      The MEInc.Dist package
      Installer FAQ
      Extensions
      Installer Utilities
  A Python C++ API
  Embedding Python
  Stackless Python
  MkSQL
  Import Hooks
Java Samples
Sponsoring ME Inc.
About ME Inc.


Creating Distributions with Installer Release 4

Note: Release 4 is no longer being maintained. Please see Release 5.

Standalone (Windows and Linux)

Standalone takes a script name and optional args, creates a config file and runs Builder.


          >python ../Standalone.py myscript.py [-d -tk -runw -win32 -q -v -o <directory>]
          

There are two products from Standalone. You get your script wrapped up with it's Python dependencies in one exe. Then Standalone gathers the .exe and all it's binary dependencies into a subdirectory. You can then use Wise, or InstallShield or Winzip or tar / zip to build the download by packing up the subdirectory. Everything should be there. (If you want a free, professional looking install program for Windows, Inno has many fans.)

Standalone allows these optional args:

  • -d will use the debug version of Run. (The debug version spits out lots of messages as it unpacks archives and loads modules.)
  • -tk will automate Tk support (Windows only, but shouldn't be needed on Linux).
  • -runw will (on Windows) use a console-less version of Run.
  • -win32 (Windows) will override the excludes of pywintypes and win32api (which are dependencies of os, which doesn't normally need them).
  • -q will invoke quiet mode - only Error msgs will print.
  • -v will invoke verbose mode - tons of progress messages will fly by.
  • -o <directory> will use directory for output (where the config file will be written and the build will take place).

To use the Tk support, you will first need to run SetupTK.py (just once). This script sets up the projects/buildTK project with information about your Tcl/Tk installation. See below for how it works.

Simple (Windows and Linux)

Simple takes a script name and optional args, creates a config file and runs Builder.


          >python ../Simple.py myscript.py [-d -tk -runw -win32 -q -v -o <directory>]
          
Simple actually creates two executables. The core one consists of your script and all its Python dependencies. The other one is a crude installer. It includes the first executable, all its binary dependencies and a generated install script.

The net result is like using Standalone and then packaging up the result with a really cheesy install program. Seriously, folks, if you've written something worth distributing, it's worth using Standalone and a real installer.

The generated install script is not intended to be the final install script, (unless you like the crude look). It will prompt the user for an install directory, issue a few messages and quit. It is recommended that you run Simple once, and then fine tune the configuration and install scripts, using Builder directly on the modified config file. At least add "Welcome to..." and "...completed Successfully" messages to the install script!

The projects/buildTK project first needs to be configured by running SetupTK.py (before first use of -tk). Please see the information about Tk below for details.

See above for the command line options.

Freeze (Windows and Linux)


          >python ../Freeze.py myscript.py [-d -tk -runw -win32 -q -v -o <directory>]
          
Freeze takes a script name as argument. It creates a config file and runs Builder on it. The result is an executable with all the Python and binary dependencies of your script built into it. The executable actually runs as 2 processes: the parent process unpacks all the binaries, then invokes itself as a child process (with a magic environment variable set, and inherited handles). The child process executes your script. On Windows, the two-step is necessary so that after the child process exits, the parent process can clean up everything it unpacked (Python does not do FreeLibrary on extension modules on Windows). On Linux the problem is the other way round - the parent process can't link with the extension modules it unpacked, but the child process can.

See above for command line options, and how to set up Tk.

ZlibArchives (any platform with zlib)

If all you want is to distribute a set of pure Python code wrapped into a single file, then use Builder directly. For example, to distribute your package imalumberjack, you would create a config file:

          [ZLIB]
          name=imalumberjack.pyz
          packages=imalumberjack
          
and run:
          >python Builder.py imalumberjack.cfg
          
To use your zlib, you need code as follows:
          import imputil    # in the std lib for Python 2.0, or the support directory
          import archive_rt # from the support directory
          import sys
          sys.path.append(archive_rt.ZlibArchive('imalumberjack.pyz', 0))
          from imalumberjack import imok
          

Builder

Builder takes one or more config files as arguments; if multiple config files are used, they are processed as if they were all concatenated into one.

Builder understands 2 option flags: -q for quiet mode and -v for verbose mode. Without either of these flags, Builder will print all warning and error messages.

Each section in your config file becomes a Target.

Target Type Description
PYZTarget PYZ An archive of compressed compiled Python modules. This is the default type (if type= is not specified). In most configurations, the one you care about will by called [APPZLIB].
CollectTarget COLLECT A directory where all the binary and Python dependencies of your script will be gathered. Intended for use with InstallShield, WISE, zip, etc.
ArchiveTarget CARCHIVE An archive that can hold binaries, modules, scripts, zlibs, other CArchives or arbitrary data files. Accessible from both Python and C. Normally you will not use one of these directly.
ExeTarget STANDALONE A standalone executable that contains your script and anything else that you (explicitly) include in it. The kind of exe that Standalone creates.
FullExeTarget FULLEXE A standalone executable that contains your script and all of its dependencies (both Python and binary). The kind of exe that Freeze creates.
InstallTarget INSTALL Like a FullExeTarget, except that the script is a generated install script. The kind of exe that Simple creates.

The following options are available in the appropriate sections (CSL means "Comma separated list", B means "Boolean" - 1 or 0, and S means "string"):

Option Sections Type Description
name ALL: required S The (file system) name to be given to the result of building the target.
script COLLECT: optional
STANDALONE: required
FULLEXE: required
INSTALL: optional
CSL For a COLLECT target, these are just scripts to include (in source form). For the executables, these are top level scripts that will be run. For FULLEXE and INSTALL targets, the scripts will be analyzed for all dependencies. If not included in an INSTALL section, an install script (gen_install.py) will be generated.
zlib PYZ: ignored
ALL OTHERS: optional
CSL References other section(s) of type ZLIB; these will be included. Reference is by the section name (square brackets in the config).
bindepends PYZ: ignored
ALL OTHERS: optional
CSL Scripts to be analyzed for binary dependencies. (With 4a2, not normally needed.)
misc PYZ: ignored
ALL OTHERS: optional
CSL Almost any entity (file, module, script, other section...) that you want included. Usually the type of the entity can be determined. Other sections are referenced by the name in square brackets in the config file.
userunw STANDALONE: optional
FULLEXE: optional
B If 1, the non-console executable (Runw) will be used.
dependencies PYZ: optional CSL The Python dependencies of any modules / scripts mentioned here will be included. The scripts themselves will not be included (the assumption is that they are top-level, and thus won't be imported).
directories PYZ: optional CSL All Python modules from these directories will be packed into the PYZ.
trees COLLECT: optional CSL The directory tree (subject to excludes) is included. Relative path names are used. Python resources are included in source form.
excludes ALL: optional CSL Anything you want specifically excluded from the target. Generally smart about determining the "type" of the named entity.
extypes PYZ: ignored
ALL OTHERS: optional
CSL Any file types (by file extension) you want to exclude.
exstdlib PYZ: optional B If 1, anything in the standard library will be excluded.
expatterns ALL: optional CSL Regex patterns that will be applied to the path names of resources. Because path names have been normpath'ed, backslashes are a headache.
includes PYZ: optional CSL Any modules mentioned here will be included, along with their dependencies (in 4a2).
packages PYZ: optional CSL Packages you want included. The package's dependencies will also be included (in 4a2).
pathprefix ALL: optional CSL A list of directories to prepend to Builder's search path. The main script's directory is already at the front of the search path.
debug STANDALONE: optional
FULLEXE: optional
INSTALL: optional
B Use the verbose (testing) version of Run.
support PYZ: ignored
ALL OTHERS: optional
B If 1 (default), Python15.dll and exception.pyc are automatically included (whether found as dependencies or not).
icon NT Only!
STANDALONE: optional
FULLEXE: optional
INSTALL: optional
S Use icon in the resultant exe.
Three forms: Myicon.ico: An icon file.
path/some.exe, 0: The nth icon in an exe (count from zero)
path/some.exe, -99: The icon with resource id 99 in some.exe.
version NT Only!
STANDALONE: optional
FULLEXE: optional
INSTALL: optional
S Use version in the resultant exe.
Version is a text file (Python syntax) which is evaluated. The easiest way to create one is run GrabVersion.py against an executable and redirect to a text file, then edit the text file.

Note that in this version, Builder is a lot more forgiving in how it handles names. A Python module mymodule could be passed as "mymodule", "mymodule.py" or "my/path/to/mymodule.py" etc. Internally, Python resources (modules, extensions, scripts and packages) are handled by their Python name ("mymodule"), to avoid things like including both the ".py" file and the ".pyc" file.

The essential difference between a script and module is that Builder expects modules to be imported (not run), and will generally include them in compiled form. Scripts, on the other hand, are expected to be run, and will be included in source form.

TK and other extensions

The new method for supporting extensions with non-vanilla requirements is based on the fact that Builder can take multiple config files as arguments. These are treated as one large config file (acting as though they had been concatenated).

Some extensions get their own configs. This is passed to Builder (on the command line) along with the config file that will make use of it. So when you create your config file, you can reference sections of the extension's config file as though those sections were members of your config file.

Naturally, the extension's config file is just another config file, and can build any type of target(s). So you might use this feature simply to factor out some common cases (save yourself some cut and paste).

In the case of Tk, we're packing up an arbitrary (as far as Python is concerned) set of files. The tk and tcl libs are packed into a couple of CArchives, and a script snippets are included for unpacking the archives on the user's machine. The section which builds the CArchive includes the file name of the snippet in a "installscript=" option. The code which generates install scripts is smart enough to recognize this option name, and include the snippet within in the generated install. When you write a snippet, you can assume the following:

  • The modules installutils, os, sys and carchive are imported.
  • The string variable idir contains the directory that the user has selected to install into.
  • The string variable here contains the directory the install is being run from (usually, but not necessarily the same as os.getcwd()).
  • If you're operating on a CArchive, that CArchive has already been moved to idir.

So, for example, the installation snippet for the Tcl support is installutils.installCArchive(os.path.join(idir,'TCLlib.pkg'), idir, 'lib/tcl'). This will create the directory idir/lib/tcl if it doesn't exist, and unpack TCLlib.pkg into it.

Now, at runtime, we need to get Python to recognize the (private) Tcl/Tk installation we've made. The easy way to do that is to use the TCL_LIBRARY and TK_LIBRARY environment variables. So a script which does just that is stuffed into the STANDALONE ahead of the main script. When Runw does its startup, this script will be run before the main script, and the main script will have a Tk available without further effort.

Yeah, this is a bit much to grok from some verbiage, so you might want to run Simple against some script with and without the "-tk" option, and compare the generated config files, and also examine the config files and scripts in the create/buildTK directory. I'm hoping that the scheme is general enough to allow "stock" config files to be built for common extensions, without having to hack away at Builder.

copyright 1999-2002
McMillan Enterprises, Inc.