Changeset 340

Show
Ignore:
Timestamp:
Tue Nov 27 10:37:33 2007
Author:
giovannibajo
Message:

Add appended_pkg option to EXE() and remove NonELFEXE

Combine ELFEXE and NonELFEXE to a common class EXE. NonELFEXE
functionality can be achieved using the new option append_pkg of
the EXE initialization function. The default value of append_pkg
is taken from the useELFEXE (Make.py -n) to preserve backwards
compatibility of command line behavior.

Now also works on Windows.

Files:

Legend:

Unmodified
Added
Removed
Modified
  • trunk/Build.py

    r314 r340  
    456 456         return 1  
    457 457  
    458   class ELFEXE(Target):  
      458 class EXE(Target):  
    458 458     typ = 'EXECUTABLE'  
    459 459     exclude_binaries = 0  
      460     append_pkg = 1  
    460 461     def __init__(self, *args, **kws):  
    461 462         Target.__init__(self)  
     
    469 470         self.upx = kws.get('upx',None)  
    470 471         self.exclude_binaries = kws.get('exclude_binaries',0)  
      472         self.append_pkg = kws.get('append_pkg', self.append_pkg)  
    471 473         if self.name is None:  
    472 474             self.name = self.out[:-3] + 'exe'  
    473 475         if not os.path.isabs(self.name):  
    474 476             self.name = os.path.join(SPECPATH, self.name)  
      477         if iswin or cygwin:  
      478             self.pkgname = self.name[:-3] + 'pkg'  
      479         else:  
      480             self.pkgname = self.name + '.pkg'  
    475 481         self.toc = TOC()  
    476 482         for arg in args:  
     
    492 498             print "rebuilding %s because %s missing" % (outnm, os.path.basename(self.name))  
    493 499             return 1  
      500         if not self.append_pkg and not os.path.exists(self.pkgname):  
      501             print "rebuilding because %s missing" % (  
      502                 os.path.basename(self.pkgname),)  
      503             return 1  
    494 504         try:  
    495 505             name, console, debug, icon, versrsrc, strip, upx, mtm = eval(open(self.out, 'r').read())  
     
    543 553         return exe  
    544 554     def assemble(self):  
    545           print "building ELFEXE", os.path.basename(self.out)  
      555         print "building EXE", os.path.basename(self.out)  
    545 555         trash = []  
    546 556         outf = open(self.name, 'wb')  
     
    567 577         exe = checkCache(exe, self.strip, self.upx and config['hasUPX'])  
    568 578         self.copy(exe, outf)  
    569           self.copy(self.pkg.name, outf)  
      579         if self.append_pkg:  
      580             print "Appending archive to EXE", self.name  
      581             self.copy(self.pkg.name, outf)  
      582         else:  
      583             print "Copying archive to", self.pkgname  
      584             shutil.copy2(self.pkg.name, self.pkgname)  
    570 585         outf.close()  
    571 586         os.chmod(self.name, 0755)  
     
    585 600             outf.write(data)  
    586 601  
    587   class DLL(ELFEXE):  
      602 class DLL(EXE):  
    587 602     def assemble(self):  
    588 603         print "building DLL", os.path.basename(self.out)  
     
    601 616         return 1  
    602 617  
    603   class NonELFEXE(ELFEXE):  
    604       def assemble(self):  
    605           print "building NonELFEXE", os.path.basename(self.out)  
    606           trash = []  
    607           exe = 'support/loader/run'  
    608           if not self.console:  
    609               exe = exe + 'w'  
    610           if self.debug:  
    611               exe = exe + '_d'  
    612           exe = os.path.join(HOMEPATH, exe)  
    613           exe = checkCache(exe, self.strip, self.upx and config['hasUPX'])  
    614           shutil.copy2(exe, self.name)  
    615           os.chmod(self.name, 0755)  
    616           shutil.copy2(self.pkg.name, self.name+'.pkg')  
    617           f = open(self.out, 'w')  
    618           pprint.pprint((self.name, self.console, self.debug, self.icon, self.versrsrc,  
    619                          self.strip, self.upx, mtime(self.name)), f)  
    620           f.close()  
    621           for fnm in trash:  
    622               os.remove(fnm)  
    623           return 1  
    624 618  
    625   if config['useELFEXE']:  
    626       EXE = ELFEXE  
    627   else:  
    628       EXE = NonELFEXE  
      619 if not config['useELFEXE']:  
      620     EXE.append_pkg = 0  
    629 621  
    630 622 class COLLECT(Target):  
     
    644 636             elif isinstance(arg, Target):  
    645 637                 self.toc.append((os.path.basename(arg.name), arg.name, arg.typ))  
    646                   if isinstance(arg, NonELFEXE):  
    647                       self.toc.append((os.path.basename(arg.name)+'.pkg', arg.name+'.pkg', 'PKG'))  
      638                 if isinstance(arg, EXE) and not arg.append_pkg:  
      639                     self.toc.append((os.path.basename(arg.pkgname), arg.pkgname, 'PKG'))  
    648 640                 self.toc.extend(arg.dependencies)  
    649 641             else:  
  • trunk/doc/Manual.html

    r258 r340  
    22 22 <td><a class="first last reference" href="mailto:william&#64;hpcf.upr.edu">william&#64;hpcf.upr.edu</a></td></tr>  
    23 23 <tr><th class="docinfo-name">Revision:</th>  
    24   <td>257</td></tr>  
    25   <tr class="field"><th class="docinfo-name">Source URL:</th><td class="field-body">svn://pyinstaller/trunk/doc/source/Manual.rst</td>  
      24 <td>282</td></tr>  
      25 <tr class="field"><th class="docinfo-name">Source URL:</th><td class="field-body">svn://pyinstaller/branches/crypt/doc/source/Manual.rst</td>  
    26 26 </tr>  
    27 27 <tr><th class="docinfo-name">Copyright:</th>  
     
    791 791 create your own. (The syntax of version resources is so arcane that I  
    792 792 wouldn't attempt to write one from scratch.)</dd>  
      793 <dt><tt class="docutils literal"><span class="pre">append_pkg</span></tt></dt>  
      794 <dd>If <tt class="docutils literal"><span class="pre">True</span></tt>, then append the PKG archive to the EXE. If <tt class="docutils literal"><span class="pre">False</span></tt>,  
      795 place the PKG archive in a separate file <tt class="docutils literal"><span class="pre">exename.pkg</span></tt>.  
      796 The default is taken from a flag in <tt class="docutils literal"><span class="pre">config.dat</span></tt> and depends  
      797 on whether Make.py was given the <tt class="docutils literal"><span class="pre">-n</span></tt> argument  
      798 when building the loader. The default is <tt class="docutils literal"><span class="pre">True</span></tt> on Windows.  
      799 On non-ELF platforms where concatenating arbitrary data to  
      800 an executable does not work, <tt class="docutils literal"><span class="pre">append_pkg</span></tt> must be set to <tt class="docutils literal"><span class="pre">False</span></tt>.</dd>  
    793 801 </dl>  
    794 802 </dd>  
    795 803 </dl>  
    796   <p>There are actually two <tt class="docutils literal"><span class="pre">EXE</span></tt> classes - one for ELF platforms (where the  
    797   bootloader, that is the <tt class="docutils literal"><span class="pre">run</span></tt> executable, and the <tt class="docutils literal"><span class="pre">PKG</span></tt> are concatenated),  
    798   and one for non-ELF platforms (where the run executable is simply renamed, and  
    799   expects a <tt class="docutils literal"><span class="pre">exename.pkg</span></tt> in the same directory). Which class becomes available  
    800   as <tt class="docutils literal"><span class="pre">EXE</span></tt> is determined by a flag in <tt class="docutils literal"><span class="pre">config.dat</span></tt>. This flag is set to  
    801   non-ELF when using <tt class="docutils literal"><span class="pre">Make.py</span> <span class="pre">-n</span></tt>.</p>  
    802 804 <p><a class="reference reference reference reference reference reference reference reference reference reference reference reference reference reference reference reference reference reference reference" href="#pyinstaller-manual">Back to Top</a></p>  
    803 805 </div>  
     
    1554 1556 <hr class="footer" />  
    1555 1557 <a class="reference" href="source/Manual.rst">View document source</a>.  
    1556   Generated on: 2006-02-08 14:02 UTC.  
      1558 Generated on: 2007-11-27 16:36 UTC.  
    1556 1558 Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.  
    1557 1559  
  • trunk/doc/source/Manual.rst

    r257 r340  
    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   got it working next time.  
    533    
    534   This technique is most useful for data files (see the ``Tree`` class below for a  
    535   way to build a ``TOC`` from a directory tree), and for runtime options. The options  
    536   the run executables understand are:  
    537    
    538   +---------------+-----------------------+-------------------------------+-------------------------------------------------------------------------------------------------------+  
    539   | **Option**    | **Description**       | **Example**                   | **Notes**                                                                                             |  
    540   +===============+=======================+===============================+=======================================================================================================+  
    541   | v             | Verbose imports       | ('v', '', 'OPTION')           | Same as Python -v ...                                                                                 |  
    542   +---------------+-----------------------+-------------------------------+-------------------------------------------------------------------------------------------------------+  
    543   | u             | Unbuffered stdio      | ('u', '', 'OPTION')           | Same as Python -u ...                                                                                 |  
    544   +---------------+-----------------------+-------------------------------+-------------------------------------------------------------------------------------------------------+  
    545   | W spec        | Warning option        | ('W ignore', '', 'OPTION')    | Python 2.1+ only.                                                                                     |  
    546   +---------------+-----------------------+-------------------------------+-------------------------------------------------------------------------------------------------------+  
    547   | s    &nbs