Patch #557719 by Tony Lownds, slightly massaged by me: streamline the
OSX framework build process. Things fixed/modified:
- the filesystem case-sensitivity test now works for builds outside
  the source directory
- various other fixes for building outside the source directory
- python.app now has a target in the main Makefile
- WASTE and AquaTk are found more automatically
diff --git a/Mac/OSX/Mac.pth b/Mac/OSX/Mac.pth
new file mode 100644
index 0000000..6ab4acd
--- /dev/null
+++ b/Mac/OSX/Mac.pth
@@ -0,0 +1,2 @@
+../../../Mac/Lib
+../../../Mac/Lib/lib-scriptpackages
diff --git a/Mac/OSX/Makefile b/Mac/OSX/Makefile
index f7baeb4..aadf340 100644
--- a/Mac/OSX/Makefile
+++ b/Mac/OSX/Makefile
@@ -1,4 +1,11 @@
-PYTHONBUILDDIR=../..
+# This file can be invoked from the "python.app" target in the 
+# main Makefile. The next two variables are overridden on the 
+# commandline in that case.
+
+# assume user was invoking from Mac/OSX directory and building in source tree
+PYTHONBUILDDIR = ../..
+PYTHONSRCDIR = ../..
+
 INSTALLDIR=/Library/Frameworks/Python.framework/Versions/Current
 APPINSTALLDIR=/Applications/Python.app
 
@@ -17,8 +24,8 @@
 STRIPFLAG=-s
 OPT=-g -O3 -Wall -Wstrict-prototypes -Wno-long-double -no-cpp-precomp \
 	-fno-common -dynamic
-INCLUDES=-I$(PYTHONBUILDDIR) -I$(PYTHONBUILDDIR)/Include \
-	-I$(PYTHONBUILDDIR)/Mac/Include
+INCLUDES=-I$(PYTHONBUILDDIR) -I$(PYTHONSRCDIR)/Include \
+	-I$(PYTHONSRCDIR)/Mac/Include
 DEFINES=-DHAVE_CONFIG_H
 
 CFLAGS=$(OPT) $(DEFINES) $(INCLUDES)
@@ -36,11 +43,11 @@
 	$(LD) $(LDFLAGS) $(OBJECTS) -o pythonforbundle
 
 PYTHON=$(PYTHONBUILDDIR)/python.exe
-APPTEMPLATE=$(PYTHONBUILDDIR)/Mac/OSXResources/app
+APPTEMPLATE=$(PYTHONSRCDIR)/Mac/OSXResources/app
 APPSUBDIRS=MacOS Resources Resources/English.lproj
-RESOURCEDIR=$(PYTHONBUILDDIR)/Mac/Resources
+RESOURCEDIR=$(PYTHONSRCDIR)/Mac/Resources
 RESOURCEFILE=python.rsrc
-RFCONVERTER=$(PYTHONBUILDDIR)/Mac/Lib/applesingle.py
+RFCONVERTER=$(PYTHONSRCDIR)/Mac/Lib/applesingle.py
 install: pythonforbundle
 	@for i in $(APPINSTALLDIR) $(APPINSTALLDIR)/Contents; do \
 		if test ! -d $$i; then \
@@ -89,7 +96,7 @@
 	$(INSTALL_DATA) $(RESOURCEFILE) $(APPINSTALLDIR)/Contents/Resources/$(RESOURCEFILE)
 		
 LIBDEST=$(INSTALLDIR)/Mac/Lib
-LIBSRC=$(PYTHONBUILDDIR)/Mac/Lib
+LIBSRC=$(PYTHONSRCDIR)/Mac/Lib
 LIBSUBDIRS= \
 	Carbon \
 	lib-scriptpackages \
@@ -105,7 +112,7 @@
 	mkcwproject/template-carbon \
 	mkcwproject/template-ppc
 TOOLSDEST=$(INSTALLDIR)/Mac/Tools
-TOOLSSRC=$(PYTHONBUILDDIR)/Mac/Tools
+TOOLSSRC=$(PYTHONSRCDIR)/Mac/Tools
 TOOLSSUBDIRS=IDE
 installmacsubtree:
 	@for i in $(LIBDEST) $(TOOLSDEST); \
@@ -197,8 +204,7 @@
 		done; \
 	done
 
-	@echo '** Copy the contents of sample_sitecustomize.py (or similar code) into'
-	@echo '**' $(INSTALLDIR)/lib/python2.3/sitecustomize.py
+	$(INSTALL_DATA) $(PYTHONSRCDIR)/Mac/OSX/Mac.pth $(INSTALLDIR)/lib/python2.3/site-packages/
 	
 # Put symlinks "python" and "pythonw" in the standard place
 installunixprograms: $(INSTALLED_PYTHON) pythonw.sh
@@ -213,3 +219,12 @@
 
 	@echo '** Copy the contents of sample_sitecustomize.py (or similar code) into'
 	@echo '**' $(INSTALLDIR)/lib/python2.3/sitecustomize.py
+
+
+# Rules to build each file in OBJECTS - is there a better way?
+$(PYTHONBUILDDIR)/Mac/Python/macmain.o: $(PYTHONSRCDIR)/Mac/Python/macmain.c
+	$(CC) $(CFLAGS) -c $(PYTHONSRCDIR)/Mac/Python/macmain.c -o $@
+
+$(PYTHONBUILDDIR)/Mac/Python/macgetargv.o: $(PYTHONSRCDIR)/Mac/Python/macgetargv.c
+	$(CC) $(CFLAGS) -c $(PYTHONSRCDIR)/Mac/Python/macgetargv.c -o $@
+
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 0590fa8..98fb113 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -798,6 +798,12 @@
 	$(LN) -fsh Versions/Current/Resources $(PYTHONFRAMEWORKINSTALLDIR)/Resources
 	$(INSTALL_DATA) $(LDLIBRARY) $(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY)
 
+# Build Python executable that can run GUI code. Another MacOSX pseudo
+# target.
+python.app:
+	$(MAKE) -f $(srcdir)/Mac/OSX/Makefile install installmacsubtree \
+		PYTHONSRCDIR=$(srcdir) PYTHONBUILDDIR=.
+
 # Build the toplevel Makefile
 Makefile.pre: Makefile.pre.in config.status
 	CONFIG_FILES=Makefile.pre CONFIG_HEADERS= $(SHELL) config.status
diff --git a/configure b/configure
index 4c7a436..8ae9eab 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.323 .
+# From configure.in Revision: 1.325 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.53.
 #
@@ -2951,7 +2951,7 @@
 
 echo "$as_me:$LINENO: checking for case-insensitive build directory" >&5
 echo $ECHO_N "checking for case-insensitive build directory... $ECHO_C" >&6
-if test -d "python"
+if test -d "${srcdir}/python"
 then
     echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6
@@ -11444,6 +11444,7 @@
 
 
 
+
 for ac_func in alarm chown chroot clock confstr ctermid ctermid_r execv \
  fchdir flock fork fsync fdatasync fpathconf ftime ftruncate \
  gai_strerror getgroups getlogin getpeername getpgid getpid getpwent getwd \
@@ -15924,7 +15925,7 @@
 done
 
 
-SRCDIRS="Parser Grammar Objects Python Modules"
+SRCDIRS="Parser Grammar Objects Python Modules Mac Mac/Python"
 echo "$as_me:$LINENO: checking for build directories" >&5
 echo $ECHO_N "checking for build directories... $ECHO_C" >&6
 for dir in $SRCDIRS; do
diff --git a/configure.in b/configure.in
index 5a53aab..eeab200 100644
--- a/configure.in
+++ b/configure.in
@@ -221,7 +221,7 @@
 # case we give a warning if no ext is given
 AC_SUBST(BUILDEXEEXT)
 AC_MSG_CHECKING(for case-insensitive build directory)
-if test -d "python"
+if test -d "${srcdir}/python"
 then
     AC_MSG_RESULT(yes)
     BUILDEXEEXT=.exe
@@ -2316,7 +2316,7 @@
 done
 
 AC_SUBST(SRCDIRS)
-SRCDIRS="Parser Grammar Objects Python Modules"
+SRCDIRS="Parser Grammar Objects Python Modules Mac Mac/Python"
 AC_MSG_CHECKING(for build directories)
 for dir in $SRCDIRS; do
     if test ! -d $dir; then
diff --git a/setup.py b/setup.py
index 39997e4..1012645 100644
--- a/setup.py
+++ b/setup.py
@@ -718,7 +718,7 @@
                                    ['macfsmodule.c',
                                     '../Python/getapplbycreator.c'],
                         extra_link_args=['-framework', 'Carbon']) )
-            exts.append( Extension('_CF', ['cf/_CFmodule.c'],
+            exts.append( Extension('_CF', ['cf/_CFmodule.c', 'cf/pycfbridge.c'],
                         extra_link_args=['-framework', 'CoreFoundation']) )
             exts.append( Extension('_Res', ['res/_Resmodule.c'],
                         extra_link_args=['-framework', 'Carbon']) )
@@ -767,21 +767,26 @@
                         extra_link_args=['-framework', 'Carbon']) )
                 exts.append( Extension('_TE', ['te/_TEmodule.c'],
                         extra_link_args=['-framework', 'Carbon']) )
-                # As there is no standardized place (yet) to put user-installed
-                # Mac libraries on OSX you should put a symlink to your Waste
-                # installation in the same folder as your python source tree.
-                # Or modify the next two lines:-)
-                waste_incs = find_file("WASTE.h", [], ["../waste/C_C++ Headers"])
+                # As there is no standardized place (yet) to put
+                # user-installed Mac libraries on OSX, we search for "waste"
+                # in parent directories of the Python source tree. You
+                # should put a symlink to your Waste installation in the
+                # same folder as your python source tree.  Or modify the
+                # next few lines:-)
+                waste_incs = find_file("WASTE.h", [], 
+                        ['../'*n + 'waste/C_C++ Headers' for n in (0,1,2,3,4)])
                 waste_libs = find_library_file(self.compiler, "WASTE", [],
-                        ["../waste/Static Libraries"])
+			["../"*n + "waste/Static Libraries" for n in (0,1,2,3,4)])
                 if waste_incs != None and waste_libs != None:
+                    (srcdir,) = sysconfig.get_config_vars('srcdir')
                     exts.append( Extension('waste',
-                                   ['waste/wastemodule.c',
+                                   ['waste/wastemodule.c'] + [
+                                    os.path.join(srcdir, d) for d in 
                                     'Mac/Wastemods/WEObjectHandlers.c',
                                     'Mac/Wastemods/WETabHooks.c',
                                     'Mac/Wastemods/WETabs.c'
                                    ],
-                                   include_dirs = waste_incs + ['Mac/Wastemods'],
+                                   include_dirs = waste_incs + [os.path.join(srcdir, 'Mac/Wastemods')],
                                    library_dirs = waste_libs,
                                    libraries = ['WASTE'],
                                    extra_link_args = ['-framework', 'Carbon'],
@@ -794,10 +799,71 @@
         # Call the method for detecting whether _tkinter can be compiled
         self.detect_tkinter(inc_dirs, lib_dirs)
 
+    def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
+        # The _tkinter module, using frameworks. Since frameworks are quite
+        # different the UNIX search logic is not sharable.
+        from os.path import join, exists
+        framework_dirs = [
+            '/System/Library/Frameworks/', 
+            '/Library/Frameworks', 
+            join(os.getenv('HOME'), '/Library/Frameworks')
+        ]
 
+        # Find the directory that contains the Tcl.framwork and Tk.framework
+        # bundles.
+        # XXX distutils should support -F!
+        for F in framework_dirs:
+            # both Tcl.framework and Tk.framework should be present 
+            for fw in 'Tcl', 'Tk':
+            	if not exists(join(F, fw + '.framework')):
+                    break
+            else:
+                # ok, F is now directory with both frameworks. Continure
+                # building
+                break
+        else:
+            # Tk and Tcl frameworks not found. Normal "unix" tkinter search
+            # will now resume.
+            return 0
+                
+        # For 8.4a2, we must add -I options that point inside the Tcl and Tk
+        # frameworks. In later release we should hopefully be able to pass
+        # the -F option to gcc, which specifies a framework lookup path. 
+        #
+        include_dirs = [
+            join(F, fw + '.framework', H) 
+            for fw in 'Tcl', 'Tk'
+            for H in 'Headers', 'Versions/Current/PrivateHeaders'
+        ]
+
+        # For 8.4a2, the X11 headers are not included. Rather than include a 
+        # complicated search, this is a hard-coded path. It could bail out
+        # if X11 libs are not found...
+        include_dirs.append('/usr/X11R6/include')
+        frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
+
+        ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
+                        define_macros=[('WITH_APPINIT', 1)],
+                        include_dirs = include_dirs,
+                        libraries = [],
+                        extra_compile_args = frameworks,
+                        extra_link_args = frameworks,
+                        )
+        self.extensions.append(ext)
+        return 1
+
+         
     def detect_tkinter(self, inc_dirs, lib_dirs):
         # The _tkinter module.
 
+        # Rather than complicate the code below, detecting and building
+        # AquaTk is a separate method. Only one Tkinter will be built on
+        # Darwin - either AquaTk, if it is found, or X11 based Tk.
+        platform = self.get_platform()
+        if platform == 'darwin' and \
+           self.detect_tkinter_darwin(inc_dirs, lib_dirs):
+          return
+
         # Assume we haven't found any of the libraries or include files
         # The versions with dots are used on Unix, and the versions without
         # dots on Windows, for detection by cygwin.
@@ -835,7 +901,6 @@
                 include_dirs.append(dir)
 
         # Check for various platform-specific directories
-        platform = self.get_platform()
         if platform == 'sunos5':
             include_dirs.append('/usr/openwin/include')
             added_lib_dirs.append('/usr/openwin/lib')