Sitemap

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

Bug Tracker

Spec Files

Contents:

Introduction

Spec files are in Python syntax. They are evaluated by Build.py. A simplistic spec file might look like this:

      a = Analysis(['myscript.py'])
      pyz = PYZ(a.pure)
      exe = EXE(pyz, a.scripts, a.binaries, name="myapp.exe")
      

This creates a single file deployment with all binaries (extension modules and their dependencies) packed into the executable.

A simplistic single directory deployment might look like this:

      a = Analysis(['myscript.py'])
      pyz = PYZ(a.pure)
      exe = EXE(a.scripts, pyz, name="myapp.exe", exclude_binaries=1)
      dist = COLLECT(exe, a.binaries, name="dist")
      

Note that neither of these examples are realistic. Use Makespec.py (documented here) to create your specfile, and tweak it (if necessary) from there.

All of the classes you see above are subclasses of Build.Target. A Target acts like a rule in a makefile. It knows enough to cache its last inputs and outputs. If its inputs haven't changed, it can assume its outputs wouldn't change on recomputation. So a spec file acts much like a makefile, only rebuilding as much as needs rebuilding. This means, for example, that if you change an EXE from debug=1 to debug=0 that the rebuild will be nearly instantaneous.

The high level view is that an Analysis takes a list of scripts as input, and generates three "outputs", held in attributes named scripts, pure and binaries. A PYZ (a .pyz archive) is built from the modules in pure. The EXE is built from the PYZ, the scripts and, in the case of a single-file deployment, the binaries. In a single-directory deployment, a directory is built containing a slim EXE and the binaries.

TOC Class (Table of Contents)

Before you can do much with a spec file, you need to understand the TOC (Table Of Contents) class.

A TOC appears to be a list of tuples of the form (name, path, typecode). In fact, it's an ordered set, not a list. A TOC contains no duplicates, where uniqueness is based on name only. Furthermore, within this constraint, a TOC preserves order.

Besides the normal list methods and operations, TOC supports taking differences and intersections (and note that adding or extending is really equivalent to union). Furthermore, the operations can take a real list of tuples on the right hand side. This makes excluding modules quite easy:

      pyz = PYZ(a.pure - [('badmodule', '', '')])
      
for a pure Python module and
      dist = COLLECT(..., a.binaries - [('badmodule', '', '')], ...)
      
for an extension module in a single-directory deployment, or
      exe = EXE(..., a.binaries - [('badmodule', '', '')], ...)
      
for a single-file deployment.

To add files to a TOC, you need to know about the typecodes (or the step using the TOC won't know what to do with the entry).

typecodedescriptionnamepath
'EXTENSION' An extension module. Python internal name. Full path name in build.
'PYSOURCE' A script. Python internal name. Full path name in build.
'PYMODULE' A pure Python module (including __init__ modules). Python internal name. Full path name in build.
'PYZ' A .pyz archive (archive_rt.ZlibArchive). Runtime name. Full path name in build.
'PKG' A pkg archive (carchive4.CArchive). Runtime name. Full path name in build.
'BINARY' A shared library. Runtime name. Full path name in build.
'DATA' Aribitrary files. Runtime name. Full path name in build.
'OPTION' A runtime runtime option (frozen into the executable). The option. Unused.

You can force the include of any file in much the same way you do excludes.

      collect = COLLECT(a.binaries + 
                [('readme', '/my/project/readme', 'DATA')], ...)
      
or even
      collect = COLLECT(a.binaries, 
                [('readme', '/my/project/readme', 'DATA')], ...)
      
(that is, you can use a list of tuples in place of a TOC in most cases).

There's not much reason to use this technique for PYSOURCE, since an Analysis takes a list of scripts as input. For PYMODULEs and EXTENSIONs, the hook mechanism discussed here is better because you won't have to remember how you got it working next time.

This technique is most useful for data files (see the Tree class below for a way to build a TOC from a directory tree), and for runtime options. The options the run executables understand are:

OptionDescriptionExampleNotes
v Verbose imports ('v', '', 'OPTION') Same as Python -v ...
u Unbuffered stdio ('u', '', 'OPTION') Same as Python -u ...
W spec Warning option ('W ignore', '', 'OPTION') Python 2.1+ only.
s Use site.py ('s', '', 'OPTION') The opposite of Python's -S flag. Note that site.py must be in the executable's directory to be used.
f Force execvp ('f', '', 'OPTION') Linux/unix only. Ensures that LD_LIBRARY_PATH is set properly.

Advanced users should note that by using set differences and intersections, it becomes possible to factor out common modules, and deploy a project containing multiple executables with minimal redundancy. You'll need some top level code in each executable to mount the common PYZ.

Target Subclasses

Analysis

      Analysis(scripts, pathex=None, hookspath=None, excludes=None)
      
scripts
a list of scripts specified as file names.
pathex
an optional list of paths to be searched before sys.path.
hookspath
an optional list of paths used to extend the hooks package.
excludes
an optional list of module or package names (their Python names, not path names) that will be ignored (as though they were not found).
An Analysis has three outputs, all TOCs accessed as attributes of the Analysis.
scripts
The scripts you gave Analysis as input, with any runtime hook scripts prepended.
pure
The pure Python modules.
binaries
The extension modules and their dependencies. The secondary dependencies are filtered. On Windows, a long list of MS dlls are excluded. On Linux/Unix, any shared lib in /lib or /usr/lib is excluded.

PYZ

      PYZ(toc, name=None, level=9)
      
toc
a TOC, normally an Analysis.pure.
name
A filename for the .pyz. Normally not needed, as the generated name will do fine.
level
The Zlib compression level to use. If 0, the zlib module is not required.

PKG

Generally, you will not need to create your own PKGs, as the EXE will do it for you. This is one way to include read-only data in a single-file deployment, however. A single-file deployment including TK support will use this technique.

      PKG(toc, name=None, cdict=None, exclude_binaries=0)
      
toc
a TOC
name
a filename for the pkg (optional).
cdict
a dictionary that specifies compression by typecode. For example, PYZ is left uncompressed so that it can be accessed inside the PKG. The default uses sensible values. If zlib is not available, no compression is used.
exclude_binaries
If 1, EXTENSIONs and BINARYs will be left out of the PKG, and forwarded to its container (ususally a COLLECT).

EXE

      EXE(*args, **kws)
      
args
One or more arguments which are either TOCs or Targets.
kws
console
Always 1 on Linux/unix. On Windows, governs whether to use the console executable, or the Windows subsystem executable.
debug
Setting to 1 gives you progress messages from the executable (for a console=0, these will be annoying MessageBoxes).
name
The filename for the executable.
exclude_binaries
Forwarded to the PKG the EXE builds.
icon
Windows NT family only. icon='myicon.ico' to use an icon file, or icon='notepad.exe,0' to grab an icon resource.
version
Windows NT family only. version='myversion.txt'. Use GrabVersion.py to steal a version resource from an executable, and then edit the ouput to create your own. (The syntax of version resources is so arcane that I wouldn't attempt to write one from scratch.)

There are actually two EXE classes - one for ELF platforms (where the run executable and the PKG are concatenated), and one for non-ELF platforms (where the run executable is simply renamed, and expects a exename.pkg in the same directory). Which class becomes available as EXE is determined by a flag in config.dat. This flag is set to non-ELF when using Make.py -n.

DLL

On Windows, this provides support for doing in-process COM servers. It is not generalized. However, embedders can follow the same model to build a special purpose DLL so the Python support in their app is hidden. You will need to write your own dll, but thanks to Allan Green for refactoring the C code and making that a managable task.

COLLECT

      COLLECT(*args, **kws)
      
args
One or more arguments which are either TOCs or Targets.
kws
name
The name of the directory to be built.

Tree

      Tree(root, prefix=None, excludes=None)
      
root
The root of the tree (on the build system).
prefix
Optional prefix to the names on the target system.
excludes
A list of names to exclude. Two forms are allowed:
name
files with this basename will be excluded (do not include the path).
*.ext
any file with the given extension will be excluded.

Since a Tree is a TOC, you can also use the exclude technique described above in the section on TOCs.

copyright 1999-2002
McMillan Enterprises, Inc.