cpython/Tools/freeze
Guido van Rossum ce7695191f Simplified version of a patch by Chih-Hao Huang, who wrote:
"""
When there are additional Setup files, specified by -e option of freeze,
checkextenstions.py assumes that *.o, *.a, -Lpath, and -Rpath are all
relative to where the Setup file is. select() inserts the path to the
Setup file to make them absolute. However, the assumption is not true.
There are cases that absolute paths are specified for them. The inserted
prefix, by select(), results in error.

The following fix check for absolute paths. The assumption is: an
absolute path begins with either '/' or '$'. In the latter case, it is
from the environmental variable. (Variables defined locally in the Setup
file have already been handled by expandvars())
"""

My version of the patch has been verified by Charles Waldman (a
colleague of Chih-Hao).
1999-06-23 21:37:57 +00:00
..
.cvsignore Ignore cruft generating by the test run for hello.py. 1998-08-25 15:27:36 +00:00
bkfile.py New version, with contributions from Sjoerd Mullender and Mark Hammond. 1998-08-25 14:06:55 +00:00
checkextensions_win32.py New version, with contributions from Sjoerd Mullender and Mark Hammond. 1998-08-25 14:06:55 +00:00
checkextensions.py Simplified version of a patch by Chih-Hao Huang, who wrote: 1999-06-23 21:37:57 +00:00
extensions_win32.ini New version, with contributions from Sjoerd Mullender and Mark Hammond. 1998-08-25 14:06:55 +00:00
freeze.py Bug submitted by Wayne Knowles, who writes: 1999-03-12 22:07:05 +00:00
hello.py # Accidentally checked in a test version of this file with a bogus 1999-02-16 23:05:46 +00:00
makeconfig.py Totally new "freeze" program. 1994-10-03 16:33:08 +00:00
makefreeze.py New version, with contributions from Sjoerd Mullender and Mark Hammond. 1998-08-25 14:06:55 +00:00
makemakefile.py Jonathan Giddy: 1998-06-12 14:09:34 +00:00
modulefinder.py Fix for modulefinder so that it prints all modules an unknown module 1998-12-22 13:44:01 +00:00
parsesetup.py Totally new "freeze" program. 1994-10-03 16:33:08 +00:00
README New version, with contributions from Sjoerd Mullender and Mark Hammond. 1998-08-25 14:06:55 +00:00
win32.html Additions for Mark Hammond's Win32 specific hacks. 1998-05-19 20:18:37 +00:00
winmakemakefile.py Patch submitted by Toby Dickenson and approved by Mark Hammond. 1999-06-21 22:36:53 +00:00

THE FREEZE SCRIPT
=================

(Directions for Windows are at the end of this file.)


What is Freeze?
---------------

Freeze make it possible to ship arbitrary Python programs to people
who don't have Python.  The shipped file (called a "frozen" version of
your Python program) is an executable, so this only works if your
platform is compatible with that on the receiving end (this is usually
a matter of having the same major operating system revision and CPU
type).

The shipped file contains a Python interpreter and large portions of
the Python run-time.  Some measures have been taken to avoid linking
unneeded modules, but the resulting binary is usually not small.

The Python source code of your program (and of the library modules
written in Python that it uses) is not included in the binary --
instead, the compiled byte-code (the instruction stream used
internally by the interpreter) is incorporated.  This gives some
protection of your Python source code, though not much -- a
disassembler for Python byte-code is available in the standard Python
library.  At least someone running "strings" on your binary won't see
the source.


How does Freeze know which modules to include?
----------------------------------------------

Previous versions of Freeze used a pretty simple-minded algorithm to
find the modules that your program uses, essentially searching for
lines starting with the word "import".  It was pretty easy to trick it
into making mistakes, either missing valid import statements, or
mistaking string literals (e.g. doc strings) for import statements.

This has been remedied: Freeze now uses the regular Python parser to
parse the program (and all its modules) and scans the generated byte
code for IMPORT instructions.  It may still be confused -- it will not
know about calls to the __import__ built-in function, or about import
statements constructed on the fly and executed using the 'exec'
statement, and it will consider import statements even when they are
unreachable (e.g. "if 0: import foobar").

This new version of Freeze also knows about Python's new package
import mechanism, and uses exactly the same rules to find imported
modules and packages.  One exception: if you write 'from package
import *', Python will look into the __all__ variable of the package
to determine which modules are to be imported, while Freeze will do a
directory listing.

One tricky issue: Freeze assumes that the Python interpreter and
environment you're using to run Freeze is the same one that would be
used to run your program, which should also be the same whose sources
and installed files you will learn about in the next section.  In
particular, your PYTHONPATH setting should be the same as for running
your program locally.  (Tip: if the program doesn't run when you type
"python hello.py" there's little chance of getting the frozen version
to run.)


How do I use Freeze?
--------------------

Normally, you should be able to use it as follows:

	python freeze.py hello.py

where hello.py is your program and freeze.py is the main file of
Freeze (in actuality, you'll probably specify an absolute pathname
such as /usr/joe/python/Tools/freeze/freeze.py).


What do I do next?
------------------

Freeze creates a number of files: frozen.c, config.c and Makefile,
plus one file for each Python module that gets included named
M_<module>.c.  To produce the frozen version of your program, you can
simply type "make".  This should produce a binary file.  If the
filename argument to Freeze was "hello.py", the binary will be called
"hello".

Note: you can use the -o option to freeze to specify an alternative
directory where these files are created. This makes it easier to
clean up after you've shipped the frozen binary.  You should invoke
"make" in the given directory.


Freezing Tkinter programs
-------------------------

Unfortunately, it is currently not possible to freeze programs that
use Tkinter.  It *seems* to work, but when you ship the frozen program 
to a site without a Tcl/Tk installation, it will fail with a complaint 
about missing Tcl/Tk initialization files.

A workaround would be possible, in which the Tcl/Tk library files are
incorporated in a frozen Python module as string literals and written
to a temporary location when the program runs; this is currently left
as an exercise for the reader.  (If you implement this, please post to
the Python newsgroup!)

Of course, you can also simply require that Tcl/Tk is required on the
target installation.


A warning against shared library modules
----------------------------------------

When your Python installation uses shared library modules, these will
not be incorporated in the frozen program.  Again, the frozen program
will work when you test it, but it won't work when you ship it to a
site without a Python installation.

Freeze prints a warning when this is the case at the end of the
freezing process:

	Warning: unknown modules remain: ...

When this occurs, the best thing to do is usually to rebuild Python
using static linking only.


Troubleshooting
---------------

If you have trouble using Freeze for a large program, it's probably
best to start playing with a really simple program first (like the file
hello.py).  If you can't get that to work there's something
fundamentally wrong -- perhaps you haven't installed Python.  To do a
proper install, you should do "make install" in the Python root
directory.


Usage under Windows 95 or NT
----------------------------

Under Windows 95 or NT, you *must* use the -p option and point it to
the top of the Python source tree.

WARNING: the resulting executable is not self-contained; it requires
the Python DLL, currently PYTHON15.DLL (it does not require the
standard library of .py files though).  It may also require one or
more extension modules loaded from .DLL or .PYD files; the module
names are printed in the warning message about remaining unknown
modules.

The driver script generates a Makefile that works with the Microsoft
command line C compiler (CL).  To compile, run "nmake"; this will
build a target "hello.exe" if the source was "hello.py".  Only the
files frozenmain.c and frozen.c are used; no config.c is generated or
used, since the standard DLL is used.

In order for this to work, you must have built Python using the VC++
(Developer Studio) 5.0 compiler.  The provided project builds
python15.lib in the subdirectory pcbuild\Release of thje Python source
tree, and this is where the generated Makefile expects it to be.  If
this is not the case, you can edit the Makefile or (probably better)
winmakemakefile.py (e.g., if you are using the 4.2 compiler, the
python15.lib file is generated in the subdirectory vc40 of the Python
source tree).

You can freeze programs that use Tkinter, but Tcl/Tk must be installed
on the target system.

It is possible to create frozen programs that don't have a console
window, by specifying the option '-s windows'.

--Guido van Rossum (home page: http://www.python.org/~guido/)