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