mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			122 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| Python and MPW
 | |
| ==============
 | |
| 
 | |
| There is conditional code in Python for MPW.  This has been used with
 | |
| different compilers at various points in time.  Right now it is being
 | |
| used to turn the entire interpreter into a shared library on 68K Macs,
 | |
| so we can build "applets" (see below).  I have used MPW 3.2 and the OpenDoc
 | |
| development environment from an OpenDoc CD released in 1984.  This
 | |
| contains the Symantec C compiler for MPW (version 7.0.4), the
 | |
| Universal Headers (version 2.0a1), and early versions of CFM-68K (version 1.0a1)
 | |
| (the Code Fragment Manager ported back to the 68K Mac) and
 | |
| MixedModeInit (version 1.0d12), which are required to use shared libraries.
 | |
| 
 | |
| I've created a Makefile that does everything, plus a three-line Build
 | |
| script that calls Make and runs its output.  The Makefile assumes that
 | |
| it lives in a 1-deep subdirectory of the root, so e.g. the Python
 | |
| Include directory can be referenced through "::Include".  All object
 | |
| files are collected in the subsubdirectory Objcode.
 | |
| 
 | |
| I use these feature test macros:
 | |
| 
 | |
| MPW	        for all MPW compilers (e.g. long double in <math.h>)
 | |
| __SC__      for things specific to the Symantec C compiler
 | |
|             (e.g. doesn't like static forward)
 | |
| __CFM68K__  for things specific to CFM-68K
 | |
|             (e.g. it requires the use of #pragma lib_export on|off)
 | |
| HAVE_UNIVERSAL_HEADERS    for things not yet in Think's headers (e.g. UPPs)
 | |
| GENERATINGCFM    for both PPC and 68K Code Fragment Manager
 | |
| 
 | |
| MPW is defined in config.h (if it finds that applec is defined);
 | |
| HAVE_UNIVERSAL_HEADERS is defined in macglue.h depending on whether it
 | |
| thinks we are using Universal Headers.  The others are defined by the
 | |
| compiler or by the system headers.
 | |
| 
 | |
| Compiler switches were a nightmare until I found I had to use -b.
 | |
| This wasn't mentioned in the CFM-68K docs that came on the OpenDoc
 | |
| CD-ROM.  Apparently it is only needed for large projects...
 | |
| 
 | |
| 
 | |
| Warning: Mixing Think C and MPW
 | |
| ===============================
 | |
| 
 | |
| (XXX Need to check what convention SC uses -- I hope it uses Think's.)
 | |
| 
 | |
| If you are mixing Think C and MPW, you may experience weird errors in
 | |
| previously correct modules.  These disappear when you throw away the
 | |
| module's .pyc file.  The errors usually have to do with string
 | |
| literals containing '\n' or '\r'.  The reason is an incompatibility
 | |
| between their handling of '\n' and '\r' -- in MPW C, '\n' actually is
 | |
| ASCII CR while '\r' is ASCII LF, which is the reverse situation from
 | |
| any other ASCII based C implementation.  This behaviour is inherited
 | |
| by Python compiled with MPW C.  This is normally not a problem, but
 | |
| *binary* files written by one system will be mis-interpreted by the
 | |
| other, and this is what happens to the .pyc files.  There is no easy
 | |
| way to fix this in the source.  (This is a real shame, since the
 | |
| format of .pyc files was carefully designed to be independent of byte
 | |
| order and integer size -- deviations in the ASCII character codes were
 | |
| never anticipated.)
 | |
| 
 | |
| 
 | |
| Building "Applets" for the Mac
 | |
| ==============================
 | |
| 
 | |
| An "applet" is a tiny application that's written in a scripting language
 | |
| but behaves like a real application.  The behavior is much like that of
 | |
| executable scripts in Unix -- but the implementation is entirely different.
 | |
| 
 | |
| The applet's file can be small because it doesn't contain the actual
 | |
| interpreter for the scripting language -- this has to be installed in the
 | |
| Extensions folder (usually) before the applet will work.  The applet file
 | |
| itself only contains a tiny bootstrap program and the script itself --
 | |
| possibly "compiled" or otherwise encoded to save on parsing time and space,
 | |
| and to make it harder to reverse engineer the script (some people care about
 | |
| this).
 | |
| 
 | |
| In Python's case, the Python interpreter, without its main program, is built
 | |
| as a shared library that is dropped in the Extensions folder.  Some more
 | |
| shared libraries must also be present -- these form the C run-time system.
 | |
| [[XXX perhaps we should link these in statically with the Python library,
 | |
| for simpler distribution???]]  On the 68K Mac, two more extensions are needed:
 | |
| CFM-68K (the Code Fragment Manager) and MixedModeInit.  These provide
 | |
| functionality that's built in the Power Mac's OS.  It seems that System 7.1.1
 | |
| or higher is also required.
 | |
| 
 | |
| The applet file contains a small main program program, plus a 'PYC ' resource
 | |
| named __main__ which contains the "compiled" version of the script.  A 'PYC '
 | |
| resource contains exactly the same data as a ".pyc" file.  (The advantage of
 | |
| storing compiled modules as resources instead of files is that many modules
 | |
| can be stored in a single file.)  The applet's main
 | |
| program initializes most of the toolbox managers (it uses the same sequence
 | |
| as stdwin or the Think C console I/O library), then initializes Python,
 | |
| then loads the resource and decodes it into a Python code object, and finally
 | |
| passes the code object to the Python interpreter for execution.  [[XXX Actually,
 | |
| the applet's main program could be moved entirely to the shared library --
 | |
| there's nothing in it that's dependent on the applet's configuration.
 | |
| The applet itself could then be reduced to main() { applet_main(); } ]]
 | |
| [[XXX I tried this but it only save 512 bytes on a total of 10K -- the rest
 | |
| is boilerplate that the linker always seems to create.  Wonder how this is on
 | |
| the Power Mac...]]
 | |
| 
 | |
| A big restriction for applets is that they have no standard input and their
 | |
| standard output and error streams are diverted to files called "stdout" and
 | |
| "stderr".  This means that in order to interact with the user, or even just
 | |
| to provide some feedback while they're grinding along, they must make use of
 | |
| Mac toolbox calls to create windows, etc.  I plan to provide a library that at
 | |
| least has the output functionality of the Think C Console I/O library or
 | |
| CodeWarrior's SIOX.
 | |
| 
 | |
| The current procedure to create an applet is not as simple as it could be.
 | |
| I have written a Python script (which itself can be -- and has been -- made
 | |
| into an applet!) which asks for a Python source file (input) and an existing
 | |
| applet file (output).  It adds a 'PYC ' resource to the applet named __main__,
 | |
| which contains the compiled code of the script (it compiles on the fly,
 | |
| so you don't need to have a .pyc file for the script).
 | |
| Although this seems fairly simple, the practical complication is that you need
 | |
| to copy the applet template first -- if you specify the template as the output,
 | |
| you will overwrite the template!  [[XXX I guess a simplification could be made
 | |
| by using the convention that the applet built from a script has the same name
 | |
| as the script but with ".py" stripped; the applet-making script could then
 | |
| search for the template in a few common locations (e.g. the Python module
 | |
| search path) and copy it, reducing the user interaction to just indicating the
 | |
| Python source file to be converted into an applet.]]
 | 
