| 1 | THE FREEZE SCRIPT | 
|---|
| 2 | ================= | 
|---|
| 3 |  | 
|---|
| 4 | (Directions for Windows are at the end of this file.) | 
|---|
| 5 |  | 
|---|
| 6 |  | 
|---|
| 7 | What is Freeze? | 
|---|
| 8 | --------------- | 
|---|
| 9 |  | 
|---|
| 10 | Freeze make it possible to ship arbitrary Python programs to people | 
|---|
| 11 | who don't have Python.  The shipped file (called a "frozen" version of | 
|---|
| 12 | your Python program) is an executable, so this only works if your | 
|---|
| 13 | platform is compatible with that on the receiving end (this is usually | 
|---|
| 14 | a matter of having the same major operating system revision and CPU | 
|---|
| 15 | type). | 
|---|
| 16 |  | 
|---|
| 17 | The shipped file contains a Python interpreter and large portions of | 
|---|
| 18 | the Python run-time.  Some measures have been taken to avoid linking | 
|---|
| 19 | unneeded modules, but the resulting binary is usually not small. | 
|---|
| 20 |  | 
|---|
| 21 | The Python source code of your program (and of the library modules | 
|---|
| 22 | written in Python that it uses) is not included in the binary -- | 
|---|
| 23 | instead, the compiled byte-code (the instruction stream used | 
|---|
| 24 | internally by the interpreter) is incorporated.  This gives some | 
|---|
| 25 | protection of your Python source code, though not much -- a | 
|---|
| 26 | disassembler for Python byte-code is available in the standard Python | 
|---|
| 27 | library.  At least someone running "strings" on your binary won't see | 
|---|
| 28 | the source. | 
|---|
| 29 |  | 
|---|
| 30 |  | 
|---|
| 31 | How does Freeze know which modules to include? | 
|---|
| 32 | ---------------------------------------------- | 
|---|
| 33 |  | 
|---|
| 34 | Previous versions of Freeze used a pretty simple-minded algorithm to | 
|---|
| 35 | find the modules that your program uses, essentially searching for | 
|---|
| 36 | lines starting with the word "import".  It was pretty easy to trick it | 
|---|
| 37 | into making mistakes, either missing valid import statements, or | 
|---|
| 38 | mistaking string literals (e.g. doc strings) for import statements. | 
|---|
| 39 |  | 
|---|
| 40 | This has been remedied: Freeze now uses the regular Python parser to | 
|---|
| 41 | parse the program (and all its modules) and scans the generated byte | 
|---|
| 42 | code for IMPORT instructions.  It may still be confused -- it will not | 
|---|
| 43 | know about calls to the __import__ built-in function, or about import | 
|---|
| 44 | statements constructed on the fly and executed using the 'exec' | 
|---|
| 45 | statement, and it will consider import statements even when they are | 
|---|
| 46 | unreachable (e.g. "if 0: import foobar"). | 
|---|
| 47 |  | 
|---|
| 48 | This new version of Freeze also knows about Python's new package | 
|---|
| 49 | import mechanism, and uses exactly the same rules to find imported | 
|---|
| 50 | modules and packages.  One exception: if you write 'from package | 
|---|
| 51 | import *', Python will look into the __all__ variable of the package | 
|---|
| 52 | to determine which modules are to be imported, while Freeze will do a | 
|---|
| 53 | directory listing. | 
|---|
| 54 |  | 
|---|
| 55 | One tricky issue: Freeze assumes that the Python interpreter and | 
|---|
| 56 | environment you're using to run Freeze is the same one that would be | 
|---|
| 57 | used to run your program, which should also be the same whose sources | 
|---|
| 58 | and installed files you will learn about in the next section.  In | 
|---|
| 59 | particular, your PYTHONPATH setting should be the same as for running | 
|---|
| 60 | your program locally.  (Tip: if the program doesn't run when you type | 
|---|
| 61 | "python hello.py" there's little chance of getting the frozen version | 
|---|
| 62 | to run.) | 
|---|
| 63 |  | 
|---|
| 64 |  | 
|---|
| 65 | How do I use Freeze? | 
|---|
| 66 | -------------------- | 
|---|
| 67 |  | 
|---|
| 68 | Normally, you should be able to use it as follows: | 
|---|
| 69 |  | 
|---|
| 70 | python freeze.py hello.py | 
|---|
| 71 |  | 
|---|
| 72 | where hello.py is your program and freeze.py is the main file of | 
|---|
| 73 | Freeze (in actuality, you'll probably specify an absolute pathname | 
|---|
| 74 | such as /usr/joe/python/Tools/freeze/freeze.py). | 
|---|
| 75 |  | 
|---|
| 76 |  | 
|---|
| 77 | What do I do next? | 
|---|
| 78 | ------------------ | 
|---|
| 79 |  | 
|---|
| 80 | Freeze creates a number of files: frozen.c, config.c and Makefile, | 
|---|
| 81 | plus one file for each Python module that gets included named | 
|---|
| 82 | M_<module>.c.  To produce the frozen version of your program, you can | 
|---|
| 83 | simply type "make".  This should produce a binary file.  If the | 
|---|
| 84 | filename argument to Freeze was "hello.py", the binary will be called | 
|---|
| 85 | "hello". | 
|---|
| 86 |  | 
|---|
| 87 | Note: you can use the -o option to freeze to specify an alternative | 
|---|
| 88 | directory where these files are created. This makes it easier to | 
|---|
| 89 | clean up after you've shipped the frozen binary.  You should invoke | 
|---|
| 90 | "make" in the given directory. | 
|---|
| 91 |  | 
|---|
| 92 |  | 
|---|
| 93 | Freezing Tkinter programs | 
|---|
| 94 | ------------------------- | 
|---|
| 95 |  | 
|---|
| 96 | Unfortunately, it is currently not possible to freeze programs that | 
|---|
| 97 | use Tkinter without a Tcl/Tk installation. The best way to ship a | 
|---|
| 98 | frozen Tkinter program is to decide in advance where you are going | 
|---|
| 99 | to place the Tcl and Tk library files in the distributed setup, and | 
|---|
| 100 | then declare these directories in your frozen Python program using | 
|---|
| 101 | the TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. | 
|---|
| 102 |  | 
|---|
| 103 | For example, assume you will ship your frozen program in the directory | 
|---|
| 104 | <root>/bin/windows-x86 and will place your Tcl library files | 
|---|
| 105 | in <root>/lib/tcl8.2 and your Tk library files in <root>/lib/tk8.2. Then | 
|---|
| 106 | placing the following lines in your frozen Python script before importing | 
|---|
| 107 | Tkinter or Tix would set the environment correctly for Tcl/Tk/Tix: | 
|---|
| 108 |  | 
|---|
| 109 | import os | 
|---|
| 110 | import os.path | 
|---|
| 111 | RootDir = os.path.dirname(os.path.dirname(os.getcwd())) | 
|---|
| 112 |  | 
|---|
| 113 | import sys | 
|---|
| 114 | if sys.platform == "win32": | 
|---|
| 115 | sys.path = ['', '..\\..\\lib\\python-2.0'] | 
|---|
| 116 | os.environ['TCL_LIBRARY'] = RootDir + '\\lib\\tcl8.2' | 
|---|
| 117 | os.environ['TK_LIBRARY'] = RootDir + '\\lib\\tk8.2' | 
|---|
| 118 | os.environ['TIX_LIBRARY'] = RootDir + '\\lib\\tix8.1' | 
|---|
| 119 | elif sys.platform == "linux2": | 
|---|
| 120 | sys.path = ['', '../../lib/python-2.0'] | 
|---|
| 121 | os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2' | 
|---|
| 122 | os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2' | 
|---|
| 123 | os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1' | 
|---|
| 124 | elif sys.platform == "solaris": | 
|---|
| 125 | sys.path = ['', '../../lib/python-2.0'] | 
|---|
| 126 | os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2' | 
|---|
| 127 | os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2' | 
|---|
| 128 | os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1' | 
|---|
| 129 |  | 
|---|
| 130 | This also adds <root>/lib/python-2.0 to your Python path | 
|---|
| 131 | for any Python files such as _tkinter.pyd you may need. | 
|---|
| 132 |  | 
|---|
| 133 | Note that the dynamic libraries (such as tcl82.dll tk82.dll python20.dll | 
|---|
| 134 | under Windows, or libtcl8.2.so and libtcl8.2.so under Unix) are required | 
|---|
| 135 | at program load time, and are searched by the operating system loader | 
|---|
| 136 | before Python can be started. Under Windows, the environment | 
|---|
| 137 | variable PATH is consulted, and under Unix, it may be the | 
|---|
| 138 | environment variable LD_LIBRARY_PATH and/or the system | 
|---|
| 139 | shared library cache (ld.so). An additional preferred directory for | 
|---|
| 140 | finding the dynamic libraries is built into the .dll or .so files at | 
|---|
| 141 | compile time - see the LIB_RUNTIME_DIR variable in the Tcl makefile. | 
|---|
| 142 | The OS must find the dynamic libraries or your frozen program won't start. | 
|---|
| 143 | Usually I make sure that the .so or .dll files are in the same directory | 
|---|
| 144 | as the executable, but this may not be foolproof. | 
|---|
| 145 |  | 
|---|
| 146 | A workaround to installing your Tcl library files with your frozen | 
|---|
| 147 | executable would be possible, in which the Tcl/Tk library files are | 
|---|
| 148 | incorporated in a frozen Python module as string literals and written | 
|---|
| 149 | to a temporary location when the program runs; this is currently left | 
|---|
| 150 | as an exercise for the reader.  An easier approach is to freeze the | 
|---|
| 151 | Tcl/Tk/Tix code into the dynamic libraries using the Tcl ET code, | 
|---|
| 152 | or the Tix Stand-Alone-Module code. Of course, you can also simply | 
|---|
| 153 | require that Tcl/Tk is required on the target installation, but be | 
|---|
| 154 | careful that the version corresponds. | 
|---|
| 155 |  | 
|---|
| 156 | There are some caveats using frozen Tkinter applications: | 
|---|
| 157 | Under Windows if you use the -s windows option, writing | 
|---|
| 158 | to stdout or stderr is an error. | 
|---|
| 159 | The Tcl [info nameofexecutable] will be set to where the | 
|---|
| 160 | program was frozen, not where it is run from. | 
|---|
| 161 | The global variables argc and argv do not exist. | 
|---|
| 162 |  | 
|---|
| 163 |  | 
|---|
| 164 | A warning about shared library modules | 
|---|
| 165 | -------------------------------------- | 
|---|
| 166 |  | 
|---|
| 167 | When your Python installation uses shared library modules such as | 
|---|
| 168 | _tkinter.pyd, these will not be incorporated in the frozen program. | 
|---|
| 169 | Again, the frozen program will work when you test it, but it won't | 
|---|
| 170 | work when you ship it to a site without a Python installation. | 
|---|
| 171 |  | 
|---|
| 172 | Freeze prints a warning when this is the case at the end of the | 
|---|
| 173 | freezing process: | 
|---|
| 174 |  | 
|---|
| 175 | Warning: unknown modules remain: ... | 
|---|
| 176 |  | 
|---|
| 177 | When this occurs, the best thing to do is usually to rebuild Python | 
|---|
| 178 | using static linking only. Or use the approach described in the previous | 
|---|
| 179 | section to declare a library path using sys.path, and place the modules | 
|---|
| 180 | such as _tkinter.pyd there. | 
|---|
| 181 |  | 
|---|
| 182 |  | 
|---|
| 183 | Troubleshooting | 
|---|
| 184 | --------------- | 
|---|
| 185 |  | 
|---|
| 186 | If you have trouble using Freeze for a large program, it's probably | 
|---|
| 187 | best to start playing with a really simple program first (like the file | 
|---|
| 188 | hello.py).  If you can't get that to work there's something | 
|---|
| 189 | fundamentally wrong -- perhaps you haven't installed Python.  To do a | 
|---|
| 190 | proper install, you should do "make install" in the Python root | 
|---|
| 191 | directory. | 
|---|
| 192 |  | 
|---|
| 193 |  | 
|---|
| 194 | Usage under Windows 95 or NT | 
|---|
| 195 | ---------------------------- | 
|---|
| 196 |  | 
|---|
| 197 | Under Windows 95 or NT, you *must* use the -p option and point it to | 
|---|
| 198 | the top of the Python source tree. | 
|---|
| 199 |  | 
|---|
| 200 | WARNING: the resulting executable is not self-contained; it requires | 
|---|
| 201 | the Python DLL, currently PYTHON20.DLL (it does not require the | 
|---|
| 202 | standard library of .py files though).  It may also require one or | 
|---|
| 203 | more extension modules loaded from .DLL or .PYD files; the module | 
|---|
| 204 | names are printed in the warning message about remaining unknown | 
|---|
| 205 | modules. | 
|---|
| 206 |  | 
|---|
| 207 | The driver script generates a Makefile that works with the Microsoft | 
|---|
| 208 | command line C compiler (CL).  To compile, run "nmake"; this will | 
|---|
| 209 | build a target "hello.exe" if the source was "hello.py".  Only the | 
|---|
| 210 | files frozenmain.c and frozen.c are used; no config.c is generated or | 
|---|
| 211 | used, since the standard DLL is used. | 
|---|
| 212 |  | 
|---|
| 213 | In order for this to work, you must have built Python using the VC++ | 
|---|
| 214 | (Developer Studio) 5.0 compiler.  The provided project builds | 
|---|
| 215 | python20.lib in the subdirectory pcbuild\Release of thje Python source | 
|---|
| 216 | tree, and this is where the generated Makefile expects it to be.  If | 
|---|
| 217 | this is not the case, you can edit the Makefile or (probably better) | 
|---|
| 218 | winmakemakefile.py (e.g., if you are using the 4.2 compiler, the | 
|---|
| 219 | python20.lib file is generated in the subdirectory vc40 of the Python | 
|---|
| 220 | source tree). | 
|---|
| 221 |  | 
|---|
| 222 | It is possible to create frozen programs that don't have a console | 
|---|
| 223 | window, by specifying the option '-s windows'. See the Usage below. | 
|---|
| 224 |  | 
|---|
| 225 | Usage | 
|---|
| 226 | ----- | 
|---|
| 227 |  | 
|---|
| 228 | Here is a list of all of the options (taken from freeze.__doc__): | 
|---|
| 229 |  | 
|---|
| 230 | usage: freeze [options...] script [module]... | 
|---|
| 231 |  | 
|---|
| 232 | Options: | 
|---|
| 233 | -p prefix:    This is the prefix used when you ran ``make install'' | 
|---|
| 234 | in the Python build directory. | 
|---|
| 235 | (If you never ran this, freeze won't work.) | 
|---|
| 236 | The default is whatever sys.prefix evaluates to. | 
|---|
| 237 | It can also be the top directory of the Python source | 
|---|
| 238 | tree; then -P must point to the build tree. | 
|---|
| 239 |  | 
|---|
| 240 | -P exec_prefix: Like -p but this is the 'exec_prefix', used to | 
|---|
| 241 | install objects etc.  The default is whatever sys.exec_prefix | 
|---|
| 242 | evaluates to, or the -p argument if given. | 
|---|
| 243 | If -p points to the Python source tree, -P must point | 
|---|
| 244 | to the build tree, if different. | 
|---|
| 245 |  | 
|---|
| 246 | -e extension: A directory containing additional .o files that | 
|---|
| 247 | may be used to resolve modules.  This directory | 
|---|
| 248 | should also have a Setup file describing the .o files. | 
|---|
| 249 | On Windows, the name of a .INI file describing one | 
|---|
| 250 | or more extensions is passed. | 
|---|
| 251 | More than one -e option may be given. | 
|---|
| 252 |  | 
|---|
| 253 | -o dir:       Directory where the output files are created; default '.'. | 
|---|
| 254 |  | 
|---|
| 255 | -m:           Additional arguments are module names instead of filenames. | 
|---|
| 256 |  | 
|---|
| 257 | -a package=dir: Additional directories to be added to the package's | 
|---|
| 258 | __path__.  Used to simulate directories added by the | 
|---|
| 259 | package at runtime (eg, by OpenGL and win32com). | 
|---|
| 260 | More than one -a option may be given for each package. | 
|---|
| 261 |  | 
|---|
| 262 | -l file:      Pass the file to the linker (windows only) | 
|---|
| 263 |  | 
|---|
| 264 | -d:           Debugging mode for the module finder. | 
|---|
| 265 |  | 
|---|
| 266 | -q:           Make the module finder totally quiet. | 
|---|
| 267 |  | 
|---|
| 268 | -h:           Print this help message. | 
|---|
| 269 |  | 
|---|
| 270 | -x module     Exclude the specified module. | 
|---|
| 271 |  | 
|---|
| 272 | -i filename:  Include a file with additional command line options.  Used | 
|---|
| 273 | to prevent command lines growing beyond the capabilities of | 
|---|
| 274 | the shell/OS.  All arguments specified in filename | 
|---|
| 275 | are read and the -i option replaced with the parsed | 
|---|
| 276 | params (note - quoting args in this file is NOT supported) | 
|---|
| 277 |  | 
|---|
| 278 | -s subsystem: Specify the subsystem (For Windows only.); | 
|---|
| 279 | 'console' (default), 'windows', 'service' or 'com_dll' | 
|---|
| 280 |  | 
|---|
| 281 | -w:           Toggle Windows (NT or 95) behavior. | 
|---|
| 282 | (For debugging only -- on a win32 platform, win32 behavior | 
|---|
| 283 | is automatic.) | 
|---|
| 284 |  | 
|---|
| 285 | Arguments: | 
|---|
| 286 |  | 
|---|
| 287 | script:       The Python script to be executed by the resulting binary. | 
|---|
| 288 |  | 
|---|
| 289 | module ...:   Additional Python modules (referenced by pathname) | 
|---|
| 290 | that will be included in the resulting binary.  These | 
|---|
| 291 | may be .py or .pyc files.  If -m is specified, these are | 
|---|
| 292 | module names that are search in the path instead. | 
|---|
| 293 |  | 
|---|
| 294 |  | 
|---|
| 295 |  | 
|---|
| 296 | --Guido van Rossum (home page: http://www.python.org/~guido/) | 
|---|