Sitemap

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

Bug Tracker

Getting Started

Contents:

Installing Installer

First, unpack the archive wherever you want to. Installer is not a Python package, so it doesn't need to go in site-packages, or have a .pth file. You will be using a couple of scripts in the root directory, and these will find everything they need from their own location. Since you will be running a couple scripts, you might want to keep the paths to these scripts short (don't install in a deeply nested subdirectory).

You will need a separate copy for each Python version you wish to work with (or you'll need to rerun Configure.py every time you switch).

I - Building the runtime executables

Windows users can skip this step, because all of Python is contained in pythonXX.dll, and Installer will use your pythonXX.dll.

On non-Windows platforms, the first thing to do is build the runtime executables.

Change to the source/linux subdirectory. Run Make.py [-n|-e] and then make. This will produce support/run and support/run_d. If you have multiple versions of Python, the Python you use to run Make.py is the one whose configuration is used.

The -n and -e options set a non-elf or elf flag in your config.dat. As of 5b5, the executable will try both strategies, and this flag just sets how you want your executables built. In the elf strategy, the archive is concatenated to the executable. In the non-elf strategy, the executable expects an archive with the same name as itself in the executable's directory. Note that the executable chases down symbolic links before determining it's name and directory, so putting the archive in the same directory as the symbolic link will not work.

Windows distributions come with four executables in the support dir: run.exe, run_d.exe, runw.exe and runw_d.exe. There are also two dlls, inprocsrvr.dll and inprocsrvr_d.dll for doing in-process COM servers. All of these can be rebuilt from the MSVC workspace in source/windows. Please be careful of MS's optimizations - I suggest you disable them in the release builds. (I'm fairly sure these could be built using MinGW, too, but I haven't yet tried it).

Note that the _d suffix does not mean the same as it does with extension modules - you don't need a debug build of Python to use them.

II - Configuring your Installer setup

In the root directory, run Configure.py. This saves some information into config.dat that would otherwise be recomputed every time. It can be rerun at any time if your configuration changes. It must be run before trying to build anything.

III - Create a spec file for your project

[For Windows COM server support, see below.]

The root directory has a script Makespec.py for this purpose.

       >python Makespec.py [OPTIONS] script...
      
Where allowed options are:
--onefile
produce a single file deployment (see below).
--onedir
produce a single directory deployment (default).
--tk
include TCL/TK in the deployment.
--ascii
do not include encodings. The default (on Python versions with unicode support) is now to include all encodings.
--debug
use debug (verbose) versions of the executables.
--noconsole
Windows: use the Windows subsystem executable (runw.exe or runw_d.exe).
--strip
the executable and all shared libraries will be run through strip. Note that cygwin's strip tends to render normal Win32 dlls unusable.
--upx
if you have UPX installed (detected by Configure), this will use it to compress your executable (and, on Windows, your dlls). See note below.
--out directory
create the spec file in directory. If not specified, and the current directory is Installer's root directory, an output subdirectory will be created. Otherwise the current directory is used.
--icon file.ico
add file.ico to the executable's resources (Windows only).
--icon file.exe,n
add the nth incon in file.exe to the executable's resources (Windows only).
--version verfile
add verfile as a version resource to the executable (Windows only).
--name name
optional name to assign to the project (from which the spec file name is generated). If omitted, the basename of the (first) script is used.
[For building with optimization on (like Python -O), see below.]

For simple projects, the generated spec file will probably be sufficient. For more complex projects, it should be regarded as a template. The spec file is actually Python code, and modifying it should be much easier than working with the config files used in earlier Installer releases. See Spec Files for details.

IV - Build your project

      >python Build.py specfile
      
A buildproject subdirectory will be created in the specfile's directory. This is a private workspace so that Build can act like a makefile. Any named targets will appear in the specfile's directory. For --onedir configurations, that include distproject, which is the directory you're interested in. For a --onefile, the executable will be in the specfile's directory.

In most cases, this will be all you have to do. If not, see When things go wrong and be sure to read the introduction to Spec Files.

Windows COM Server support


       >python MakeCOMServer.py [OPTION] script...
      
will generate a new script drivescript.py and a spec file for the script.

[For Win32all builds before 151, use MakeCOMServer_old.py.]

These options are allowed:

--debug
Use the verbose version of the executable.
--verbose
Register the COM server(s) with the quiet flag off.
--ascii
do not include encodings (this is passed through to Makespec).
--out dir
Generate the driver script and spec file in dir.

Now run Build.py on the generated spec file.

If you have the win32dbg package installed, you can use it with the generated COM server. In the driver script, set debug=1 in the registration line.

Warnings: the inprocess COM server support will not work when the client process already has Python loaded. It would be rather tricky to non-obtrusively hook into an already running Python, but the show-stopper is that the Python/C API won't let me find out which interpreter instance I should hook into. (If this is important to you, you might experiment with using apartment threading, which seems the best possibility to get this to work). To use a "frozen" COM server from a Python process, you'll have to load it as an exe:

      o = win32com.client.Dispatch(progid,
                       clsctx=pythoncom.CLSCTX_LOCAL_SERVER)
      

MakeCOMServer also assumes that your top level code (registration etc.) is "normal". If it's not, you will have to edit the generated script.

Building Optimized

There are two facets to running optimized: gathering .pyo's, and setting the Py_OptimizeFlag. Installer will gather .pyo's if it is run optimized:

       >python -O Build.py ...
      

The Py_OptimizeFlag will be set if you use a ('O','','OPTION') in one of the TOCs building the EXE.

      exe = EXE(pyz,
                a.scripts + [('O','','OPTION')],
                ...
      

See Spec Files for details.

A Note on using UPX

On both Windows and Linux, UPX can give truly startling compression - the days of fitting something useful on a diskette are not gone forever! Installer has been tested with UPX 1.24 without problems. Just get it and install it on your PATH, then rerun configure. For Windows, that's all you need to know.

For Linux, a bit more discussion is in order. First, UPX is only useful on executables, not shared libs. Installer accounts for that, but to get the full benefit, you might rebuild Python with more things statically linked.

More importantly, when run finds that it's sys.argv[0] does not contain a path, it will use /proc/pid/exe to find itself (if it can). This happens, for example, when executed by Apache. If it has been upx-ed, this symbolic link points to the tempfile created by the upx stub and Installer will fail (please see the UPX docs for more information). So for now, at least, you can't use upx for CGI's executed by Apache. Otherwise, you can ignore the warnings in the UPX docs, since what Installer opens is the executable Installer created, not the temporary upx-created executable.

A Note on --onefile

A --onefile works by packing all the shared libs / dlls into the archive attached to the executable (or next to the executable in a nonelf configuration). When first started, it finds that it needs to extract these files before it can run "for real". That's because locating and loading a shared lib or linked-in dll is a system level action, not user-level. Before 5b5, a --onefile would extract into the executable's directory (if possible). With 5b5 it now always uses a temporary directory (_MEIpid) in the user's temp directory. It then executes itself again, setting things up so the system will be able to load the shared libs / dlls. When executing is complete, it recursively removes the entire directory it created.

This has a number of implications.

  • You can run multiple copies - they won't collide.
  • Running multiple copies will be rather expensive to the system (nothing is shared).
  • If you're using the cheat of adding user data as 'BINARY', it will be in os.environ['_MEIPASS2'], not the executable's directory.
  • On Windows, using Task Manager to kill the parent process will leave the directory behind.
  • On *nix, a kill -9 (or crash) will leave the directory behind.
  • Otherwise, on both platforms, the directory will be recursively deleted.
  • So any files you might create in os.environ['_MEIPASS2'] will be deleted.
  • The executable can be in a protected or read-only directory.

While I am not a security expert, I believe the scheme is reasonably safe. If for some reason, the _MEIpid directory already exists, the executable will fail. It is created mode 0700, so only the one user can modify it (on *nix, of course). If the executable does a setuid root, a determined hacker could possibly (given enough tries) introduce a malicious lookalike of one of the shared libraries during the hole between when the library is extracted and when it gets loaded by the execvp'd process. So maybe you shouldn't do setuid root programs using --onefile.

Sponsorship

Please show your appreciation and help fund continued development of Installer by making a contribution. To date, the contributions I have received amount to a tiny bit more than I pay for the hosting of this site for one month. If Installer is contributing to your commercial success, please let your conscience be your guide. I really do not want to go to a dual-licensed model.

License

This code is licensed under the MIT license. Please see license.txt. Note that I do not consider that Installer includes significant portions of itself in the executables it produces, so I make no restrictions on their licensing.

Reporting Bugs

Report bugs (or feature requests, or send patches) here. Please make sure you set Product to Installer. (If you choose not to become a registered user, please include some contact information in the report itself.) The bug tracker does not send out email, and email addresses are obsfucated in the user list.

Subscribe to the Installer Mailing List to discuss Installer related issues. Having been discovered by the SPAM monsters, you now need to join before you can post (it is a low volume list).

copyright 1999-2002
McMillan Enterprises, Inc.