Commits

Ronald Oussoren  committed c8fe4cc

* Minor code cleanups
* No longer use the native build system of libffi, but integrate into the
normal setup.py. We also no longer use autoconf. This makes the build
process easier to understand and should make it fairly easy to build fat
binaries.
* Build univeral binaries when the AUTO_UNIVERSAL option is set in
setup.py (defaults to off and requires editing of setup.py to set).
This is a temporary solution, distutils should learn about this.

  • Participants
  • Parent commits b5c375e
  • Branches pyobjc-ancient

Comments (0)

Files changed (21)

File Doc/Xcode-Templates.html

 PyObjC Xcode Templates</title>
 <meta name="Author" content="Bob Ippolito" />
 <meta name="Contact" content="bob@redivi.com" />
-<title>
-Contents</title>
 </head>
 <body>
 <h2>PyObjC Xcode Templates</h2>
 applications &quot;by hand&quot; using py2app, as described in the
 tutorial.  As of PyObjC 1.3.1, these templates are py2app based,
 so there is no longer a technical reason not to use them.</p>
-<h2>Contents</h2>
+<table border="1" width="80%" align="center"><tbody><tr><td><i><center>Contents</center></i><br />
 <ul>
-<li><a href="#installing" id="id3" name="id3">Installing</a></li>
-<li><a href="#notes" id="id4" name="id4">Notes</a></li>
-<li><a href="#groups" id="id5" name="id5">Groups</a></li>
-<li><a href="#targets" id="id6" name="id6">Targets</a></li>
-<li><a href="#custom-executable" id="id7" name="id7">Custom Executable</a></li>
-<li><a href="#pyobjc-application" id="id8" name="id8">PyObjC Application</a></li>
-<li><a href="#pyobjc-document-based-application" id="id9" name="id9">PyObjC Document Based Application</a></li>
-<li><a href="#pyobjc-mixed-application" id="id10" name="id10">PyObjC Mixed Application</a></li>
+<li><a href="#installing">Installing</a></li>
+<li><a href="#notes">Notes</a></li>
+<li><a href="#groups">Groups</a></li>
+<li><a href="#targets">Targets</a></li>
+<li><a href="#custom-executable">Custom Executable</a></li>
+<li><a href="#pyobjc-application">PyObjC Application</a></li>
+<li><a href="#pyobjc-document-based-application">PyObjC Document Based Application</a></li>
+<li><a href="#pyobjc-mixed-application">PyObjC Mixed Application</a></li>
 </ul>
-<h2><a href="#id3" name="installing">Installing</a></h2>
+</td></tr></tbody></table>
+<h2><a href="#id3">Installing</a></h2>
 <p>If you have installed PyObjC 1.3.1 or later using the installer, then
 the Xcode templates are already installed.</p>
 <p>If you have installed any version of PyObjC prior to 1.3.1, then you
 </pre>
 <p>To install the templates manually, simply copy (or link) them into
 this Project Templates folder.</p>
-<h2><a href="#id4" name="notes">Notes</a></h2>
+<h2><a href="#id4">Notes</a></h2>
 <ul>
 <li>These templates are brand new in PyObjC 1.3.1 and haven't had much
 use yet.  If you think that you have found a bug or would like them to be
 See PyObjC Mixed Application below for more information about using
 plug-ins to integrate non-Python code into your application.</li>
 </ul>
-<h2><a href="#id5" name="groups">Groups</a></h2>
+<h2><a href="#id5">Groups</a></h2>
 <p>The PyObjC Xcode templates use py2app to build applications,
 but they parse the <code><span>.xcode</span></code> project file to determine
 how they should be built, rather than directly in the
 </dl>
 </dd>
 </dl>
-<h2><a href="#id6" name="targets">Targets</a></h2>
+<h2><a href="#id6">Targets</a></h2>
 <dl>
 <dt>Development:</dt>
 <dd><p>This target will use py2app <code><span>--alias</span></code> build mode.  Executables
 project.  The build style has no effect on Python code.</p>
 </dd>
 </dl>
-<h2><a href="#id7" name="custom-executable">Custom Executable</a></h2>
+<h2><a href="#id7">Custom Executable</a></h2>
 <p>The custom executable enables for your built application to be run from Xcode.</p>
 <p>If you rename your main script or fiddle around with your <code><span>Info.plist</span></code>,
 the path to your application may change and this will no longer work.
 <p>Custom executables are specific to a particular user in Xcode, so anything
 you do to this part of the template won't be seen by anyone else unless
 they happen to have the same short user name as you.</p>
-<h2><a href="#id8" name="pyobjc-application">PyObjC Application</a></h2>
+<h2><a href="#id8">PyObjC Application</a></h2>
 <p>This is a simple template that has a window and an application delegate.</p>
-<h2><a href="#id9" name="pyobjc-document-based-application">PyObjC Document Based Application</a></h2>
+<h2><a href="#id9">PyObjC Document Based Application</a></h2>
 <p>This is template demonstrates a Document-based application written in Python.
 It is a simple text editor (like the TinyTinyEdit example).</p>
-<h2><a href="#id10" name="pyobjc-mixed-application">PyObjC Mixed Application</a></h2>
+<h2><a href="#id10">PyObjC Mixed Application</a></h2>
 <p>This template contains both Objective-C and Python code.  The Objective-C code
 is built as a &quot;ProjectNamePlugIn.bundle&quot; plug-in in a separate target.  The plug-in
 is placed in the <code><span>Resources</span></code> directory of your application.  A wrapper script

File Modules/objc/libffi_support.m

 
 #import <Foundation/NSHost.h>
 
+#ifdef MACOSX
+/*
+ * Define SMALL_STRUCT_LIMIT as the largest struct that will be returned
+ * in registers instead of with a hidden pointer argument.
+ */
+
+#if defined(__ppc__)
+
+#   define SMALL_STRUCT_LIMIT	4
+
+#elif defined(__i386__) 
+
+#   define SMALL_STRUCT_LIMIT 	8
+
+#else
+
+#   error "Unsupported MACOSX platform"
+
+#endif
+
+#endif /* MACOSX */
+
+
+
 #ifndef FFI_CLOSURES
 #    error "Need FFI_CLOSURES!"
 #endif
 
 	rettype = methinfo->rettype;
 
-#ifdef __i386__
-	if (((size_t)PyObjCRT_SizeOfType(rettype) > 8)
-#else
-	if (((size_t)PyObjCRT_SizeOfType(rettype) > sizeof(id))
-#endif
+	if (((size_t)PyObjCRT_SizeOfType(rettype) > SMALL_STRUCT_LIMIT)
 		 	&& *rettype != _C_DBL && *rettype != _C_FLT
 		 	&& *rettype != _C_LNGLNG && *rettype != _C_ULNGLNG) {
 		/* the prototype is objc_msgSend_stret(void* retbuf, ... */
 			 */
 
 			arglistOffset = 0;
-#ifdef __i386__
-		} else if ((size_t)resultSize > 8) {
-#else
-		} else if ((size_t)resultSize > sizeof(id)) {
-#endif
+		} else if ((size_t)resultSize > SMALL_STRUCT_LIMIT) {
 			arglistOffset = 1;
 			arglist[0] = &ffi_type_pointer;
 			values[0] = &msgResult;
 	rettype = methinfo->rettype;
 
 	/* XXX: this needs work!!! */
-#ifdef __i386__
-	if (pArgOffset != NULL && (((size_t)PyObjCRT_SizeOfType(rettype) > 8)
-#else
-	if (pArgOffset != NULL && (((size_t)PyObjCRT_SizeOfType(rettype) > sizeof(id))
-#endif
+	if (pArgOffset != NULL && (((size_t)PyObjCRT_SizeOfType(rettype) > SMALL_STRUCT_LIMIT)
 		 	&& *rettype != _C_DBL && *rettype != _C_FLT
 		 	&& *rettype != _C_LNGLNG && *rettype != _C_ULNGLNG)) {
 

File Modules/objc/mach_inject.m

 
 	***************************************************************************/
 
-#if defined(MACOSX) && !defined(__i386__)
+#if defined(MACOSX) && defined(__ppc__)
 #include	"mach_inject.h"
 
 #include <mach-o/dyld.h>

File Modules/objc/module.m

 	return PyObjC_IDToCFType(PyObjCObject_GetObject(argument));
 }
 
-#if defined(MAC_OS_X_VERSION_10_3) && !defined(__i386__)
+#if defined(MAC_OS_X_VERSION_10_3) && defined(__ppc__)
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
 
 PyDoc_STRVAR(inject_doc,
 		METH_VARARGS|METH_KEYWORDS, PyObjC_loadBundleVariables_doc },
 	{ "loadBundleFunctions", (PyCFunction)PyObjC_loadBundleFunctions,
 		METH_VARARGS|METH_KEYWORDS, PyObjC_loadBundleFunctions_doc },
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) && !defined(__i386__)
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) && defined(__ppc__)
 	{ "_inject", (PyCFunction)pyject_inject, METH_VARARGS|METH_KEYWORDS, inject_doc },
 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */
 #endif /* MACOSX */

File Modules/objc/objc_inject.m

 #include "objc_inject.h"
-#if defined(MAC_OS_X_VERSION_10_3) && !defined(__i386__)
+#if defined(MAC_OS_X_VERSION_10_3) && defined(__ppc__)
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
 #include "mach_inject.h"
 #include <string.h>

File Modules/objc/objc_support.m

 	unsigned long long utemp;
 	int       r;
 
-#ifndef __i386__
+#ifdef __ppc__
+	/* Small integers are promoted to integers when returning them */
 	switch (*type) {
 	case _C_CHR: 
 		if (PyString_Check(argument) && PyString_Size(argument) == 1) {
 PyObject *
 pythonify_c_return_value (const char *type, void *datum)
 {
-#ifndef __i386__
+#ifdef __ppc__
 	/*
- 	 * On PowerPC short and char return values are passed
+ 	 * On PowerPC short and char return values are returned
  	 * as full-size ints.
 	 */
 	static  const char intType[] = { _C_INT, 0 };

File Modules/objc/test/testbndl.m

 	[key release];
 	[observed release];
 	[value release];
+	[super dealloc];
 }
 
 -getValue
 <body>
 <h2>PyObjC NEWS</h2>
 <p>An overview of the relevant changes in new, and older, releases.</p>
-<h2><a name="version-1-3-7">Version 1.3.7 (????-??-??)</a></h2>
+<h2><a>Version 1.3.7 (????-??-??)</a></h2>
 <ul>
 <li>Probably working Xcode 2.1 support (for converted Xcode 2.0 projects)</li>
 <li>Hide List, Object, and Protocol classes from objc.loadBundle
 <li>Fixed a problem with reference counting in initializers.</li>
 <li>New TinyURLService example in AppKit that demonstrates how to write
 a service that transforms URLs into their tinyurl.com equivalents.</li>
+<li>Ported to Mac OS X on Intel. This is an initial, experimental port. The
+Intel ABI has not been finalised yet. It is also possible to build fat
+binaries, that option should not be used in production builds.</li>
 </ul>
-<h2><a name="version-1-3-6-2005-05-19">Version 1.3.6 (2005-05-19)</a></h2>
+<h2><a>Version 1.3.6 (2005-05-19)</a></h2>
 <ul>
 <li>Fixed bugs in the ProgressViewPalette example</li>
 <li>Fixed a bug in the class builder that caused most plugins to break</li>
 <li>Removed all references to Project Builder</li>
 <li>Mac OS X 10.2 (Jaguar) no longer supported</li>
 </ul>
-<h2><a name="version-1-3-5-2005-05-18">Version 1.3.5 (2005-05-18)</a></h2>
+<h2><a>Version 1.3.5 (2005-05-18)</a></h2>
 <ul>
 <li>Importing objc now ensures that Foundation is multi-threaded, previously
 it only ensured that Python was.</li>
 <code><span>array.array</span></code> (but not <code><span>str</span></code> or <code><span>unicode</span></code>) are now bridged as
 <code><span>NSData</span></code> subclasses.</li>
 </ul>
-<h2><a name="version-1-3-2005-03-31">Version 1.3 (2005-03-31)</a></h2>
+<h2><a>Version 1.3 (2005-03-31)</a></h2>
 <ul>
 <li>New <code><span>objc.pyobjc_id</span></code> function that returns a the id of the underlying
 NSObject as an integer.  (Python wrapper objects are often made on the
 function is also exposed in the C API (and has been for a while).</p>
 </li>
 </ul>
-<h2><a name="version-1-2-2004-12-29">Version 1.2 (2004-12-29)</a></h2>
+<h2><a>Version 1.2 (2004-12-29)</a></h2>
 <ul>
 <li><code><span>PyObjCTools.AppHelper.stopEventLoop</span></code> will attempt to stop the current
 <code><span>NSRunLoop</span></code> (if started by <code><span>runConsoleEventLoop</span></code>) or terminate the
 packages as <code><span>objc._objc</span></code>, <code><span>AppKit._AppKit</span></code>, etc.  They should never be
 used directly, so this should not break user code.</li>
 </ul>
-<h2><a name="version-1-1-2004-05-30">Version 1.1 (2004-05-30)</a></h2>
+<h2><a>Version 1.1 (2004-05-30)</a></h2>
 <ul>
 <li>KVO now actually works from Python without using nasty hacks.</li>
 <li>Added Xcode template for document-based applications</li>
 </ul>
-<h2><a name="version-1-1b2-2004-04-11">Version 1.1b2 (2004-04-11)</a></h2>
+<h2><a>Version 1.1b2 (2004-04-11)</a></h2>
 <ul>
 <li>More fine-grained multi-threading support</li>
 <li>Xcode templates use a smarter embedded main program</li>
 expression in Objective-C.</li>
 <li>Add several new examples</li>
 </ul>
-<h2><a name="version-1-1b1-2004-02-20">Version 1.1b1 (2004-02-20)</a></h2>
+<h2><a>Version 1.1b1 (2004-02-20)</a></h2>
 <ul>
 <li>Fixes some regressions in 1.1 w.r.t. 1.0</li>
 <li>Add Xcode templates for python files<p>You can now select a new python file in the 'add file...' dialog in Xcode</p>
 accessor method.</p>
 </li>
 </ul>
-<h2><a name="version-1-1a0-2004-02-02">Version 1.1a0 (2004-02-02)</a></h2>
+<h2><a>Version 1.1a0 (2004-02-02)</a></h2>
 <ul>
 <li>Objective-C structs can now be wrapped using struct-like types. This has
 been used to implement wrapper types for NSPoint, NSSize, NSRange and NSRect
 </ul>
 </li>
 </ul>
-<h2><a name="version-1-0-2003-09-21">Version 1.0 (2003-09-21)</a></h2>
+<h2><a>Version 1.0 (2003-09-21)</a></h2>
 <ul>
 <li>This version includes a new version of libffi that properly deals with
 complex types on MacOS X.</li>
 </ul>
-<h2><a name="version-1-0rc3-2003-09-14">Version 1.0rc3 (2003-09-14)</a></h2>
+<h2><a>Version 1.0rc3 (2003-09-14)</a></h2>
 <ul>
 <li>1.0rc2 didn't include the nibclassbuilder script</li>
 <li>Fix bug in NSRectFillList</li>
 </ul>
-<h2><a name="version-1-0rc2-2003-09-10">Version 1.0rc2 (2003-09-10)</a></h2>
+<h2><a>Version 1.0rc2 (2003-09-10)</a></h2>
 <ul>
 <li>Fix a number of bugs found in 1.0rc1.</li>
 </ul>
-<h2><a name="version-1-0rc1-2003-08-10">Version 1.0rc1 (2003-08-10)</a></h2>
+<h2><a>Version 1.0rc1 (2003-08-10)</a></h2>
 <ul>
 <li>Better support for the NSKeyValueCoding protocol.  The module 
 <code><span>PyObjCTools.KeyValueCoding</span></code> provides a python interface that makes it
 <li>The interface of Foundation.NSFillRects changed, it now has an interface
 that is consistent with the rest of the bridge.</li>
 </ul>
-<h2><a name="version-1-0b1-2003-07-05">Version 1.0b1 (2003-07-05)</a></h2>
+<h2><a>Version 1.0b1 (2003-07-05)</a></h2>
 <ul>
 <li>More tutorials<p>Two new tutorials were added: 'Adding Python code to an existing ObjC 
 application' and 'Understanding existing PyObjC examples'. The former
 <li>The generator scripts are automaticly called when building PyObjC. This
 should make it easier to support multiple versions of MacOS X.</li>
 </ul>
-<h2><a name="version-0-9-may-02-2003">Version 0.9 (May-02-2003)</a></h2>
+<h2><a>Version 0.9 (May-02-2003)</a></h2>
 <ul>
 <li>This version includes numerous bugfixes and improvements.</li>
 <li>The module AppKit.NibClassBuilder has been moved to the package
 makes it easily possible to use NSString values with Python APIs, while at 
 the same time allowing access to the full power of NSString.</li>
 </ul>
-<h2><a name="version-0-8-dec-10-2002">Version 0.8 (Dec-10-2002)</a></h2>
+<h2><a>Version 0.8 (Dec-10-2002)</a></h2>
 <ul>
 <li>GNUStep support has been removed for lack of support.  Volunteers
 needed.</li>
 <li>Support for Project Builder based Cocoa-Python projects.</li>
 <li>Unit tests.</li>
 </ul>
-<h2><a name="version-2002-01-30-january-30-2002">Version 2002-01-30 (January 30, 2002)</a></h2>
+<h2><a>Version 2002-01-30 (January 30, 2002)</a></h2>
 <ul>
 <li>Version bumped to 0.6.1 ( __version__ is now a PyString )</li>
 <li>Will now build for Python 2.2</li>
 without check, it crashes on sends to abstract classes like NSProxy.</li>
 <li>There are still problems with Delegates and Notifications.</li>
 </ul>
-<h2><a name="version-2001-03-17-march-17-2001">Version 2001-03-17 (March 17, 2001)</a></h2>
+<h2><a>Version 2001-03-17 (March 17, 2001)</a></h2>
 <ul>
 <li>moved to using distutils setup.py (requires small patch to distutils
 that has been submitted against python 2.1b1)</li>
 </ul>
-<h2><a name="version-2000-11-14-november-14-2000">Version 2000-11-14 (November 14, 2000)</a></h2>
+<h2><a>Version 2000-11-14 (November 14, 2000)</a></h2>
 <ul>
 <li>GNU_RUNTIME is likely completely broken</li>
 <li>Compiles on Mac OS X Server (python 2.0)</li>
 <li>Some pre-OSX stuff removed;  references to old APIs, etc... (but
 nowhere near clean)</li>
 </ul>
-<h2><a name="version-0-55-18-august-1998">Version 0.55, 18 August 1998</a></h2>
+<h2><a>Version 0.55, 18 August 1998</a></h2>
 <ul>
 <li>Here again, supporting GNU_RUNTIME and GNUstep Base! On my new Linux
 box I can finally test the module against them: I installed the
 </pre>
 </li>
 </ul>
-<h2><a name="version-0-54-24-march-1998">Version 0.54, 24 March 1998</a></h2>
+<h2><a>Version 0.54, 24 March 1998</a></h2>
 <ul>
 <li>OC_Pasteboard.[hm], OC_Stream.[mh] and ObjCStreams.m are definitively gone.</li>
 <li>OC_PythonObject derives from NSProxy.</li>
 </ul>
-<h2><a name="version-0-53-4-january-1998">Version 0.53, 4 January 1998</a></h2>
+<h2><a>Version 0.53, 4 January 1998</a></h2>
 <ul>
 <li>Tons of changes, retargeting the core functionality around the
 OpenSTEP API. This release basically matches the previous one
 if they are needed anymore.</li>
 <li>Updated LittleButtonedWindow demo.</li>
 </ul>
-<h2><a name="version-0-47-29-october-1996">Version 0.47, 29 October 1996</a></h2>
+<h2><a>Version 0.47, 29 October 1996</a></h2>
 <ul>
 <li>Misc/Makefile.pre.in automatically sets TARGET to <code><span>pyobjc</span></code>.</li>
 <li>ObjC.m splitted to ObjCObject.m ObjCMethod.m ObjCPointer.m
 <li>OC_Streams are mapped to ObjCStreams by pythonify_c_value and its
 counterpart.</li>
 </ul>
-<h2><a name="version-0-46-18-october-1996">Version 0.46, 18 October 1996</a></h2>
+<h2><a>Version 0.46, 18 October 1996</a></h2>
 <ul>
 <li>OC_Stream is now a subclass of NSData under Foundation.</li>
 <li>New Objective-C class: OC_Pasteboard. Use it instead of Pasteboard/
 <li>OC_Python.[hm] aren't in the package anymore.</li>
 <li>Setup.in directives changed again, due to OC_Python.m dropping.</li>
 </ul>
-<h2><a name="version-0-45-14-october-1996">Version 0.45, 14 October 1996</a></h2>
+<h2><a>Version 0.45, 14 October 1996</a></h2>
 <ul>
 <li>Double syntax: to make it easier for us to test and choose the
 better candidate, the only one that will be present in the final 1.0
 release. Keeping both would result in a speed penality.</li>
 <li>Revisited streams, in particular GNUstep support.</li>
 </ul>
-<h2><a name="version-0-44-9-october-1996">Version 0.44, 9 October 1996</a></h2>
+<h2><a>Version 0.44, 9 October 1996</a></h2>
 <ul>
 <li>Integers are now accepted too where floats or doubles are expected.</li>
 <li>New method: ObjC.make_pointer (1) returns an ObjCPointer containing
 <code><span>((void</span> <span>*)</span> <span>1)</span></code>.</li>
 </ul>
-<h2><a name="version-0-43-7-october-1996">Version 0.43, 7 October 1996</a></h2>
+<h2><a>Version 0.43, 7 October 1996</a></h2>
 <ul>
 <li>Completed ObjCStream implementation. There is now a new module, ObjCStreams
 which is automatically loaded by ObjC. You can access it as ObjC.streams.</li>
 libObjC.tex describing the main module, libObjCStreams.tex explains the
 stream facilities.</li>
 </ul>
-<h2><a name="version-0-42-4-october-1996">Version 0.42, 4 October 1996</a></h2>
+<h2><a>Version 0.42, 4 October 1996</a></h2>
 <ul>
 <li>You can pass initialization arguments when using the <code><span>Class()</span></code> syntax. You
 select the right initializer selector with the <code><span>init</span></code> keyword parameter.</li>
 <li>First cut on ObjCStream objects. Thanx to Bill Bumgarner for motivations.</li>
 <li>New demo ShellText, to test above points.</li>
 </ul>
-<h2><a name="version-0-41-2-october-1996">Version 0.41, 2 October 1996</a></h2>
+<h2><a>Version 0.41, 2 October 1996</a></h2>
 <ul>
 <li>Revised error messages: for arguments type mismatch they show the ObjC type
 expected.</li>
 <li>Setup.in directives changed. See the new file Modules/Setup.PyObjC.in</li>
 <li>Distribuited as a standalone package. Special thanks to Bill Bumgarner.</li>
 </ul>
-<h2><a name="version-0-4-27-september-1996">Version 0.4, 27 September 1996</a></h2>
+<h2><a>Version 0.4, 27 September 1996</a></h2>
 <ul>
 <li>Now handles methods returning doubles or floats.</li>
 <li>ObjCRuntime responds to .sel_is_mapped().</li>
 </ul>
-<h2><a name="version-0-31-26-september-1996">Version 0.31, 26 September 1996</a></h2>
+<h2><a>Version 0.31, 26 September 1996</a></h2>
 <ul>
 <li>It's now possible to use a different strategy to map ObjC method names to
 Python ones. Sooner or later we should decide the one to go, and drop the
 <li>ObjC.runtime.__dict__ added.</li>
 <li>ObjC.runtime.kind added.</li>
 </ul>
-<h2><a name="version-0-3-20-september-1996">Version 0.3, 20 September 1996</a></h2>
+<h2><a>Version 0.3, 20 September 1996</a></h2>
 <ul>
 <li>No user visible changes, just a little effort towards GNU_RUNTIME support.</li>
 </ul>
-<h2><a name="version-0-2-16-september-1996">Version 0.2, 16 September 1996</a></h2>
+<h2><a>Version 0.2, 16 September 1996</a></h2>
 <ul>
 <li>Accepts a struct.pack() string for pointer arguments, but...</li>
 <li>... New methods on ObjCMethod: .pack_argument and .unpack_argument:
 </pre>
 </li>
 </ul>
-<h2><a name="version-0-1-13-september-1996">Version 0.1, 13 September 1996</a></h2>
+<h2><a>Version 0.1, 13 September 1996</a></h2>
 <ul>
 <li>Correctly handle pointer arguments.</li>
 <li>New syntax to get a class: ObjC.runtime.NameOfClass</li>
 - New TinyURLService example in AppKit that demonstrates how to write
   a service that transforms URLs into their tinyurl.com equivalents.
 
+- Ported to Mac OS X on Intel. This is an initial, experimental port. The
+  Intel ABI has not been finalised yet. It is also possible to build fat
+  binaries, that option should not be used in production builds.
+
 Version 1.3.6 (2005-05-19)
 --------------------------
 

File libffi-src/include/ffi.h

+/* -----------------------------------------------------------------*-C-*-
+   libffi PyOBJC - Copyright (c) 1996-2003  Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+   The basic API is described in the README file.
+
+   The raw API is designed to bypass some of the argument packing
+   and unpacking on architectures for which it can be avoided.
+
+   The closure API allows interpreted functions to be packaged up
+   inside a C function pointer, so that they can be called as C functions,
+   with no understanding on the client side that they are interpreted.
+   It can also be used in other cases in which it is necessary to package
+   up a user specified parameter and a function pointer as a single
+   function pointer.
+
+   The closure API must be implemented in order to get its functionality,
+   e.g. for use by gij.  Routines are provided to emulate the raw API
+   if the underlying platform doesn't allow faster implementation.
+
+   More details on the raw and cloure API can be found in:
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+   and
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+   -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+#ifdef MACOSX
+
+#ifdef __i386__
+# define X86_DARWIN
+#elif defined(__ppc__)
+# define POWERPC_DARWIN
+#else
+# error "Unsupported MacOS X CPU type"
+#endif
+
+#else
+
+#error "Unsupported OS type"
+
+#endif
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+#include "fficonfig.h"
+
+#ifndef LIBFFI_ASM
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+   But we can find it either under the correct ANSI name, or under GNU
+   C's internal name.  */
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+#  define FFI_LONG_LONG_MAX LLONG_MAX
+# else
+#  ifdef __GNUC__
+#   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+#  endif
+# endif
+#endif
+
+#if SCHAR_MAX == 127
+# define ffi_type_uchar                ffi_type_uint8
+# define ffi_type_schar                ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort       ffi_type_uint16
+# define ffi_type_sshort       ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort       ffi_type_uint32
+# define ffi_type_sshort       ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint         ffi_type_uint16
+# define ffi_type_sint         ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint         ffi_type_uint32
+# define ffi_type_sint         ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint         ffi_type_uint64
+# define ffi_type_sint         ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#define ffi_type_ulong         ffi_type_uint64
+#define ffi_type_slong         ffi_type_sint64
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != 9223372036854775807
+  #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != 9223372036854775807
+ #error "long size not supported"
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t	*/
+/* can hold a pointer.							*/
+
+typedef struct _ffi_type
+{
+  size_t size;
+  unsigned short alignment;
+  unsigned short type;
+  /*@null@*/ struct _ffi_type **elements;
+} ffi_type;
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_longdouble;
+extern ffi_type ffi_type_pointer;
+
+
+typedef enum {
+  FFI_OK = 0,
+  FFI_BAD_TYPEDEF,
+  FFI_BAD_ABI 
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+  ffi_abi abi;
+  unsigned nargs;
+  /*@dependent@*/ ffi_type **arg_types;
+  /*@dependent@*/ ffi_type *rtype;
+  unsigned bytes;
+  unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+  FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+#  define FFI_SIZEOF_ARG        4
+# elif LONG_MAX == 9223372036854775807
+#  define FFI_SIZEOF_ARG        8
+# endif
+#endif
+
+typedef union {
+  ffi_sarg  sint;
+  ffi_arg   uint;
+  float	    flt;
+  char      data[FFI_SIZEOF_ARG];
+  void*     ptr;
+} ffi_raw;
+
+void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, 
+		   void (*fn)(), 
+		   /*@out@*/ void *rvalue, 
+		   /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter	*/
+/* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
+/* longs and doubles are followed by an empty 64-bit word.		*/
+
+void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, 
+		        void (*fn)(), 
+		        /*@out@*/ void *rvalue, 
+		        /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+  ffi_cif   *cif;
+  void     (*fun)(ffi_cif*,void*,void**,void*);
+  void      *user_data;
+} ffi_closure;
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+		  ffi_cif *,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data);
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+  void      *user_data;
+
+} ffi_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_raw_closure*,
+		           ffi_cif *cif,
+		           void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		           void *user_data);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
+			ffi_abi abi,
+			unsigned int nargs, 
+			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
+			/*@dependent@*/ ffi_type **atypes);
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)())f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID       0    
+#define FFI_TYPE_INT        1
+#define FFI_TYPE_FLOAT      2    
+#define FFI_TYPE_DOUBLE     3
+#ifdef HAVE_LONG_DOUBLE
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8      5   
+#define FFI_TYPE_SINT8      6
+#define FFI_TYPE_UINT16     7 
+#define FFI_TYPE_SINT16     8
+#define FFI_TYPE_UINT32     9
+#define FFI_TYPE_SINT32     10
+#define FFI_TYPE_UINT64     11
+#define FFI_TYPE_SINT64     12
+#define FFI_TYPE_STRUCT     13
+#define FFI_TYPE_POINTER    14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST       FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

File libffi-src/include/fficonfig.h

+/*
+ * Manually created fficonfig.h for darwin on PowerPC or Intel 
+ *
+ * This file is manually generated to do away with the need for autoconf and
+ * therefore make it easier to cross-compile and build fat binaries.
+ *
+ * NOTE: This file was added by PyObjC.
+ */
+
+#ifndef MACOSX
+# error "This file is only supported on Mac OS X"
+#endif
+
+#if defined(__i386__)
+#   define BYTEORDER 1234
+#   undef HOST_WORDS_BIG_ENDIAN
+#   undef WORDS_BIGENDIAN
+#   define SIZEOF_DOUBLE 8
+#   define HAVE_LONG_DOUBLE 1
+#   define SIZEOF_LONG_DOUBLE 16
+#elif defined(__ppc__)
+#   define BYTEORDER 4321
+#   define HOST_WORDS_BIG_ENDIAN 1
+#   define WORDS_BIGENDIAN 1
+#   define SIZEOF_DOUBLE 8
+
+#if __GNUC__ >= 4
+#   define HAVE_LONG_DOUBLE 1
+#   define SIZEOF_LONG_DOUBLE 16 
+#else
+#   undef HAVE_LONG_DOUBLE
+#   define SIZEOF_LONG_DOUBLE 8 
+#endif /* __GNUC__ */
+
+#else
+#  error "Unknown CPU type"
+#endif
+
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+#define EH_FRAME_FLAGS "aw"
+
+/* Define this if you want extra debugging. */
+/* #undef FFI_DEBUG */
+
+/* Define this is you do not want support for the raw API. */
+#define FFI_NO_RAW_API 1
+
+/* Define this is you do not want support for aggregate types. */
+/* #undef FFI_NO_STRUCTS */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#define HAVE_ALLOCA_H 1
+
+/* Define if your assembler supports .register. */
+/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
+
+/* Define if your assembler and linker support unaligned PC relative relocs.
+   */
+/* #undef HAVE_AS_SPARC_UA_PCREL */
+
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+#define HAVE_MMAP_ANON 1
+
+/* Define if mmap of /dev/zero works. */
+/* #undef HAVE_MMAP_DEV_ZERO */
+
+/* Define if read-only mmap of a plain file works. */
+#define HAVE_MMAP_FILE 1
+
+/* Define if .eh_frame sections should be read-only. */
+/* #undef HAVE_RO_EH_FRAME */
+
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Name of package */
+#define PACKAGE "libffi"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://gcc.gnu.org/bugs.html"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libffi"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libffi 2.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libffi"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.1"
+
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown */
+/*#undef STACK_DIRECTION */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define this if you are using Purify and want to suppress spurious messages.
+   */
+/*#undef USING_PURIFY*/
+
+/* Version number of package */
+#define VERSION "2.1-pyobjc"
+

File libffi-src/include/ffitarget.h

+/*
+ * Dispatch to the right ffitarget file. This file is PyObjC specific, in a
+ * normal build the build environment copies the file to the right location or
+ * sets up the right include flags. We want to do neither because that would
+ * make building fat binaries harder.
+ */
+#if defined(__i386__)
+
+#include "../src/x86/ffitarget.h"
+
+#elif defined(__ppc__)
+
+#include "../src/powerpc/ffitarget.h"
+
+#else
+
+#errror "Unsupported CPU type"
+
+#endif

File libffi-src/src/powerpc/darwin.S

+#ifdef __ppc__
 /* -----------------------------------------------------------------------
    darwin.S - Copyright (c) 2000 John Hornkvist
 
         .align 2
 LLFB0$non_lazy_ptr:
         .long   LFB0
+#endif

File libffi-src/src/powerpc/darwin_closure.S

+#ifdef __ppc__
 /* -----------------------------------------------------------------------
    darwin_closure.S - Copyright (c) 2002 2003 Free Software Foundation,
    Inc. based on ppc_closure.S
 	.align 2
 LLFB1$non_lazy_ptr:
         .long LFB1
+#endif

File libffi-src/src/powerpc/ffi_darwin.c

+#ifdef __ppc__
 /* -----------------------------------------------------------------------
    ffi.c - Copyright (c) 1998 Geoffrey Keating
 
   /* Tell ffi_closure_ASM to perform return type promotions.  */
   return cif->rtype->type;
 }
+#endif

File libffi-src/src/x86/darwin.S

+#ifdef __i386__
 /* -----------------------------------------------------------------------
    darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003  Red Hat, Inc.
    
 #endif
 
 #endif /* ifndef __x86_64__ */
+
+#endif /* defined __i386__ */

File libffi-src/src/x86/ffi_darwin.c

+#ifdef __i386__
 /* -----------------------------------------------------------------------
    ffi.c - Copyright (c) 1996, 1998, 1999, 2001  Red Hat, Inc.
            Copyright (c) 2002  Ranjit Mathew
 					 void** args, ffi_cif* cif);
 static void ffi_closure_SYSV (ffi_closure *)
      __attribute__ ((regparm(1)));
+#if !FFI_NO_RAW_API
 static void ffi_closure_raw_SYSV (ffi_raw_closure *)
      __attribute__ ((regparm(1)));
+#endif
 
 /* This function is jumped to by the trampoline */
 
 #endif
 
 #endif /* __x86_64__  */
+
+#endif /* __i386__ */

File setup-lib/build_libffi.py

-import os
-import sys, platform
-import shutil
-from distutils.cmd import Command
-from distutils.util import get_platform
-from distutils.errors import *
-from pyobjc_setup_utils import runtasks
-
-class build_libffi(Command):
-    description = "build libffi"
-    user_options = [
-        ('libffi-sources=', None,
-        "location of libffi sources (defaults to \"libffi-src\")"),
-    ]
-
-    def initialize_options(self):
-        self.finalized = False
-        if sys.platform != 'darwin' and os.path.exists('/usr/include/ffi.h'):
-            self.libffi_sources = None
-        else:
-            self.libffi_sources = 'libffi-src'
-
-    def finalize_options(self):
-        if self.libffi_sources is not None:
-            self.libffi_sources = os.path.abspath(self.libffi_sources)
-            if not os.path.isdir(self.libffi_sources):
-                print >>sys.stderr, "LIBFFI_SOURCES is not a directory: %s" % (self.libffi_sources,)
-                print >>sys.stderr, "\tSee Install.txt or Install.html for more information."
-                raise DistutilsFileError('LIBFFI_SOURCES is not a directory')
-            build_base = os.path.abspath(self.reinitialize_command('build').build_base)
-            base = self.libffi_base = os.path.join(build_base, 'libffi.' + get_platform())
-            self.cflags = ["-isystem", os.path.join(base, "include")]
-            extra = os.path.join(base, 'lib', 'gcc', 'include', 'libffi')
-            if os.path.exists(extra):
-                self.cflags.extend(['-isystem', extra])
-            self.ldflags = ['-L' + os.path.join(base, 'lib'), '-lffi']
-        else:
-            self.cflags = []
-            self.ldflags = ['-lffi']
-        self.finalized = True
-
-    def run(self):
-        self.finalize_options()
-        if self.libffi_sources is not None:
-            inst_dir = self.libffi_base
-            build_dir = os.path.join(inst_dir, 'BLD')
-            if not os.path.exists(build_dir):
-                os.makedirs(build_dir)
-
-            if not os.path.exists(os.path.join(inst_dir, 'lib', 'libffi.a')):
-                # No pre-build version available, build it now.
-                # Do not use a relative path for the build-tree, libtool on
-                # MacOS X doesn't like that.
-
-                cflags = os.environ.get('CFLAGS', None)
-                if sys.platform == 'darwin' and platform.machine() != 'Power Macintosh':
-                    os.environ['CFLAGS'] = '-O0 -fPIC'
-
-                runtasks('Building FFI',
-                    [os.path.join(self.libffi_sources, 'configure'),
-                        '--prefix=' + inst_dir, '--disable-shared', '--enable-static'],
-                    ['make', 'install'],
-                    cwd=build_dir)
-
-                if cflags is not None:
-                    os.environ['CFLAGS'] = cflags
-                elif 'CFLAGS' in os.environ:
-                    del os.environ['CFLAGS']
-
-                # make sure cflags is set correctly
-                self.finalize_options()
-
-cmdclass = dict(build_libffi=build_libffi)

File setup-lib/di_build_ext.py

             build_ext.run(self)
 
     def build_extension(self, ext):
-        if getattr(ext, 'use_libffi', False):
-            libffi = self.reinitialize_command('build_libffi')
-            libffi.run()
-            ext.extra_compile_args[:0] = libffi.cflags
-            ext.extra_link_args[:0] = libffi.ldflags
-            ext.use_libffi = False
         build_ext.build_extension(self, ext)
 
 

File setup-lib/pyobjc_commands.py

-import build_libffi
 import build_html
 import di_build_ext
 import di_sdist
 import glob
 import site
 
+# If true we'll build universal binaries on systems with the 10.4u SDK running
+# OS X 10.4 or later.
+# 
+# NOTE: This is an experimental feature.
+AUTO_UNIVERSAL=0
+
 # We need at least Python 2.3
 MIN_PYTHON = (2, 3)
 
 from distutils.core import setup, Extension
 import os
 
+
 def frameworks(*args):
     lst = []
     for arg in args:
         "-no-cpp-precomp",
         "-Wno-long-double",
         "-g",
-        "-O0",
+        #"-O0",
 
         # Loads of warning flags
         "-Wall", "-Wstrict-prototypes", "-Wmissing-prototypes",
     EXCEPTION_HANDLING_LDFLAGS = frameworks('CoreFoundation', 'ExceptionHandling', 'Foundation')
     PREFPANES_LDFLAGS = frameworks('CoreFoundation', 'PreferencePanes', 'Foundation')
 
+    BASE_LDFLAGS = []
+    if AUTO_UNIVERSAL:
+        if os.path.exists('/Developer/SDKs/MacOSX10.4u.sdk') and int(os.uname()[2].split('.')[0]) >= 8:
+            CFLAGS.extend([
+                    '-arch', 'i386', 
+                    '-arch', 'ppc',
+                    '-isysroot', '/Developer/SDKs/MacOSX10.4u.sdk',
+            ])
+            BASE_LDFLAGS.extend([
+                    '-arch', 'i386', 
+                    '-arch', 'ppc',
+                    '-isysroot', '/Developer/SDKs/MacOSX10.4u.sdk',
+                    '-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk',
+            ])
+
+
 else:
     #
     # GNUstep
     # support.
     gs_root = gs_root + '/Library'
 
+    BASE_LDFLAGS=[]
+
     gs_cpu = os.environ.get('GNUSTEP_HOST_CPU')
     gs_os = os.environ.get('GNUSTEP_HOST_OS')
     gs_combo = os.environ.get('LIBRARY_COMBO')
 
 CFLAGS.append('-Ibuild/codegen/')
 
+FFI_CFLAGS=['-Ilibffi-src/include']
+
+# The list below includes the source files for all CPU types that we run on
+# this makes it easier to build fat binaries on Mac OS X.
+FFI_SOURCE=[
+    "libffi-src/src/types.c",
+    "libffi-src/src/prep_cif.c",
+    "libffi-src/src/x86/ffi_darwin.c",
+    "libffi-src/src/x86/darwin.S",
+    "libffi-src/src/powerpc/ffi_darwin.c",
+    "libffi-src/src/powerpc/darwin.S",
+    "libffi-src/src/powerpc/darwin_closure.S",
+]
+
+# Patch distutils: it needs to compile .S files as well.
+from distutils.unixccompiler import UnixCCompiler
+UnixCCompiler.src_extensions.append('.S')
+del UnixCCompiler
+
+
 CorePackages = [ 'objc' ]
 objcExtension = Extension("objc._objc",
-    glob.glob(os.path.join('Modules', 'objc', '*.m')),
-    extra_compile_args=CFLAGS,
-    extra_link_args=OBJC_LDFLAGS,
+    FFI_SOURCE + list(glob.glob(os.path.join('Modules', 'objc', '*.m'))),
+    extra_compile_args=CFLAGS + list(FFI_CFLAGS),
+    extra_link_args=OBJC_LDFLAGS + BASE_LDFLAGS,
 )
-objcExtension.use_libffi = True
 
 CoreExtensions =  [ objcExtension ]
 
 for test_source in glob.glob(os.path.join('Modules', 'objc', 'test', '*.m')):
     name, ext = os.path.splitext(os.path.basename(test_source))
-    ext = Extension('objc.test.' + name,
-        [test_source],
-        extra_compile_args=['-IModules/objc'] + CFLAGS,
-        extra_link_args=OBJC_LDFLAGS)
-    if name == 'ctests':
-        ext.use_libffi = True
+
+    if name != 'ctests':
+        ext = Extension('objc.test.' + name,
+            [test_source],
+            extra_compile_args=['-IModules/objc'] + CFLAGS,
+            extra_link_args=OBJC_LDFLAGS)
+    else:
+        ext = Extension('objc.test.' + name,
+            [test_source] + FFI_SOURCE,
+            extra_compile_args=['-IModules/objc'] + CFLAGS + FFI_CFLAGS,
+            extra_link_args=OBJC_LDFLAGS + BASE_LDFLAGS)
+
     CoreExtensions.append(ext)
 
 CoreFoundationDepends = dict()
                         "-IModules/objc",
                     ] + CFLAGS,
                     extra_link_args=[
-                    ] + FND_LDFLAGS,
+                    ] + FND_LDFLAGS + BASE_LDFLAGS,
                     **FoundationDepends
                     ),
         ])
                         "-IModules/objc",
                     ] + CFLAGS,
                     extra_link_args=[
-                    ] + APPKIT_LDFLAGS,
+                    ] + APPKIT_LDFLAGS + BASE_LDFLAGS,
                     **AppKitDepends
                     ),
       ])
                         '-IModules/objc',
                       ] + CFLAGS,
                       extra_link_args=[
-                      ] + ADDRESSBOOK_LDFLAGS,
+                      ] + ADDRESSBOOK_LDFLAGS + BASE_LDFLAGS,
                       **AddressBookDepends
                       ),
         ])
                         '-IModules/objc',
                       ] + CFLAGS,
                       extra_link_args=[
-                      ] + CF_LDFLAGS,
+                      ] + CF_LDFLAGS + BASE_LDFLAGS,
                       **CoreFoundationDepends),
         ])
 
                         '-IModules/objc',
                       ] + CFLAGS,
                       extra_link_args=[
-                      ] + SECURITY_INTERFACE_LDFLAGS,
+                      ] + SECURITY_INTERFACE_LDFLAGS + BASE_LDFLAGS,
                       **SecurityInterfaceDepends
                       ),
         ])
                         '-IModules/objc',
                       ] + CFLAGS,
                       extra_link_args=[
-                      ] + EXCEPTION_HANDLING_LDFLAGS,
+                      ] + EXCEPTION_HANDLING_LDFLAGS + BASE_LDFLAGS,
                       **ExceptionHandlingDepends
                       ),
         ])
                         '-IModules/objc',
                       ] + CFLAGS,
                       extra_link_args=[
-                      ] + PREFPANES_LDFLAGS,
+                      ] + PREFPANES_LDFLAGS + BASE_LDFLAGS,
                       **PrefPanesDepends
                       ),
         ])