|
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/) |