485 lines
16 KiB
HTML
485 lines
16 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
||
|
<HTML>
|
||
|
|
||
|
<HEAD>
|
||
|
|
||
|
<TITLE>HOWTO: Compiling Python Modules with MPW</TITLE>
|
||
|
|
||
|
</HEAD>
|
||
|
|
||
|
<BODY>
|
||
|
|
||
|
<H1>HOWTO: Compiling Python Modules with MPW</H1>
|
||
|
|
||
|
<blockquote>
|
||
|
This HOWTO is a slightly reformatted version of an original by
|
||
|
<A HREF="mailto:cwebster@nevada.edu">Corran Webster</A>, whose
|
||
|
<A HREF="http://www.nevada.edu/~cwebster/Python/">Python page</A>
|
||
|
may contain a more up-to-date version.
|
||
|
</blockquote>
|
||
|
<HR>
|
||
|
|
||
|
<P>
|
||
|
The <A HREF="http://www.cwi.nl/~jack/macpython.html">Macintosh version</A>
|
||
|
of the <A HREF="http://www.python.org/">Python programming language</A> is
|
||
|
usually compiled with <A HREF="http://www.metrowerks.com/">Metrowerks
|
||
|
CodeWarrior</A>. As a result, C extension modules are also usually
|
||
|
compiled with CodeWarrior, and the documentation and sample code reflects
|
||
|
this. CodeWarrior is a commercial product, and may be beyond the budgets
|
||
|
of hobbyist hackers, making them dependent on others to compile C extension
|
||
|
modules. At the present time, many standard C extension modules compile
|
||
|
"out of the box" on the Macintosh, but in only a few cases is the plugin
|
||
|
for the Macintosh included in the distribution.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
The <A HREF="http://developer.apple.com/tools/mpw-tools/">Macintosh
|
||
|
Programmer's Workshop</A> (MPW) is Apple's development environment, and is
|
||
|
freely available for <A
|
||
|
HREF="ftp://ftp.apple.com/developer/Tool_Chest/Core_Mac_OS_Tools/MPW_etc./">download</A>
|
||
|
from Apple, as well as on their Developer CDs. Since Python was originally
|
||
|
developed using MPW, before CodeWarrior became the dominant MacOS
|
||
|
development environment, most of the idiosyncrasies of MPW are already
|
||
|
supported, and compilation of C extension modules in MPW is possible.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
This HOWTO only deals with compiling for PowerPC Macintoshes. The process
|
||
|
should be similar for 68k Macintoshes using the code fragment manager, but
|
||
|
I have not attempted this - my old Mac is running NetBSD.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
This way of compiling modules is still experimental. Please read the
|
||
|
caveats section below.
|
||
|
</P>
|
||
|
|
||
|
<H2><A NAME="setup">Setting Up MPW for Compiling Python Modules</A></H2>
|
||
|
|
||
|
<P>
|
||
|
This assumes that you have successfully installed both MPW and Python with
|
||
|
the Developer's Kit on your Macintosh.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
The first step is to let MPW know where you keep Python. This step is not
|
||
|
strictly necessary, but will make development easier and improve
|
||
|
portability. Create a new file in the <CODE>Startup Items</CODE> folder of
|
||
|
MPW called <A HREF="Python"><CODE>Python</CODE></A>. Type the lines:
|
||
|
</P>
|
||
|
|
||
|
<PRE>
|
||
|
set Python "Macintosh HD:Applications:Python 1.5.2c1:"
|
||
|
set PythonIncludes "{Python}Include"
|
||
|
set PythonMacIncludes "{Python}Mac:Include"
|
||
|
set PythonCore "{Python}PythonCore"
|
||
|
|
||
|
export Python PythonIncludes PythonMacIncludes PythonCore
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
where <CODE>Macintosh HD:Applications:Python 1.5.2c1:</CODE> is replaced by
|
||
|
the path to the directory where you keep your copy of Python, and the other
|
||
|
variables reflect where you keep your header files and Python core files.
|
||
|
The locations here are the standard for Python 1.5.2c1, but they are
|
||
|
different for Python 1.52b2 and earlier (most notably, the PythonCore is
|
||
|
kept in the Extensions folder).
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
Next, you need to update the <A HREF="config.h"><CODE>config.h</CODE></A>
|
||
|
file for the <CODE>MrC</CODE> compiler included with MPW. This header file
|
||
|
is located in the <CODE>:Mac:Include</CODE> folder in the standard
|
||
|
distribution. You can update it by hand, by adding the lines:
|
||
|
</P>
|
||
|
|
||
|
<PRE>
|
||
|
#ifdef __MRC__
|
||
|
#define BAD_STATIC_FORWARD
|
||
|
#endif
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
at the after the similar defines for <CODE>__MWERKS__</CODE> and
|
||
|
<CODE>__SC__</CODE> in the file. This step is critical: many modules,
|
||
|
including ones in the standard distribution, will not compile properly
|
||
|
without this modification (see common problems below).
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
Copies of both the <A HREF="Python"><CODE>Python</CODE></A> startup item
|
||
|
for MPW and the <A HREF="config.h"><CODE>config.h</CODE></A> are included
|
||
|
here for your convenience.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
If you are porting Unix modules to the mac, you may find it useful to
|
||
|
install <A
|
||
|
HREF="http://www.iis.ee.ethz.ch/~neeri/macintosh/gusi-qa.html">GUSI</A> for
|
||
|
your copy of MPW. GUSI provides some amount of POSIX compatibility, and is
|
||
|
used by Python itself for this purpose - at the very least having it's
|
||
|
header files available may be useful. Also of note for people porting Unix
|
||
|
modules, the most recent alpha version (4.1a8) of <CODE>MrC</CODE> and
|
||
|
<CODE>MrCpp</CODE> at this writing permits using unix-style pathnames for
|
||
|
includes via the <CODE>-includes unix</CODE> command line option. I have
|
||
|
not experimented heavily with this, but will be doing so in the future and
|
||
|
report my findings.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
You now have MPW and Python set up to allow compilation of modules.
|
||
|
</P>
|
||
|
|
||
|
<H2><A NAME="compiling">Compiling a Module</A></H2>
|
||
|
|
||
|
<P>
|
||
|
This assumes that you have a C extension module ready to compile. For
|
||
|
instructions on how to write a module, see the Python documentation.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
There are three approaches you can take to compiling in MPW: using the
|
||
|
command line interface, using the MPW <CODE>CreateMake</CODE> command
|
||
|
(available as the "Create build commands..." menu item, and writing a
|
||
|
Makefile by hand.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
Before you start any of these, you'll need to know:
|
||
|
</P>
|
||
|
|
||
|
<UL>
|
||
|
<LI>The names and locations of the C source files. In the examples, this
|
||
|
is the file <A HREF="xxmodule.c"><CODE>xxmodule.c</CODE></A>, and is in
|
||
|
MPW's current working directory.
|
||
|
<LI>The name that Python expects to import your module under. In the
|
||
|
examples, this is <CODE>xx</CODE>, so the shared library file will be
|
||
|
called <CODE>xx.ppc.slb</CODE>.
|
||
|
<LI>The location of any additional header files use by the C source. The
|
||
|
example does not use any additional header files.
|
||
|
<LI>The location of any additional shared libraries which the module needs
|
||
|
to link to. The example does not link to any other shared libraries.
|
||
|
<LI>The name of the entry point to your module. This is usually the last
|
||
|
function in the main C source file, and the name usually starts with
|
||
|
<CODE>init</CODE>. In the examples, this is <CODE>initxx</CODE>.
|
||
|
</UL>
|
||
|
|
||
|
<H3>Using the Command Line</H3>
|
||
|
|
||
|
<P>
|
||
|
For simple modules consisting of one or two C files, it's often convenient
|
||
|
to simply use commands in a MPW Worksheet. Usually you will want to set
|
||
|
MPW's working directory to the directory containing the C source code. The
|
||
|
following commands compile and link the standard Python test module <A
|
||
|
HREF="xxmodule.c"><CODE>xxmodule.c</CODE></A>:
|
||
|
</P>
|
||
|
|
||
|
<PRE>
|
||
|
MrC "xxmodule.c" -o "xx.c.x" -w off -d HAVE_CONFIG_H ∂
|
||
|
-i "{PythonMacIncludes}" ∂
|
||
|
-i "{PythonIncludes}"
|
||
|
PPCLink ∂
|
||
|
-o "xx.ppc.slb" ∂
|
||
|
"xx.c.x" ∂
|
||
|
-t 'shlb' ∂
|
||
|
-c 'Pyth' ∂
|
||
|
-xm s ∂
|
||
|
-d ∂
|
||
|
"{PythonCore}" ∂
|
||
|
"{SharedLibraries}InterfaceLib" ∂
|
||
|
"{SharedLibraries}MathLib" ∂
|
||
|
"{SharedLibraries}StdCLib" ∂
|
||
|
"{PPCLibraries}StdCRuntime.o" ∂
|
||
|
"{PPCLibraries}PPCCRuntime.o" ∂
|
||
|
"{PPCLibraries}PPCToolLibs.o" ∂
|
||
|
-export initxx
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
(Note: The last character on each line should appear as "partial
|
||
|
derivative" symbol, which you type as <KBD>option-d</KBD> and which is
|
||
|
MPW's line continuation symbol.)
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
Any additional header files should be specified by adding their directories
|
||
|
as extra <CODE>-i</CODE> options to the <CODE>MrC</CODE> command. Any
|
||
|
additional shared libraries should be added before the PythonCore library
|
||
|
in the <CODE>PPCLink</CODE> command.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
If there is more than one source file, you will need to duplicate the
|
||
|
compile command for each source file, and you will need to include all the
|
||
|
object files in the place where <CODE>"xx.c.x"</CODE> appears in the
|
||
|
<CODE>PPCLink</CODE> command.
|
||
|
</P>
|
||
|
|
||
|
<H3>Using CreateMake</H3>
|
||
|
|
||
|
<P>
|
||
|
For more complex modules, or modules that you are writing yourself, you
|
||
|
will probably want to use a makefile. Unfortunately MPW's makefiles are
|
||
|
incompatible with the standard Unix makefiles, so you will not be able to
|
||
|
use any makefiles which come with a C module.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
Usually, you will want the makefile to reside in the same directory as the
|
||
|
C source code, so you should set MPW's working directory to that directory
|
||
|
before proceeding.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
To create a makefile for the standard Python test module <A
|
||
|
HREF="xxmodule.c"><CODE>xxmodule.c</CODE></A>:
|
||
|
</P>
|
||
|
|
||
|
<UL>
|
||
|
<LI>Select "Create build commands..." from the "Build" Menu.
|
||
|
<LI>Type <KBD>xx.ppc.slb</KBD> for the Program Name.
|
||
|
<LI>Select "Shared Library" for the Program Type.
|
||
|
<LI>Select "PowerPC Only" for the Target.
|
||
|
<LI>Click on the "Source Files..." button, and add your module's C source
|
||
|
files to the list.
|
||
|
<LI>Click on the "Other Options..." button and change the creator type to
|
||
|
"Pyth". If you are using additional header files, you can also add their
|
||
|
directories at this stage. Click on "Continue" once you have done this.
|
||
|
<LI>Click on the "Exported Symbols..." button and type <KBD>initxx</KBD>
|
||
|
into the entry field. Click on "Continue" once you have done this.
|
||
|
<LI>At this stage, your CreateMake window should look like this: <IMG
|
||
|
SRC="html.icons/createmake.png" ALT="[picture of commando window for CreateMake]">
|
||
|
<LI>Click on the "CreateMake" button.
|
||
|
</UL>
|
||
|
|
||
|
<P>
|
||
|
You will now need to edit the makefile that was just created. Open the
|
||
|
file "xx.ppc.slb.make" in the current directory and make the following
|
||
|
changes:
|
||
|
</P>
|
||
|
|
||
|
<UL>
|
||
|
<LI>Change the line
|
||
|
|
||
|
<PRE>
|
||
|
Includes =
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
to read
|
||
|
</P>
|
||
|
|
||
|
<PRE>
|
||
|
Includes = -i "{PythonIncludes}" -i "{PythonMacIncludes}"
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
If you have any additional headers than need to be included, you can add
|
||
|
them here as well.
|
||
|
<LI>Change the line
|
||
|
|
||
|
<PRE>
|
||
|
PPCCOptions = {Includes} {Sym•PPC}
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
to read
|
||
|
</P>
|
||
|
|
||
|
<PRE>
|
||
|
PPCCOptions = -w off -d HAVE_CONFIG_H {Includes} {Sym•PPC}
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
<LI>After the line
|
||
|
|
||
|
<PRE>
|
||
|
-xm s ∂
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
add
|
||
|
</P>
|
||
|
|
||
|
<PRE>
|
||
|
-d ∂
|
||
|
"{PythonCore}" ∂
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
If you have any other shared libraries you need to link to, add each on a
|
||
|
line before PythonCore, terminating each line with a <CODE>∂</CODE>.
|
||
|
</P>
|
||
|
|
||
|
</UL>
|
||
|
|
||
|
<P>Save the file. You are now ready to build.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
Go to the "Build" or "Full Build" menu items, type in
|
||
|
<KBD>xx.ppc.slb</KBD>, and MPW should take things from there. Any time you
|
||
|
need to rebuild the shared library, you can simply do another "Build" or
|
||
|
"Full Build".
|
||
|
</P>
|
||
|
|
||
|
<H3>Writing a Makefile by Hand</H3>
|
||
|
|
||
|
<P>
|
||
|
For modules which have complex interdependencies between files, you will
|
||
|
likely need a more sophisticated makefile than the one created by
|
||
|
<CODE>CreateMake</CODE>. You will need to be familiar with the MPW
|
||
|
makefile format, but you can get a start by either using
|
||
|
<CODE>CreateMake</CODE> to get a simple starting point, or taking another
|
||
|
MPW makefile as a starting point.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
It is beyond the scope of this HOWTO to go into the generalities of MPW
|
||
|
makefiles. Documentation on MPW's <CODE>Make</CODE> command can be found
|
||
|
with the MPW distribution, in particular the documents <A
|
||
|
HREF="http://developer.apple.com/tools/mpw-tools/books.html#Building">Building
|
||
|
and Maintaining Programs with MPW (2nd Edition)</A> and the <A
|
||
|
HREF="http://developer.apple.com/tools/mpw-tools/books.html#CommandRef">MPW
|
||
|
Command Reference</A>.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
There are a couple of important points to keep in mind when writing a
|
||
|
makefile by hand:</P>
|
||
|
|
||
|
<UL>
|
||
|
<LI>When there are multiple symbols with the same name in object files or
|
||
|
shared libraries, <CODE>PPCLink</CODE> used the symbol from the file which
|
||
|
appears first in arguments of the <CODE>PPCLink</CODE> command. For this
|
||
|
reason, you will usually want the PythonCore and any other shared libraries
|
||
|
which are not part of the standard MPW runtime environment to appear before
|
||
|
the standard runtime libraries. This is particularly the case with
|
||
|
StdCLib. The "-d" option turns off the (often copious) warnings about
|
||
|
multiply defined symbols.
|
||
|
<LI>You will want to make sure that the <CODE>HAVE_CONFIG_H</CODE>
|
||
|
preprocessor symbol is defined for most C source files using the <CODE>-d
|
||
|
HAVE_CONFIG_H</CODE> option to <CODE>MrC</CODE>.
|
||
|
</UL>
|
||
|
|
||
|
<P>
|
||
|
The file <A HREF="xx.ppc.slb.make.sit.hqx"><CODE>xx.ppc.slb.make</CODE></A>
|
||
|
is included here for you to use as a starting point.
|
||
|
</P>
|
||
|
|
||
|
<H2><A NAME="using">Using the Extension Module</A></H2>
|
||
|
|
||
|
<P>
|
||
|
Once you have compiled your extension module, you will need to let Python
|
||
|
know where it is. You can either move it into a place on Python's search
|
||
|
path - such as the <CODE>:Mac:Plugins</CODE> folder - or modify the path to
|
||
|
include the location of your new module using the
|
||
|
<CODE>EditPythonPrefs</CODE> applet.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
Your work may not be completely done, as many extension modules have a
|
||
|
Python wrapper around them. If the Python was not written with portability
|
||
|
in mind, you may need to do some more work to get that up and running.
|
||
|
Indeed, if the Python part uses OS-specific features, like pipes, you may
|
||
|
have to completely rewrite it if you can make it work at all.
|
||
|
</P>
|
||
|
|
||
|
<H2><A NAME="problems">Common Problems</A></H2>
|
||
|
|
||
|
<P>
|
||
|
There are a couple of common problems which occur when porting a module
|
||
|
from another platform. Fortunately, they are often easy to fix.
|
||
|
</P>
|
||
|
|
||
|
<H3>Static Forward Definitions</H3>
|
||
|
|
||
|
<P>
|
||
|
If you get a compiler error which looks something like:
|
||
|
</P>
|
||
|
|
||
|
<PRE>
|
||
|
File "xxmodule.c"; line 135 #Error: 'Xxo_Type' is already defined
|
||
|
</PRE>
|
||
|
|
||
|
<P>
|
||
|
then most likely either you have not set up <CODE>config.h</CODE> correctly
|
||
|
to handle static forward definitions, or the module author has not adhered
|
||
|
to the standard python conventions. If the second is the case, find where
|
||
|
the variable is first defined, and replace the <CODE>static</CODE> with
|
||
|
<CODE>staticforward</CODE>. Then find the second place it is defined
|
||
|
(usually the line where the compiler complained) and replace
|
||
|
<CODE>static</CODE> with <CODE>statichere</CODE>.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
If you have set up things correctly, you should now be able to compile.
|
||
|
</P>
|
||
|
|
||
|
<H3>Automatic Type Conversion</H3>
|
||
|
|
||
|
<P>
|
||
|
<CODE>MrC</CODE> seems to be a little pickier about automatically
|
||
|
converting from one type to another than some other C compilers. These can
|
||
|
often be fixed by simply adding an explicit cast to the desired type.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
XXX There may be a compiler option which relaxes this. That would be a
|
||
|
better solution.
|
||
|
</P>
|
||
|
|
||
|
<H2><A NAME="caveats">Caveats</A></H2>
|
||
|
|
||
|
<P>
|
||
|
As Jack Jansen pointed out on the Mac Python mailing list, there could
|
||
|
potentially be conflicts between the MetroWerks C runtime which the Python
|
||
|
core and standard modules was compiled with, and the MPW C runtime which
|
||
|
your extension module is compiled with. While things seem to work fine in
|
||
|
everyday use, it is possible that there are bugs which have not been
|
||
|
discovered yet. Most likely these world take the form of standard C
|
||
|
functions (most likely I/O functions due to conflicts between the SIOUX
|
||
|
libraries and the SIOW libraries) not working as they are supposed to, or
|
||
|
memory leaks caused by improper malloc/free.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
Some such problems have been demonstrated by compiling modules with
|
||
|
PythonCore linked after StdCLib - printf does not work properly in this
|
||
|
setup, and I suspect that there will also be malloc/free problems in
|
||
|
situations where the module allocates memory which is later disposed of by
|
||
|
Python, or vice-versa. Compiling with PythonCore taking precedence over
|
||
|
StdCLib seems to give the correct behaviour.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
This method of compiling should be considered experimental for the time
|
||
|
being. <STRONG>Use it at your own risk.</STRONG>
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
If you notice any quirks in modules compiled this way, or have insight into
|
||
|
what may go wrong or right with this situation, <A
|
||
|
HREF="mailto:cwebster@nevada.edu">please contact me</A> so that I can add
|
||
|
it to the HOWTO.
|
||
|
</P>
|
||
|
|
||
|
<P>
|
||
|
The ideal solution to this problem would be to get Python to compile using
|
||
|
MPW (and a Python MPW Tool would be very neat indeed). However, that does
|
||
|
seem to be a major project.
|
||
|
</P>
|
||
|
|
||
|
<DIV class=footer>
|
||
|
<HR>
|
||
|
<BR>
|
||
|
©<A HREF="mailto:cwebster@nevada.edu">Corran Webster</A>, 1999. <BR>
|
||
|
<!-- #LASTMODIFIED TEXT="Last modified" FORM="SHORT,TIME" -->
|
||
|
Last modified 14/12/99 12:17 PM
|
||
|
<!-- /#LASTMODIFIED -->
|
||
|
</DIV>
|
||
|
|
||
|
</BODY>
|
||
|
|
||
|
</HTML>
|