From b6e9cad34ce46a6a733d8aa5bf5b9d389fa1316f Mon Sep 17 00:00:00 2001
From: Jack Jansen <jack.jansen@cwi.nl>
Date: Wed, 15 Aug 2001 01:26:28 +0000
Subject: [PATCH] Lots of changes in the framework support: - Made framework
 builds work for MacOSX. The configure arg is now   "--enable-framework". -
 Added an install target frameworkinstall which installs the framework. -
 Ripped out Next/OpenStep support, which was broken anyway. - Made the MacOSX
 toolbox glue dependant on a --enable-toolbox-glue   configure arg. This
 should make naked darwin build work again (untested).

A few targets have been added to Makefile.pre.in, and on inspection they
look harmless to non-MacOSX machines, but it is worth checking.

Closes bug #420601 and patch #450350.
---
 Makefile.pre.in |  79 ++++++++++++++++-
 configure.in    | 221 ++++++++++++++++++++++++++----------------------
 2 files changed, 197 insertions(+), 103 deletions(-)

diff --git a/Makefile.pre.in b/Makefile.pre.in
index 1e4334db5c..d617ee291d 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -101,6 +101,12 @@ DESTSHARED=	$(BINLIBDEST)/lib-dynload
 # Executable suffix (.exe on Windows and Mac OS X)
 EXE=		@EXEEXT@
 
+# Short name and location for Mac OS X Python framework
+PYTHONFRAMEWORK=	@PYTHONFRAMEWORK@
+PYTHONFRAMEWORKDIR=	@PYTHONFRAMEWORKDIR@
+PYTHONFRAMEWORKPREFIX=	@PYTHONFRAMEWORKPREFIX@
+PYTHONFRAMEWORKINSTALLDIR= @PYTHONFRAMEWORKINSTALLDIR@
+
 # Modes for directories, executables and data files created by the
 # install process.  Default to user-only-writable for all file types.
 DIRMODE=	755
@@ -126,7 +132,9 @@ DIST=		$(DISTFILES) $(DISTDIRS)
 
 LIBRARY=	@LIBRARY@
 LDLIBRARY=      @LDLIBRARY@
+BLDLIBRARY=     @BLDLIBRARY@
 DLLLIBRARY=	@DLLLIBRARY@
+LDLIBRARYDIR=   @LDLIBRARYDIR@
 
 
 LIBS=		@LIBS@
@@ -280,7 +288,7 @@ all:		$(PYTHON) oldsharedmods sharedmods
 $(PYTHON):	Modules/$(MAINOBJ) $(LDLIBRARY)
 		$(LINKCC) $(LDFLAGS) $(LINKFORSHARED) -o $@ \
 			Modules/$(MAINOBJ) \
-			$(LDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
+			$(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
 
 platform: $(PYTHON)
 	./$(PYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
@@ -329,7 +337,7 @@ libpython$(VERSION).so:	$(LIBRARY)
 	esac
 
 # This rule is here for OPENSTEP/Rhapsody/MacOSX
-libpython$(VERSION).dylib: $(LIBRARY)
+$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): $(LIBRARY) $(PYTHONFRAMEWORKDIR)
 	libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
 		-framework System @LIBTOOL_CRUFT@ 
 
@@ -631,6 +639,7 @@ $(srcdir)/Lib/$(PLATDIR):
 	cp $(srcdir)/Lib/plat-generic/regen $(srcdir)/Lib/$(PLATDIR)/regen
 	export PATH; PATH="`pwd`:$$PATH"; \
 	export PYTHONPATH; PYTHONPATH="`pwd`/Lib"; \
+	export DYLD_FRAMEWORK_PATH; DYLD_FRAMEWORK_PATH="`pwd`"; \
 	export EXE; EXE="$(EXE)"; \
 	cd $(srcdir)/Lib/$(PLATDIR); ./regen
 
@@ -665,8 +674,12 @@ libainstall:	all
 		fi; \
 	done
 	@if test -d $(LDLIBRARY); then :; else \
-		$(INSTALL_DATA) $(LDLIBRARY) $(LIBPL)/$(LDLIBRARY) ; \
-		$(RANLIB) $(LIBPL)/$(LDLIBRARY) ; \
+		if test -z "$(PYTHONFRAMEWORKDIR)"; then \
+			$(INSTALL_DATA) $(LDLIBRARY) $(LIBPL)/$(LDLIBRARY) ; \
+			$(RANLIB) $(LIBPL)/$(LDLIBRARY) ; \
+		else \
+			echo Skip install of $(LDLIBRARY) - use make frameworkinstall; \
+		fi; \
 	fi
 	$(INSTALL_DATA) Modules/config.c $(LIBPL)/config.c
 	$(INSTALL_DATA) Modules/$(MAINOBJ) $(LIBPL)/$(MAINOBJ)
@@ -711,6 +724,64 @@ sharedinstall:
 	./$(PYTHON) -E $(srcdir)/setup.py install \
 		--install-platlib=$(DESTSHARED)
 
+# Install a MacOSX framework During build (before
+# setup.py), make a minimal Python.framework directory structure in the build
+# directory. This framework is minimal, it doesn't contain the Lib directory
+# and such, but together with some magic in Modules/getpath.c it is good enough
+# to run python from the install dir.
+
+FRAMEWORKDEST=$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)
+RESSRCDIR=$(srcdir)/Mac/OSXResources/framework
+$(PYTHONFRAMEWORKDIR): $(RESSRCDIR)/Info.plist \
+                $(RESSRCDIR)/version.plist \
+                $(RESSRCDIR)/English.lproj/InfoPlist.strings
+	@if test -z "$(PYTHONFRAMEWORKDIR)"; then \
+		echo Not configured with --enable-framework; \
+		exit; \
+	else true; \
+	fi
+	$(INSTALL) -d -m $(DIRMODE)  $(FRAMEWORKDEST)/Resources/English.lproj
+	$(INSTALL_DATA) $(RESSRCDIR)/Info.plist $(FRAMEWORKDEST)/Resources/Info.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/version.plist $(FRAMEWORKDEST)/Resources/version.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/English.lproj/InfoPlist.strings \
+		$(FRAMEWORKDEST)/Resources/English.lproj/InfoPlist.strings
+	$(LN) -fs $(VERSION) $(PYTHONFRAMEWORKDIR)/Versions/Current
+	$(LN) -fs Versions/Current/Python $(PYTHONFRAMEWORKDIR)/Python
+	$(LN) -fs Versions/Current/Headers $(PYTHONFRAMEWORKDIR)/Headers
+	$(LN) -fs Versions/Current/Resources $(PYTHONFRAMEWORKDIR)/Resources
+	
+# On install, we re-make the framework
+# structure in the install location, /Library/Frameworks/ or the argument to
+# --enable-framework. If --enable-framework has been specified then we have
+# automatically set prefix to the location deep down in the framework, so we
+# only have to cater for the structural bits of the framework.
+
+frameworkinstall: install frameworkinfrastructureinstall
+FRAMEWORKFINALDEST=$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)
+frameworkinfrastructureinstall:	$(LDLIBRARY)
+	@if test -z "$(PYTHONFRAMEWORKDIR)"; then \
+		echo Not configured with --enable-framework; \
+		exit; \
+	else true; \
+	fi
+	@for i in $(FRAMEWORKFINALDEST)/Resources/English.lproj $(FRAMEWORKFINALDEST)/lib; do\
+		if test ! -d $$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $$i; \
+		else	true; \
+		fi; \
+	done
+	$(LN) -sf $(FRAMEWORKFINALDEST)/Headers $(INCLUDEPY)
+	$(INSTALL_DATA) $(RESSRCDIR)/Info.plist $(FRAMEWORKFINALDEST)/Resources/Info.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/version.plist $(FRAMEWORKFINALDEST)/Resources/version.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/English.lproj/InfoPlist.strings \
+		$(FRAMEWORKFINALDEST)/Resources/English.lproj/InfoPlist.strings
+	$(LN) -fs $(VERSION) $(PYTHONFRAMEWORKINSTALLDIR)/Versions/Current
+	$(LN) -fs Versions/Current/Python $(PYTHONFRAMEWORKINSTALLDIR)/Python
+	$(LN) -fs Versions/Current/Headers $(PYTHONFRAMEWORKINSTALLDIR)/Headers
+	$(LN) -fs Versions/Current/Resources $(PYTHONFRAMEWORKINSTALLDIR)/Resources
+	$(INSTALL_DATA) $(LDLIBRARY) $(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY)
+		
 # Build the toplevel Makefile
 Makefile.pre: Makefile.pre.in config.status
 	CONFIG_FILES=Makefile.pre CONFIG_HEADERS= $(SHELL) config.status
diff --git a/configure.in b/configure.in
index 14d11e8de1..396728b736 100644
--- a/configure.in
+++ b/configure.in
@@ -12,40 +12,36 @@ VERSION=2.2
 AC_SUBST(CONFIG_ARGS)
 CONFIG_ARGS="$ac_configure_args"
 
-# NEXTSTEP|MacOSX|Darwin stuff
-if test -f /usr/lib/NextStep/software_version -o -f /System/Library/CoreServices/software_version ; then
-
-	AC_MSG_CHECKING(for --with-next-archs)
-	AC_ARG_WITH(next-archs,
-	 [  --with-next-archs='arch1 arch2 ..'   build MAB binary], [
-		if test -n "$withval"; then
-		    ac_arch_flags=`/usr/lib/arch_tool -archify_list $withval`
-		    # GCC does not currently support multi archs on the NeXT
-		    with_gcc=no
-		fi
-		AC_MSG_RESULT($with_next_archs)
-	], [AC_MSG_RESULT(none: using `arch`)])
-	
-	if test -z "$MACHDEP"
-	then
-	    ac_sys_system=`uname -s`
-	    if test "$ac_sys_system" = "Darwin" ; then
-		ac_sys_release=`uname -r`
-	    else
-		set X `hostinfo | egrep '(NeXT Mach|Kernel Release).*:' | \
-			sed -e 's/://' -e 's/\./_/'` && \
-		ac_sys_system=next && ac_sys_release=$4
-	    fi
-
-	    MACHDEP="$ac_sys_system$ac_sys_release"
-	fi
-fi
-
-AC_ARG_WITH(next-framework,
-[  --with-next-framework           Build (OpenStep|Rhapsody|MacOSX|Darwin) framework],,)
-AC_ARG_WITH(dyld,
-[  --with-dyld                     Use (OpenStep|Rhapsody) dynamic linker],,)
 
+AC_ARG_ENABLE(framework,
+[  --enable-framework[=INSTALLDIR] Build (MacOSX|Darwin) framework],[
+	PYTHONFRAMEWORK=Python
+	PYTHONFRAMEWORKDIR=Python.framework
+	case $enableval in
+	yes) 
+		enableval=/Library/Frameworks
+		PYTHONFRAMEWORKPREFIX=$enableval
+		;;
+	*)
+		PYTHONFRAMEWORKPREFIX=$enableval
+	esac
+	PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR
+	prefix=$PYTHONFRAMEWORKINSTALLDIR/Versions/$VERSION
+	],[
+	PYTHONFRAMEWORK=
+	PYTHONFRAMEWORKDIR=
+	PYTHONFRAMEWORKPREFIX=
+	PYTHONFRAMEWORKINSTALLDIR=
+	enable_framework=
+])
+AC_SUBST(PYTHONFRAMEWORK)
+AC_SUBST(PYTHONFRAMEWORKDIR)
+AC_SUBST(PYTHONFRAMEWORKPREFIX)
+AC_SUBST(PYTHONFRAMEWORKINSTALLDIR)
+
+##AC_ARG_WITH(dyld,
+##[  --with-dyld                     Use (OpenStep|Rhapsody) dynamic linker],,)
+##
 # Set name for machine-dependent library files
 AC_SUBST(MACHDEP)
 AC_MSG_CHECKING(MACHDEP)
@@ -224,14 +220,22 @@ fi
 AC_MSG_RESULT($LIBRARY)
 
 # LDLIBRARY is the name of the library to link against (as opposed to the
-# name of the library into which to insert object files). On systems
-# without shared libraries, LDLIBRARY is the same as LIBRARY (defined in
-# the Makefiles). On Cygwin LDLIBRARY is the import library, DLLLIBRARY is the
-# shared (i.e., DLL) library.
+# name of the library into which to insert object files). BLDLIBRARY is also
+# the library to link against, usually. On Mac OS X frameworks, BLDLIBRARY
+# is blank as the main program is not linked directly against LDLIBRARY.
+# LDLIBRARYDIR is the path to LDLIBRARY, which is made in a subdirectory. On
+# systems without shared libraries, LDLIBRARY is the same as LIBRARY
+# (defined in the Makefiles). On Cygwin LDLIBRARY is the import library,
+# DLLLIBRARY is the shared (i.e., DLL) library.
+# 
 AC_SUBST(LDLIBRARY)
 AC_SUBST(DLLLIBRARY)
+AC_SUBST(BLDLIBRARY)
+AC_SUBST(LDLIBRARYDIR)
 LDLIBRARY="$LIBRARY"
+BLDLIBRARY='$(LDLIBRARY)'
 DLLLIBRARY=''
+LDLIBRARYDIR=''
 
 # LINKCC is the command that links the python executable -- default is $(CC).
 # This is altered for AIX in order to build the export list before 
@@ -254,14 +258,6 @@ AC_MSG_RESULT($LINKCC)
 
 AC_MSG_CHECKING(LDLIBRARY)
 
-# NeXT framework builds require that the 'ar' library be converted into
-# a bundle using libtool.
-if test "$with_next_framework"
-then
-  LDLIBRARY='libpython$(VERSION).dylib'
-  DLLLIBRARY=$LDLIBRARY
-fi  
-
 # DG/UX requires some fancy ld contortions to produce a .so from an .a
 case $MACHDEP in
 dguxR4)
@@ -276,6 +272,21 @@ cygwin*)
       DLLLIBRARY='libpython$(VERSION).dll'
       ;;
 esac
+
+# MacOSX framework builds need more magic. LDLIBRARY is the dynamic library that
+# we build, but we do not want to link against it (we will find it with a -framework
+# option). For this reason there is an extra variable BLDLIBRARY against which Python
+# and the extension modules are linked, BLDLIBRARY. This is normally the same
+# as LDLIBRARY, but empty for MacOSX framework builds.
+if test "$enable_framework"
+then
+  LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+  LDLIBRARYDIR='$(PYTHONFRAMEWORKDIR)'
+  BLDLIBRARY=''
+else
+  BLDLIBRARY='$(LDLIBRARY)'
+fi  
+
 AC_MSG_RESULT($LDLIBRARY)
 
 AC_PROG_RANLIB
@@ -540,53 +551,67 @@ if test "$have_pthread_t" = yes ; then
 fi
 CC="$ac_save_cc"
 
-# Minor variations in building a framework between NextStep versions 4 and 5
+AC_MSG_CHECKING(for --enable-toolbox-glue)
+AC_ARG_ENABLE(toolbox-glue,
+[  --enable-toolbox-glue            disable/enable MacOSX glue code for extensions])
+
+if test -z "$enable_toolbox_glue"
+then 
+	case $ac_sys_system/$ac_sys_release in
+	Darwin/*)
+		enable_toolbox_glue="yes";;
+	*)
+		enable_toolbox_glue="no";;
+	esac
+fi
+case "$enable_toolbox_glue" in
+yes)
+	extra_frameworks="-framework Carbon -framework Foundation"
+	extra_machdep_objs="Python/mactoolboxglue.o"
+	AC_DEFINE(USE_TOOLBOX_OBJECT_GLUE)
+	;;
+*)
+	extra_frameworks=""
+	extra_machdep_objs=""
+	;;
+esac
+AC_MSG_RESULT($enable_toolbox_glue)
+
 AC_SUBST(LIBTOOL_CRUFT)
 case $ac_sys_system/$ac_sys_release in
   Darwin/*)
     ns_undef_sym='_environ'
-    LIBTOOL_CRUFT="-framework Foundation -framework Carbon -lcc_dynamic -arch_only ppc -U $ns_undef_sym" ;;
-  next/4*)
-    ns_undef_sym='__environ'
-    LIBTOOL_CRUFT="-U $ns_undef_sym" ;;
-  next/5*)
-    ns_undef_sym='_environ'
-    LIBTOOL_CRUFT="-lcc_dynamic -U $ns_undef_sym" ;;
+    LIBTOOL_CRUFT="-lcc_dynamic -arch_only ppc -U $ns_undef_sym"
+   	LIBTOOL_CRUFT="$LIBTOOL_CRUFT $extra_frameworks"
+    LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Python'
+    LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';;
 esac
 
-AC_MSG_CHECKING(for --with-next-framework)
-if test "$with_next_framework"
+AC_MSG_CHECKING(for --enable-framework)
+if test "$enable_framework"
 then
 	OPT="$OPT -fno-common -dynamic"
 	# -U __environ is needed since bundles don't have access
 	# to crt0 when built but will always be linked against it
-	LDFLAGS="$LDFLAGS -Wl,-U,$ns_undef_sym"
+	# -F. is needed to allow linking to the framework while 
+	# in the build location.
+	
+	LDFLAGS="$LDFLAGS -Wl,-F. -Wl,-U,$ns_undef_sym"
 	AC_DEFINE(WITH_NEXT_FRAMEWORK)
 	AC_MSG_RESULT(yes)
 else
 	AC_MSG_RESULT(no)
 fi
 
-AC_MSG_CHECKING(for --with-dyld)
+AC_MSG_CHECKING(for dyld)
 case $ac_sys_system/$ac_sys_release in
   Darwin/*)
   	AC_DEFINE(WITH_DYLD)
   	AC_MSG_RESULT(always on for Darwin)
   	;;
   *)
-	if test "$with_next_framework" -o "$with_dyld"
-	then
-		if test "$with_dyld"
-		then
-			AC_MSG_RESULT(yes)
-		else
-			AC_MSG_RESULT(required for framework build)
-		fi
-		AC_DEFINE(WITH_DYLD)
-		ns_dyld='set'
-	else
-		AC_MSG_RESULT(no)
-	fi ;;
+	AC_MSG_RESULT(no)
+	;;
 esac
 
 # Set info about shared libraries.
@@ -634,18 +659,14 @@ then
 	hp*|HP*) LDSHARED="ld -b";;
 	OSF*) LDSHARED="ld -shared -expect_unresolved \"*\"";;
 	DYNIX/ptx*) LDSHARED="ld -G";;
-        Darwin/*) 
-		LDSHARED='$(CC) $(LDFLAGS) -bundle -undefined suppress'
-		if test "$with_next_framework" ; then
-		    LDSHARED="$LDSHARED \$(LDLIBRARY)"
-		fi ;;
-        next/*) 
-		if test "$ns_dyld"
-		then LDSHARED='$(CC) $(LDFLAGS) -bundle -undefined suppress'
-		else LDSHARED='$(CC) $(CFLAGS) -nostdlib -r';
-		fi
-	if test "$with_next_framework" ; then
-		    LDSHARED="$LDSHARED \$(LDLIBRARY)"
+	Darwin/*)
+		LDSHARED='$(CC) $(LDFLAGS) -bundle'
+		if test "$enable_framework" ; then
+			# Link against the framework. All externals should be defined.
+			LDSHARED="$LDSHARED "'-framework $(PYTHONFRAMEWORK)'
+		else
+			# No framework. Ignore undefined symbols, assuming they come from Python
+			LDSHARED="$LDSHARED -undefined suppress"
 		fi ;;
 	Linux*) LDSHARED="gcc -shared";;
 	dgux*) LDSHARED="ld -G";;
@@ -722,13 +743,20 @@ then
 	BSD/OS/4*) LINKFORSHARED="-Xlinker -export-dynamic";;
 	Linux*) LINKFORSHARED="-Xlinker -export-dynamic";;
 	# -u libsys_s pulls in all symbols in libsys
-	next/2*|next/3*) LINKFORSHARED="-u libsys_s";;
-	# -u __dummy makes the linker aware of the objc runtime
-	# in System.framework; otherwise, __objcInit (referenced in
-	# crt1.o) gets erroneously defined as common, which breaks dynamic
-	# loading of any modules which reference it in System.framework
-	next/4*|next/5*) LINKFORSHARED="-u __dummy -framework System" ;;
-	Darwin/*) LINKFORSHARED="-u __dummy -u _PyMac_Error -framework System -framework Foundation -framework Carbon" ;;
+	Darwin/*) 
+		# -u __dummy makes the linker aware of the objc runtime
+		# in System.framework; otherwise, __objcInit (referenced in
+		# crt1.o) gets erroneously defined as common, which breaks dynamic
+		# loading of any modules which reference it in System.framework.
+		# -u _PyMac_Error is needed to pull in the mac toolbox glue, which is
+		# not used by the core itself but which needs to be in the core so
+		# that dynamically loaded extension modules have access to it.
+		LINKFORSHARED="-u __dummy -u _PyMac_Error -framework System"
+		if test "$enable_framework"
+		then
+			LINKFORSHARED="$LINKFORSHARED -framework Python"
+		fi
+		LINKFORSHARED="$LINKFORSHARED $extra_frameworks";;
 	UnixWare*) LINKFORSHARED="-Wl,-Bexport";;
 	SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";;
 	ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";;
@@ -1174,7 +1202,7 @@ then
 	AIX*) DYNLOADFILE="dynload_aix.o";;
 	BeOS*) DYNLOADFILE="dynload_beos.o";;
 	hp*|HP*) DYNLOADFILE="dynload_hpux.o";;
-	Darwin/*|next/*) DYNLOADFILE="dynload_next.o";;
+	Darwin/*) DYNLOADFILE="dynload_next.o";;
 	*)
 	# use dynload_shlib.c and dlopen() if we have it; otherwise stub
 	# out any dynamic loading
@@ -1197,15 +1225,11 @@ AC_SUBST(MACHDEP_OBJS)
 AC_MSG_CHECKING(MACHDEP_OBJS)
 if test -z "$MACHDEP_OBJS"
 then
-	case $ac_sys_system/$ac_sys_release in
-	Darwin/*)
-		MACHDEP_OBJS="Python/mactoolboxglue.o"
-		AC_DEFINE(USE_TOOLBOX_OBJECT_GLUE)
-		;;
-	*) MACHDEP_OBJS="";;
-	esac
+	MACHDEP_OBJS=$extra_machdep_objs
+else
+	MACHDEP_OBJS="$MACHDEP_OBJS $extra_machdep_objs"
 fi
-AC_MSG_RESULT($DYNLOADFILE)
+AC_MSG_RESULT(MACHDEP_OBJS)
 
 # checks for library functions
 AC_CHECK_FUNCS(alarm chown clock confstr ctermid ctermid_r execv \
@@ -1563,7 +1587,6 @@ fi],
 AC_SUBST(LIBM)
 case $ac_sys_system in
 Darwin) ;;
-next) ;;
 BeOS) ;;
 *) LIBM=-lm
 esac
-- 
2.40.0