1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
<HTML>
<HEAD>
<TITLE>Creating standalone applications with Python</TITLE>
</HEAD>
<BODY>
<H1>Creating standalone applications with Python</H1>
<HR>
With the <EM>macfreeze</EM> script you can <i>freeze</i> a Python
script: create a fullblown Macintosh application that is completely
self-contained. A frozen application is similar to an applet (see <a
href="example2.html">Example 2</a> for information on creating applets),
but where an applet depends on an existing Python installation for its
standard modules and interpreter core, a frozen program does not,
because it incorporates everything in a single binary. This means you
can copy a frozen program to a machine that does not have Python
installed and it will work, which is not true for an applet. <p>
There are two ways to create a frozen application: through the
CodeWarrior development environment or without any development
environment. The former method is more versatile and may result in
smaller binaries, because you can better customize what is included in
your eventual application. The latter method builds an application by
glueing together the various <em>.slb</em> shared libraries that come
with a binary Python installation into a single file. This method of
freezing, which does not require you to spend money on a development
environment, is unique to MacPython, incidentally, on other platforms
you will always need a C compiler and linker. <p>
<h2>Common steps</h2>
The two processes have a number of steps in common. When you start
<code>Mac:Tools:macfreeze:macfreeze.py</code> you are asked for the
script file, and you can select which type of freeze to do. The first
time you should always choose <em>report only</em>, which will produce a
listing of modules and where they are included from in the console
window. Macfreeze actually parses all modules, so it may crash in the
process. If it does try again with a higher debug value, this should
show you where it crashes. <p>
For more elaborate programs you will often see that freeze includes
modules you don't need (because they are for a different platform, for
instance) or that it cannot find all your modules (because you modify
<code>sys.path</code> early in your initialization). It is possible to
include directives to tell macfreeze to add items to the search path and
include or exclude certain modules. All your directives should be in the
main script file. <p>
Directives have the following form:
<pre>
# macfreeze: command argument
</pre>
The trigger <code>macfreeze:</code> must be spelled exactly like that,
but the whitespace can be any combination of spaces and tabs. Macfreeze
understands the following directives:
<DL>
<DT> <code>path</code>
<DD> Prepend a folder to <code>sys.path</code>. The argument is a
pathname, which should probably be relative (starting with a colon) and
is interpreted relative to the folder where the script lives.
<DT> <code>include</code>
<DD> Include a module. The module can either be given by filename or by
module name, in which case it is looked up through the normal method.
<DT> <code>exclude</code>
<DD> Exclude a module. The module must be given by modulename. Even when
freeze deems the module necessary it will not be included in the
application.
</DL>
There is actually a fourth way that macfreeze can operate: it can be used
to generate only the resource file containing the compiled <code>PYC</code>
resources. This may be useful if you have embedded Python in your own
application. The resource file generated is the same as for the CodeWarrior
generation process. <p>
<h2>Freezing with CodeWarrior</h2>
To freeze with CodeWarrior you need CodeWarrior, obviously, and a full
source distribution of Python. You select the <em>Codewarrior source and
project</em> option. You specify an output folder, which is by default
the name of your script with <code>.py</code> removed and
<code>build.</code> prepended. If the output folder does not exist yet
it is created, and a template project file and bundle resource file are
deposited there. Next, a source file <code>macfreezeconfig.c</code> is
created which includes all builtin modules your script uses, and a
resource file <code>frozenmodules.rsrc</code> which contains the
<code>PYC</code> resources for all your Python modules. <p>
The project expects to live in a folder one level below the Python root
folder, so the next thing you should do is move the build folder there.
It is a good idea to leave an alias with the same name in the original
location: when you run freeze again it will regenerate the
<code>frozenmodules.rsrc</code> file but not the project and bundle
files. This is probably what you want: if you modify your python sources
you have to re-freeze, but you may have changed the project and bundle
files, so you don't want to regenrate them. <p>
An alternative is to leave the build folder where it is, but then you
have to adapt the search path in the project. <p>
The project is set up to include all the standard builtin modules, but
the CW linker is smart enough to exclude any object code that isn't
referenced. Still, it may be worthwhile to remove any sources for
modules that you are sure are not used to cut back on compilation time.
You may also want to examine the various resource files (for Tcl/Tk, for
instance): the loader has no way to know that these aren't used. <p>
You may also need to add sourcefiles if your script uses non-standard
builtin modules, like anything from the <code>Extensions</code> folder. <p>
The <code>frozenbundle.rsrc</code> resource file contains the bundle
information. It is almost identical to the bundle file used for applets,
with the exception that it sets the <code>sys.path</code> initialization
to <code>$(APPLICATION)</code> only. This means that all modules will only
be looked for in PYC resources in your application. <p>
<h2>Freezing without CodeWarrior</h2>
This does not work yet.
</BODY>
</HTML>
|