blob: 3d582303049bddc6a233cbf5461e67c6f747ebe7 [file] [log] [blame]
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +00001Python and MPW
2==============
Guido van Rossum8ce65b41994-08-29 08:58:39 +00003
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +00004There is conditional code in Python for MPW. This has been used with
5different compilers at various points in time. Right now it is being
6used to turn the entire interpreter into a shared library on 68K Macs,
Guido van Rossum00effaf1995-02-18 15:04:26 +00007so we can build "applets" (see below). I have used MPW 3.2 and the OpenDoc
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +00008development environment from an OpenDoc CD released in 1984. This
Guido van Rossum00effaf1995-02-18 15:04:26 +00009contains the Symantec C compiler for MPW (version 7.0.4), the
10Universal Headers (version 2.0a1), and early versions of CFM-68K (version 1.0a1)
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +000011(the Code Fragment Manager ported back to the 68K Mac) and
Guido van Rossum00effaf1995-02-18 15:04:26 +000012MixedModeInit (version 1.0d12), which are required to use shared libraries.
Guido van Rossum8ce65b41994-08-29 08:58:39 +000013
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +000014I've created a Makefile that does everything, plus a three-line Build
15script that calls Make and runs its output. The Makefile assumes that
16it lives in a 1-deep subdirectory of the root, so e.g. the Python
17Include directory can be referenced through "::Include". All object
18files are collected in the subsubdirectory Objcode.
Guido van Rossum8ce65b41994-08-29 08:58:39 +000019
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +000020I use these feature test macros:
Guido van Rossum8ce65b41994-08-29 08:58:39 +000021
Guido van Rossum00effaf1995-02-18 15:04:26 +000022MPW for all MPW compilers (e.g. long double in <math.h>)
23__SC__ for things specific to the Symantec C compiler
24 (e.g. doesn't like static forward)
25__CFM68K__ for things specific to CFM-68K
26 (e.g. it requires the use of #pragma lib_export on|off)
27HAVE_UNIVERSAL_HEADERS for things not yet in Think's headers (e.g. UPPs)
28GENERATINGCFM for both PPC and 68K Code Fragment Manager
Guido van Rossum8ce65b41994-08-29 08:58:39 +000029
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +000030MPW is defined in config.h (if it finds that applec is defined);
31HAVE_UNIVERSAL_HEADERS is defined in macglue.h depending on whether it
32thinks we are using Universal Headers. The others are defined by the
33compiler or by the system headers.
Guido van Rossum8ce65b41994-08-29 08:58:39 +000034
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +000035Compiler switches were a nightmare until I found I had to use -b.
36This wasn't mentioned in the CFM-68K docs that came on the OpenDoc
Guido van Rossum00effaf1995-02-18 15:04:26 +000037CD-ROM. Apparently it is only needed for large projects...
Guido van Rossum8ce65b41994-08-29 08:58:39 +000038
Guido van Rossumc0af2aa1994-09-09 12:10:21 +000039
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +000040Warning: Mixing Think C and MPW
41===============================
Guido van Rossumc0af2aa1994-09-09 12:10:21 +000042
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +000043(XXX Need to check what convention SC uses -- I hope it uses Think's.)
Guido van Rossumc0af2aa1994-09-09 12:10:21 +000044
Guido van Rossum1b2fe8e1995-02-17 14:49:28 +000045If you are mixing Think C and MPW, you may experience weird errors in
Guido van Rossum31e76421994-09-16 11:08:31 +000046previously correct modules. These disappear when you throw away the
Guido van Rossumc0af2aa1994-09-09 12:10:21 +000047module's .pyc file. The errors usually have to do with string
48literals containing '\n' or '\r'. The reason is an incompatibility
49between their handling of '\n' and '\r' -- in MPW C, '\n' actually is
50ASCII CR while '\r' is ASCII LF, which is the reverse situation from
51any other ASCII based C implementation. This behaviour is inherited
Guido van Rossum31e76421994-09-16 11:08:31 +000052by Python compiled with MPW C. This is normally not a problem, but
53*binary* files written by one system will be mis-interpreted by the
54other, and this is what happens to the .pyc files. There is no easy
55way to fix this in the source. (This is a real shame, since the
56format of .pyc files was carefully designed to be independent of byte
57order and integer size -- deviations in the ASCII character codes were
58never anticipated.)
Guido van Rossum00effaf1995-02-18 15:04:26 +000059
60
61Building "Applets" for the Mac
62==============================
63
64An "applet" is a tiny application that's written in a scripting language
65but behaves like a real application. The behavior is much like that of
66executable scripts in Unix -- but the implementation is entirely different.
67
68The applet's file can be small because it doesn't contain the actual
69interpreter for the scripting language -- this has to be installed in the
70Extensions folder (usually) before the applet will work. The applet file
71itself only contains a tiny bootstrap program and the script itself --
72possibly "compiled" or otherwise encoded to save on parsing time and space,
73and to make it harder to reverse engineer the script (some people care about
74this).
75
76In Python's case, the Python interpreter, without its main program, is built
77as a shared library that is dropped in the Extensions folder. Some more
78shared libraries must also be present -- these form the C run-time system.
79[[XXX perhaps we should link these in statically with the Python library,
80for simpler distribution???]] On the 68K Mac, two more extensions are needed:
81CFM-68K (the Code Fragment Manager) and MixedModeInit. These provide
82functionality that's built in the Power Mac's OS. It seems that System 7.1.1
83or higher is also required.
84
85The applet file contains a small main program program, plus a 'PYC ' resource
86named __main__ which contains the "compiled" version of the script. A 'PYC '
87resource contains exactly the same data as a ".pyc" file. (The advantage of
88storing compiled modules as resources instead of files is that many modules
89can be stored in a single file.) The applet's main
90program initializes most of the toolbox managers (it uses the same sequence
91as stdwin or the Think C console I/O library), then initializes Python,
92then loads the resource and decodes it into a Python code object, and finally
93passes the code object to the Python interpreter for execution. [[XXX Actually,
94the applet's main program could be moved entirely to the shared library --
95there's nothing in it that's dependent on the applet's configuration.
96The applet itself could then be reduced to main() { applet_main(); } ]]
97[[XXX I tried this but it only save 512 bytes on a total of 10K -- the rest
98is boilerplate that the linker always seems to create. Wonder how this is on
99the Power Mac...]]
100
101A big restriction for applets is that they have no standard input and their
102standard output and error streams are diverted to files called "stdout" and
103"stderr". This means that in order to interact with the user, or even just
104to provide some feedback while they're grinding along, they must make use of
105Mac toolbox calls to create windows, etc. I plan to provide a library that at
106least has the output functionality of the Think C Console I/O library or
107CodeWarrior's SIOX.
108
109The current procedure to create an applet is not as simple as it could be.
110I have written a Python script (which itself can be -- and has been -- made
111into an applet!) which asks for a Python source file (input) and an existing
112applet file (output). It adds a 'PYC ' resource to the applet named __main__,
113which contains the compiled code of the script (it compiles on the fly,
114so you don't need to have a .pyc file for the script).
115Although this seems fairly simple, the practical complication is that you need
116to copy the applet template first -- if you specify the template as the output,
117you will overwrite the template! [[XXX I guess a simplification could be made
118by using the convention that the applet built from a script has the same name
119as the script but with ".py" stripped; the applet-making script could then
120search for the template in a few common locations (e.g. the Python module
121search path) and copy it, reducing the user interaction to just indicating the
122Python source file to be converted into an applet.]]