Creating Distributions with Installer
Simple (Windows)
Simple takes a script name and optional args, creates a config file and runs Builder.
>python ../Simple.py myscript.py [-d -tk]
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!
Simple allows two 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.
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.
Standalone
Standalone takes a script name and optional args, creates a config file and runs Builder.
>python ../Standalone.py myscript.py [-d -tk -runw]
Like Simple, there are two products from Standalone. You get your script wrapped up with it's Python dependencies in one exe. But Standalone does not build an install script for you. It gathers the .exe and all it's binary dependencies into a subdirectory. You can then use Wise, or InstallShield or Winzip to build the download. Everything should be there. (If you want a free, professional looking install program, Inno has many fans.)
Standalone also takes the -d and -tk options. The projects/buildTK project first needs to be configured by running SetupTK.py (before first use of -tk). Please see the information about Tk above and below for details. There is also a -runw option for running without a console window.
|
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.
Each section in your config file becomes a Target.
Target |
Type |
Description |
PYZTarget |
PYZ |
An archive of compressed compiled Python modules. |
CollectTarget |
COLLECT |
A directory where all the binary and Python dependencies of your script will be gathered. Intended for use with InstallShield, WISE, etc. |
ArchiveTarget |
CARCHIVE |
An archive that can hold binaries, modules, scripts, zlibs, other CArchives or arbitrary data files. Accessible from both Python and C. |
ExeTarget |
STANDALONE |
A standalone executable that contains your script and anything else that you (explicitly) include in it. |
FullExeTarget |
FULLEXE |
A standalone executable that contains your script and all of its dependencies (both Python and binary). |
InstallTarget |
INSTALL |
Like a FullExeTarget, except that the script is a generated install script. |
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. |
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. |
packages |
PYZ: optional |
CSL |
Packages you want included. |
pathprefix |
ALL: optional |
CSL |
A list of directories to prepend to Builder's 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. |
|
|
|
|
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).
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.
|