| 1 |
|
==================
|
| 2 |
|
PyInstaller Manual
|
| 3 |
|
==================
|
| 4 |
|
:Author: William Caban (based on Gordon McMillan's manual)
|
| 5 |
|
:Contact: william@hpcf.upr.edu
|
| 6 |
|
:Revision: $Rev$
|
| 7 |
|
:Source URL: $HeadURL$
|
| 8 |
|
:Copyright: This document has been placed in the public domain.
|
| 9 |
|
|
| 10 |
|
.. contents::
|
| 11 |
|
|
| 12 |
|
|
| 13 |
|
Getting Started
|
| 14 |
|
+++++++++++++++
|
| 15 |
|
|
| 16 |
|
Installing PyInstaller
|
| 17 |
|
|
| 18 |
|
First, unpack the archive on you path of choice. Installer is **not** a Python
|
| 19 |
|
package, so it doesn't need to go in site-packages, or have a .pth file. For
|
| 20 |
|
the purpose of this documentation we will assume |install_path|. You will be
|
| 21 |
|
using a couple of scripts in the |install_path| directory, and these will find
|
| 22 |
|
everything they need from their own location. For convenience, keep the paths
|
| 23 |
|
to these scripts short (don't install in a deeply nested subdirectory).
|
| 24 |
|
|
| 25 |
|
|PyInstaller| is dependant to the version of python you configure it for. In
|
| 26 |
|
other words, you will need a separate copy of |PyInstaller| for each Python
|
| 27 |
|
version you wish to work with *or* you'll need to rerun ``Configure.py`` every
|
| 28 |
|
time you switch the Python version).
|
| 29 |
|
|
| 30 |
|
|GOBACK|
|
| 31 |
|
|
| 32 |
|
|
| 33 |
|
Building the runtime executables
|
| 34 |
|
|
| 35 |
|
*Note:* Windows users can skip this step, because all of Python is contained in
|
| 36 |
|
pythonXX.dll, and |PyInstaller| will use your pythonXX.dll.
|
| 37 |
|
|
| 38 |
|
On Linux the first thing to do is build the runtime executables.
|
| 39 |
|
|
| 40 |
|
Change to the |install_path| ``source/linux`` subdirectory. Run ``Make.py
|
| 41 |
|
[-n|-e]`` and then make. This will produce ``support/loader/run`` and
|
| 42 |
|
``support/loader/run_d``, which are the bootloaders.
|
| 43 |
|
|
| 44 |
|
.. sidebar:: Bootloader
|
| 45 |
|
|
| 46 |
|
The bootloader (also known as *stub* in literature) is the small program
|
| 47 |
|
which starts up your packaged program. Usually, the archive containing the
|
| 48 |
|
bytecoded modules of your program is simply attended to it. See
|
| 49 |
|
`Self-extracting executables`_ for more details on the process.
|
| 50 |
|
|
| 51 |
|
*Note:* If you have multiple versions of Python, the Python you use to run
|
| 52 |
|
``Make.py`` is the one whose configuration is used.
|
| 53 |
|
|
| 54 |
|
The ``-n`` and ``-e`` options set a non-elf or elf flag in your ``config.dat``.
|
| 55 |
|
As of |InitialVersion|, the executable will try both strategies, and this flag
|
| 56 |
|
just sets how you want your executables built. In the elf strategy, the archive
|
| 57 |
|
is concatenated to the executable. In the non-elf strategy, the executable
|
| 58 |
|
expects an archive with the same name as itself in the executable's directory.
|
| 59 |
|
Note that the executable chases down symbolic links before determining it's name
|
| 60 |
|
and directory, so putting the archive in the same directory as the symbolic link
|
| 61 |
|
will not work.
|
| 62 |
|
|
| 63 |
|
Windows distributions come with several executables in the ``support/loader``
|
| 64 |
|
directory: ``run_*.exe`` (bootloader for regular programs), and
|
| 65 |
|
``inprocsrvr_*.dll`` (bootloader for in-process COM servers). To rebuild this,
|
| 66 |
|
you need to install Scons_, and then just run ``scons`` from the |install_path|
|
| 67 |
|
directory.
|
| 68 |
|
|
| 69 |
|
|GOBACK|
|
| 70 |
|
|
| 71 |
|
Configuring your PyInstaller setup
|
| 72 |
|
|
| 73 |
|
In the |install_path| directory, run ``Configure.py``. This saves some
|
| 74 |
|
information into ``config.dat`` that would otherwise be recomputed every time.
|
| 75 |
|
It can be rerun at any time if your configuration changes. It must be run before
|
| 76 |
|
trying to build anything.
|
| 77 |
|
|
| 78 |
|
|GOBACK|
|
| 79 |
|
|
| 80 |
|
|
| 81 |
|
Create a spec file for your project
|
| 82 |
|
|
| 83 |
|
[For Windows COM server support, see section `Windows COM Server Support`_]
|
| 84 |
|
|
| 85 |
|
The root directory has a script Makespec.py for this purpose::
|
| 86 |
|
|
| 87 |
|
python Makespec.py [opts] <scriptname> [<scriptname> ...]
|
| 88 |
|
|
| 89 |
|
Where allowed OPTIONS are:
|
| 90 |
|
|
| 91 |
|
produce a single file deployment (see below).
|
| 92 |
|
|
| 93 |
|
produce a single directory deployment (default).
|
| 94 |
|
|
| 95 |
|
include TCL/TK in the deployment.
|
| 96 |
|
|
| 97 |
|
do not include encodings. The default (on Python versions with unicode
|
| 98 |
|
support) is now to include all encodings.
|
| 99 |
|
|
| 100 |
|
use debug (verbose) versions of the executables.
|
| 101 |
|
|
| 102 |
|
Use the Windows subsystem executable, which does not open
|
| 103 |
|
the console when the program is launched. **(Windows only)**
|
| 104 |
|
|
| 105 |
|
Use the console subsystem executable. This is the default. **(Windows only)**
|
| 106 |
|
|
| 107 |
|
the executable and all shared libraries will be run through strip. Note
|
| 108 |
|
that cygwin's strip tends to render normal Win32 dlls unusable.
|
| 109 |
|
|
| 110 |
|
if you have UPX installed (detected by Configure), this will use it to
|
| 111 |
|
compress your executable (and, on Windows, your dlls). See note below.
|
| 112 |
|
|
| 113 |
|
create the spec file in *directory*. If not specified, and the current
|
| 114 |
|
directory is Installer's root directory, an output subdirectory will be
|
| 115 |
|
created. Otherwise the current directory is used.
|
| 116 |
|
|
| 117 |
|
set base path for import (like using PYTHONPATH). Multiple directories are
|
| 118 |
|
allowed, separating them with the path separator (';' under Windows, ':'
|
| 119 |
|
under Linux), or using this option multiple times.
|
| 120 |
|
|
| 121 |
|
add *file.ico* to the executable's resources. **(Windows only)**
|
| 122 |
|
|
| 123 |
|
add the *n*-th incon in *file.exe* to the executable's resources. **(Windows
|
| 124 |
|
only)**
|
| 125 |
|
|
| 126 |
|
add verfile as a version resource to the executable. **(Windows only)**
|
| 127 |
|
|
| 128 |
|
optional *name* to assign to the project (from which the spec file name is
|
| 129 |
|
generated). If omitted, the basename of the (first) script is used.
|
| 130 |
|
|
| 131 |
|
[For building with optimization on (like ``Python -O``), see section
|
| 132 |
|
`Building Optimized`_]
|
| 133 |
|
|
| 134 |
|
For simple projects, the generated spec file will probably be sufficient. For
|
| 135 |
|
more complex projects, it should be regarded as a template. The spec file is
|
| 136 |
|
actually Python code, and modifying it should be ease. See `Spec Files`_ for
|
| 137 |
|
details.
|
| 138 |
|
|
| 139 |
|
|
| 140 |
|
|GOBACK|
|
| 141 |
|
|
| 142 |
|
Build your project
|
| 143 |
|
|
| 144 |
|
::
|
| 145 |
|
|
| 146 |
|
python Build.py specfile
|
| 147 |
|
|
| 148 |
|
|
| 149 |
|
A ``buildproject`` subdirectory will be created in the specfile's directory. This
|
| 150 |
|
is a private workspace so that ``Build.py`` can act like a makefile. Any named
|
| 151 |
|
targets will appear in the specfile's directory. For ``--onedir``
|
| 152 |
|
configurations, it will create also ``distproject``, which is the directory you're
|
| 153 |
|
interested in. For a ``--onefile``, the executable will be in the specfile's
|
| 154 |
|
directory.
|
| 155 |
|
|
| 156 |
|
In most cases, this will be all you have to do. If not, see `When things go
|
| 157 |
|
wrong`_ and be sure to read the introduction to `Spec Files`_.
|
| 158 |
|
|
| 159 |
|
|GOBACK|
|
| 160 |
|
|
| 161 |
|
Windows COM Server support
|
| 162 |
|
|
| 163 |
|
For Windows COM support execute::
|
| 164 |
|
|
| 165 |
|
python MakeCOMServer.py [OPTION] script...
|
| 166 |
|
|
| 167 |
|
|
| 168 |
|
This will generate a new script ``drivescript.py`` and a spec file for the script.
|
| 169 |
|
|
| 170 |
|
These options are allowed:
|
| 171 |
|
|
| 172 |
|
Use the verbose version of the executable.
|
| 173 |
|
|
| 174 |
|
Register the COM server(s) with the quiet flag off.
|
| 175 |
|
|
| 176 |
|
do not include encodings (this is passed through to Makespec).
|
| 177 |
|
|
| 178 |
|
Generate the driver script and spec file in dir.
|
| 179 |
|
|
| 180 |
|
Now `Build your project`_ on the generated spec file.
|
| 181 |
|
|
| 182 |
|
If you have the win32dbg package installed, you can use it with the generated
|
| 183 |
|
COM server. In the driver script, set ``debug=1`` in the registration line.
|
| 184 |
|
|
| 185 |
|
**Warnings**: the inprocess COM server support will not work when the client
|
| 186 |
|
process already has Python loaded. It would be rather tricky to
|
| 187 |
|
non-obtrusively hook into an already running Python, but the show-stopper is
|
| 188 |
|
that the Python/C API won't let us find out which interpreter instance I should
|
| 189 |
|
hook into. (If this is important to you, you might experiment with using
|
| 190 |
|
apartment threading, which seems the best possibility to get this to work). To
|
| 191 |
|
use a "frozen" COM server from a Python process, you'll have to load it as an
|
| 192 |
|
exe::
|
| 193 |
|
|
| 194 |
|
o = win32com.client.Dispatch(progid,
|
| 195 |
|
clsctx=pythoncom.CLSCTX_LOCAL_SERVER)
|
| 196 |
|
|
| 197 |
|
|
| 198 |
|
MakeCOMServer also assumes that your top level code (registration etc.) is
|
| 199 |
|
"normal". If it's not, you will have to edit the generated script.
|
| 200 |
|
|
| 201 |
|
|GOBACK|
|
| 202 |
|
|
| 203 |
|
|
| 204 |
|
Building Optimized
|
| 205 |
|
|
| 206 |
|
There are two facets to running optimized: gathering ``.pyo``'s, and setting the
|
| 207 |
|
``Py_OptimizeFlag``. Installer will gather ``.pyo``'s if it is run optimized::
|
| 208 |
|
|
| 209 |
|
python -O Build.py ...
|
| 210 |
|
|
| 211 |
|
|
| 212 |
|
The ``Py_OptimizeFlag`` will be set if you use a ``('O','','OPTION')`` in one of
|
| 213 |
|
the ``TOCs`` building the ``EXE``::
|
| 214 |
|
|
| 215 |
|
exe = EXE(pyz,
|
| 216 |
|
a.scripts + [('O','','OPTION')],
|
| 217 |
|
...
|
| 218 |
|
|
| 219 |
|
See `Spec Files`_ for details.
|
| 220 |
|
|
| 221 |
|
|GOBACK|
|
| 222 |
|
|
| 223 |
|
|
| 224 |
|
A Note on using UPX
|
| 225 |
|
|
| 226 |
|
On both Windows and Linux, UPX can give truly startling compression - the days
|
| 227 |
|
of fitting something useful on a diskette are not gone forever! Installer has
|
| 228 |
|
been tested with many UPX versions without problems. Just get it and install it
|
| 229 |
|
on your PATH, then rerun configure.
|
| 230 |
|
|
| 231 |
|
For Windows, there is a problem of compatibility between UPX and executables
|
| 232 |
|
generated by Microsoft Visual Studio .NET 2003 (or the equivalent free
|
| 233 |
|
toolkit available for download). This is especially worrisome for users of
|
| 234 |
|
Python 2.4+, where most extensions (and Python itself) are compiled with that
|
| 235 |
|
compiler. This issue has been fixed in later beta versions of UPX, so you
|
| 236 |
|
will need at least UPX 1.92 beta. `Configure.py`_ will check this for you
|
| 237 |
|
and complain if you have an older version of UPX and you are using Python 2.4.
|
| 238 |
|
|
| 239 |
|
.. sidebar:: UPX and Unix
|
| 240 |
|
|
| 241 |
|
Under UNIX, old versions of UPX were not able to expand and execute the
|
| 242 |
|
executable in memory, and they were extracting it into a temporary file
|
| 243 |
|
in the filesystem, before spawning it. This is no longer valid under Linux,
|
| 244 |
|
but the information in this paragraph still needs to be updated.
|
| 245 |
|
|
| 246 |
|
.. _`Configure.py`: `Configuring your PyInstaller setup`_
|
| 247 |
|
|
| 248 |
|
For Linux, a bit more discussion is in order. First, UPX is only useful on
|
| 249 |
|
executables, not shared libs. Installer accounts for that, but to get the full
|
| 250 |
|
benefit, you might rebuild Python with more things statically linked.
|
| 251 |
|
|
| 252 |
|
More importantly, when ``run`` finds that its ``sys.argv[0]`` does not contain a path,
|
| 253 |
|
it will use ``/proc/pid/exe`` to find itself (if it can). This happens, for
|
| 254 |
|
example, when executed by Apache. If it has been upx-ed, this symbolic link
|
| 255 |
|
points to the tempfile created by the upx stub and |PyInstaller| will fail (please
|
| 256 |
|
see the UPX docs for more information). So for now, at least, you can't use upx
|
| 257 |
|
for CGI's executed by Apache. Otherwise, you can ignore the warnings in the UPX
|
| 258 |
|
docs, since what PyInstaller opens is the executable Installer created, not the
|
| 259 |
|
temporary upx-created executable.
|
| 260 |
|
|
| 261 |
|
|GOBACK|
|
| 262 |
|
|
| 263 |
|
A Note on ``--onefile``
|
| 264 |
|
|
| 265 |
|
A ``--onefile`` works by packing all the shared libs / dlls into the archive
|
| 266 |
|
attached to the bootloader executable (or next to the executable in a non-elf
|
| 267 |
|
configuration). When first started, it finds that it needs to extract these
|
| 268 |
|
files before it can run "for real". That's because locating and loading a
|
| 269 |
|
shared lib or linked-in dll is a system level action, not user-level. With
|
| 270 |
|
|PyInstallerVersion| it always uses a temporary directory (``_MEIpid``) in the
|
| 271 |
|
user's temp directory. It then executes itself again, setting things up so
|
| 272 |
|
the system will be able to load the shared libs / dlls. When executing is
|
| 273 |
|
complete, it recursively removes the entire directory it created.
|
| 274 |
|
|
| 275 |
|
This has a number of implications:
|
| 276 |
|
|
| 277 |
|
* You can run multiple copies - they won't collide.
|
| 278 |
|
|
| 279 |
|
* Running multiple copies will be rather expensive to the system (nothing is
|
| 280 |
|
shared).
|
| 281 |
|
|
| 282 |
|
* If you're using the cheat of adding user data as ``'BINARY'``, it will be in
|
| 283 |
|
``os.environ['_MEIPASS2']``, not in the executable's directory.
|
| 284 |
|
|
| 285 |
|
* On Windows, using Task Manager to kill the parent process will leave the
|
| 286 |
|
directory behind.
|
| 287 |
|
|
| 288 |
|
* On \*nix, a kill -9 (or crash) will leave the directory behind.
|
| 289 |
|
|
| 290 |
|
* Otherwise, on both platforms, the directory will be recursively deleted.
|
| 291 |
|
|
| 292 |
|
* So any files you might create in ``os.environ['_MEIPASS2']`` will be deleted.
|
| 293 |
|
|
| 294 |
|
* The executable can be in a protected or read-only directory.
|
| 295 |
|
|
| 296 |
|
* If for some reason, the ``_MEIpid`` directory already exists, the executable
|
| 297 |
|
will fail. It is created mode 0700, so only the one user can modify it
|
| 298 |
|
(on \*nix, of course).
|
| 299 |
|
|
| 300 |
|
While we are not a security expert, we believe the scheme is good enough for
|
| 301 |
|
most of the users.
|
| 302 |
|
|
| 303 |
|
**Notes for \*nix users**: Take notice that if the executable does a setuid root,
|
| 304 |
|
a determined hacker could possibly (given enough tries) introduce a malicious
|
| 305 |
|
lookalike of one of the shared libraries during the hole between when the
|
| 306 |
|
library is extracted and when it gets loaded by the execvp'd process. So maybe
|
| 307 |
|
you shouldn't do setuid root programs using ``--onefile``. **In fact, we do not
|
| 308 |
|
recomend the use of --onefile on setuid programs.**
|
| 309 |
|
|
| 310 |
|
|GOBACK|
|
| 311 |
|
|
| 312 |
|
A Note on .egg files and setuptools
|
| 313 |
|
`setuptools`_ is a distutils extensions which provide many benefits, including
|
| 314 |
|
the ability to distribute the extension as ``egg`` files. Together with the
|
| 315 |
|
nifty `easy_install`_ (a tool which automatically locates, downloads and
|
| 316 |
|
installs Python extensions), ``egg`` files are becoming more and more
|
| 317 |
|
widespread as a way for distributing Python extensions.
|
| 318 |
|
|
| 319 |
|
``egg`` files are actually ZIP files under the hood, and they rely on the fact
|
| 320 |
|
that Python 2.4 is able to transparently import modules stored within ZIP
|
| 321 |
|
files. PyInstaller is currently *not* able to import and extract modules
|
| 322 |
|
within ZIP files, so code which uses extensions packaged as ``egg`` files
|
| 323 |
|
cannot be packaged with PyInstaller.
|
| 324 |
|
|
| 325 |
|
The workaround is pretty easy: you can use ``easy_install -Z`` at installation
|
| 326 |
|
time to ask ``easy_install`` to always decompress egg files. This will allow
|
| 327 |
|
PyInstaller to see the files and make the package correctly. If you have already
|
| 328 |
|
installed the modules, you can simply decompress them within a directory with
|
| 329 |
|
the same name of the ``egg`` file (including also the extension).
|
| 330 |
|
|
| 331 |
|
Support for ``egg`` files is planned for a future release of PyInstaller.
|
| 332 |
|
|
| 333 |
|
.. _`setuptools`: http://peak.telecommunity.com/DevCenter/setuptools
|
| 334 |
|
.. _`easy_install`: http://peak.telecommunity.com/DevCenter/EasyInstall
|
| 335 |
|
|
| 336 |
|
|
| 337 |
|
|GOBACK|
|
| 338 |
|
|
| 339 |
|
|
| 340 |
|
PyInstaller Utilities
|
| 341 |
|
+++++++++++++++++++++
|
| 342 |
|
|
| 343 |
|
ArchiveViewer
|
| 344 |
|
|
| 345 |
|
::
|
| 346 |
|
|
| 347 |
|
python ArchiveViewer.py <archivefile>
|
| 348 |
|
|
| 349 |
|
|
| 350 |
|
ArchiveViewer lets you examine the contents of any archive build with
|
| 351 |
|
|PyInstaller| or executable (PYZ, PKG or exe). Invoke it with the target as the
|
| 352 |
|
first arg (It has been set up as a Send-To so it shows on the context menu in
|
| 353 |
|
Explorer). The archive can be navigated using these commands:
|
| 354 |
|
|
| 355 |
|
O <nm>
|
| 356 |
|
Open the embedded archive <nm> (will prompt if omitted).
|
| 357 |
|
|
| 358 |
|
U
|
| 359 |
|
Go up one level (go back to viewing the embedding archive).
|
| 360 |
|
|
| 361 |
|
X <nm>
|
| 362 |
|
Extract nm (will prompt if omitted). Prompts for output filename. If none
|
| 363 |
|
given, extracted to stdout.
|
| 364 |
|
|
| 365 |
|
Q
|
| 366 |
|
Quit.
|
| 367 |
|
|
| 368 |
|
|
| 369 |
|
|GOBACK|
|
| 370 |
|
|
| 371 |
|
|
| 372 |
|
bindepend
|
| 373 |
|
|
| 374 |
|
::
|
| 375 |
|
|
| 376 |
|
python bindepend.py <executable_or_dynamic_library>
|
| 377 |
|
|
| 378 |
|
bindepend will analyze the executable you pass to it, and write to stdout all
|
| 379 |
|
its binary dependencies. This is handy to find out which DLLs are required by
|
| 380 |
|
an executable or another DLL. This module is used by |PyInstaller| itself to
|
| 381 |
|
follow the chain of dependencies of binary extensions and make sure that all
|
| 382 |
|
of them get included in the final package.
|
| 383 |
|
|
| 384 |
|
|
| 385 |
|
GrabVersion (Windows)
|
| 386 |
|
|
| 387 |
|
::
|
| 388 |
|
|
| 389 |
|
python GrabVersion.py <executable_with_version_resource>
|
| 390 |
|
|
| 391 |
|
|
| 392 |
|
GrabVersion outputs text which can be eval'ed by ``versionInfo.py`` to reproduce
|
| 393 |
|
a version resource. Invoke it with the full path name of a Windows executable
|
| 394 |
|
(with a version resource) as the first argument. If you cut & paste (or
|
| 395 |
|
redirect to a file), you can then edit the version information. The edited
|
| 396 |
|
text file can be used in a ``version = myversion.txt`` option on any executable
|
| 397 |
|
in an |PyInstaller| spec file.
|
| 398 |
|
|
| 399 |
|
This was done in this way because version resources are rather strange beasts,
|
| 400 |
|
and fully understanding them is probably impossible. Some elements are
|
| 401 |
|
optional, others required, but you could spend unbounded amounts of time
|
| 402 |
|
figuring this out, because it's not well documented. When you view the version
|
| 403 |
|
tab on a properties dialog, there's no straightforward relationship between
|
| 404 |
|
how the data is displayed and the structure of the resource itself. So the
|
| 405 |
|
easiest thing to do is find an executable that displays the kind of
|
| 406 |
|
information you want, grab it's resource and edit it. Certainly easier than
|
| 407 |
|
the Version resource wizard in VC++.
|
| 408 |
|
|
| 409 |
|
|GOBACK|
|
| 410 |
|
|
| 411 |
|
|
| 412 |
|
Analyzing Dependencies
|
| 413 |
|
|
| 414 |
|
You can interactively track down dependencies, including getting
|
| 415 |
|
cross-references by using ``mf.py``, documented in section `mf.py: A modulefinder
|
| 416 |
|
Replacement`_
|
| 417 |
|
|
| 418 |
|
|GOBACK|
|
| 419 |
|
|
| 420 |
|
|
| 421 |
|
Spec Files
|
| 422 |
|
++++++++++
|
| 423 |
|
|
| 424 |
|
Introduction
|
| 425 |
|
|
| 426 |
|
Spec files are in Python syntax. They are evaluated by Build.py. A simplistic
|
| 427 |
|
spec file might look like this::
|
| 428 |
|
|
| 429 |
|
a = Analysis(['myscript.py'])
|
| 430 |
|
pyz = PYZ(a.pure)
|
| 431 |
|
exe = EXE(pyz, a.scripts, a.binaries, name="myapp.exe")
|
| 432 |
|
|
| 433 |
|
This creates a single file deployment with all binaries (extension modules and
|
| 434 |
|
their dependencies) packed into the executable.
|
| 435 |
|
|
| 436 |
|
A simplistic single directory deployment might look like this::
|
| 437 |
|
|
| 438 |
|
a = Analysis(['myscript.py'])
|
| 439 |
|
pyz = PYZ(a.pure)
|
| 440 |
|
exe = EXE(a.scripts, pyz, name="myapp.exe", exclude_binaries=1)
|
| 441 |
|
dist = COLLECT(exe, a.binaries, name="dist")
|
| 442 |
|
|
| 443 |
|
|
| 444 |
|
Note that neither of these examples are realistic. Use ``Makespec.py`` (documented
|
| 445 |
|
in section `Create a spec file for your project`_) to create your specfile,
|
| 446 |
|
and tweak it (if necessary) from there.
|
| 447 |
|
|
| 448 |
|
All of the classes you see above are subclasses of ``Build.Target``. A Target acts
|
| 449 |
|
like a rule in a makefile. It knows enough to cache its last inputs and
|
| 450 |
|
outputs. If its inputs haven't changed, it can assume its outputs wouldn't
|
| 451 |
|
change on recomputation. So a spec file acts much like a makefile, only
|
| 452 |
|
rebuilding as much as needs rebuilding. This means, for example, that if you
|
| 453 |
|
change an ``EXE`` from ``debug=1`` to ``debug=0``, the rebuild will be nearly
|
| 454 |
|
instantaneous.
|
| 455 |
|
|
| 456 |
|
The high level view is that an ``Analysis`` takes a list of scripts as input,
|
| 457 |
|
and generates three "outputs", held in attributes named ``scripts``, ``pure``
|
| 458 |
|
and ``binaries``. A ``PYZ`` (a ``.pyz`` archive) is built from the modules in
|
| 459 |
|
pure. The ``EXE`` is built from the ``PYZ``, the scripts and, in the case of a
|
| 460 |
|
single-file deployment, the binaries. In a single-directory deployment, a
|
| 461 |
|
directory is built containing a slim executable and the binaries.
|
| 462 |
|
|
| 463 |
|
|GOBACK|
|
| 464 |
|
|
| 465 |
|
TOC Class (Table of Contents)
|
| 466 |
|
|
| 467 |
|
Before you can do much with a spec file, you need to understand the
|
| 468 |
|
``TOC`` (Table Of Contents) class.
|
| 469 |
|
|
| 470 |
|
A ``TOC`` appears to be a list of tuples of the form (name, path, typecode).
|
| 471 |
|
In fact, it's an ordered set, not a list. A TOC contains no duplicates, where
|
| 472 |
|
uniqueness is based on name only. Furthermore, within this constraint, a TOC
|
| 473 |
|
preserves order.
|
| 474 |
|
|
| 475 |
|
Besides the normal list methods and operations, TOC supports taking differences
|
| 476 |
|
and intersections (and note that adding or extending is really equivalent to
|
| 477 |
|
union). Furthermore, the operations can take a real list of tuples on the right
|
| 478 |
|
hand side. This makes excluding modules quite easy. For a pure Python module::
|
| 479 |
|
|
| 480 |
|
pyz = PYZ(a.pure - [('badmodule', '', '')])
|
| 481 |
|
|
| 482 |
|
|
| 483 |
|
or for an extension module in a single-directory deployment::
|
| 484 |
|
|
| 485 |
|
dist = COLLECT(..., a.binaries - [('badmodule', '', '')], ...)
|
| 486 |
|
|
| 487 |
|
|
| 488 |
|
or for a single-file deployment::
|
| 489 |
|
|
| 490 |
|
exe = EXE(..., a.binaries - [('badmodule', '', '')], ...)
|
| 491 |
|
|
| 492 |
|
To add files to a TOC, you need to know about the typecodes (or the step using
|
| 493 |
|
the TOC won't know what to do with the entry).
|
| 494 |
|
|
| 495 |
|
+---------------+-------------------------------------------------------+-----------------------+-------------------------------+
|
| 496 |
|
| **typecode** | **description** | **name** | **path** |
|
| 497 |
|
+===============+=======================================================+=======================+===============================+
|
| 498 |
|
| 'EXTENSION' | An extension module. | Python internal name. | Full path name in build. |
|
| 499 |
|
+---------------+-------------------------------------------------------+-----------------------+-------------------------------+
|
| 500 |
|
| 'PYSOURCE' | A script. | Python internal name. | Full path name in build. |
|
| 501 |
|
+---------------+-------------------------------------------------------+-----------------------+-------------------------------+
|
| 502 |
|
| 'PYMODULE' | A pure Python module (including __init__ modules). | Python internal name. | Full path name in build. |
|
| 503 |
|
+---------------+-------------------------------------------------------+-----------------------+-------------------------------+
|
| 504 |
|
| 'PYZ' | A .pyz archive (archive_rt.ZlibArchive). | Runtime name. | Full path name in build. |
|
| 505 |
|
+---------------+-------------------------------------------------------+-----------------------+-------------------------------+
|
| 506 |
|
| 'PKG' | A pkg archive (carchive4.CArchive). | Runtime name. | Full path name in build. |
|
| 507 |
|
+---------------+-------------------------------------------------------+-----------------------+-------------------------------+
|
| 508 |
|
| 'BINARY' | A shared library. | Runtime name. | Full path name in build. |
|
| 509 |
|
+---------------+-------------------------------------------------------+-----------------------+-------------------------------+
|
| 510 |
|
| 'DATA' | Aribitrary files. | Runtime name. | Full path name in build. |
|
| 511 |
|
+---------------+-------------------------------------------------------+-----------------------+-------------------------------+
|
| 512 |
|
| 'OPTION' | A runtime runtime option (frozen into the executable).| The option. | Unused. |
|
| 513 |
|
+---------------+-------------------------------------------------------+-----------------------+-------------------------------+
|
| 514 |
|
|
| 515 |
|
You can force the include of any file in much the same way you do excludes::
|
| 516 |
|
|
| 517 |
|
collect = COLLECT(a.binaries +
|
| 518 |
|
[('readme', '/my/project/readme', 'DATA')], ...)
|
| 519 |
|
|
| 520 |
|
|
| 521 |
|
or even::
|
| 522 |
|
|
| 523 |
|
collect = COLLECT(a.binaries,
|
| 524 |
|
[('readme', '/my/project/readme', 'DATA')], ...)
|
| 525 |
|
|
| 526 |
|
|
| 527 |
|
(that is, you can use a list of tuples in place of a ``TOC`` in most cases).
|
| 528 |
|
|
| 529 |
|
There's not much reason to use this technique for ``PYSOURCE``, since an ``Analysis``
|
| 530 |
|
takes a list of scripts as input. For ``PYMODULEs`` and ``EXTENSIONs``, the hook
|
| 531 |
|
mechanism discussed here is better because you won't have to remember how you
|
| 532 |
|