From fcaf910a1fe9739afcf3be41ac2db31e8286c40f Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Wed, 16 Jul 2008 02:17:56 +0000 Subject: [PATCH] Merged revisions 63955 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r63955 | ronald.oussoren | 2008-06-05 14:58:24 +0200 (Thu, 05 Jun 2008) | 20 lines MacOS X: Enable 4-way universal builds This patch adds a new configure argument on OSX: --with-universal-archs=[32-bit|64-bit|all] When used with the --enable-universalsdk option this controls which CPU architectures are includes in the framework. The default is 32-bit, meaning i386 and ppc. The most useful alternative is 'all', which includes all 4 CPU architectures supported by MacOS X (i386, ppc, x86_64 and ppc64). This includes limited support for the Carbon bindings in 64-bit mode as well, limited because (a) I haven't done extensive testing and (b) a large portion of the Carbon API's aren't available in 64-bit mode anyway. I've also duplicated a feature of Apple's build of python: setting the environment variable 'ARCHFLAGS' controls the '-arch' flags used for building extensions using distutils. ........ --- Include/Python.h | 1 + Include/pymacconfig.h | 59 ++++++++++++++ Lib/distutils/sysconfig.py | 20 +++++ Lib/distutils/unixccompiler.py | 8 +- Lib/distutils/util.py | 11 ++- Lib/test/test_macos.py | 43 ++++++++++ Mac/IDLE/idlemain.py | 5 +- Mac/Makefile.in | 60 +++++++++++++- Makefile.pre.in | 13 ++- Modules/_ctypes/cfield.c | 1 + Modules/_ctypes/libffi_osx/x86/x86-darwin.S | 3 +- configure.in | 87 +++++++++++++++------ pyconfig.h.in | 23 ++---- setup.py | 38 ++++++++- 14 files changed, 321 insertions(+), 51 deletions(-) create mode 100644 Include/pymacconfig.h create mode 100644 Lib/test/test_macos.py diff --git a/Include/Python.h b/Include/Python.h index 61f886521b6..76b950321dc 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -6,6 +6,7 @@ #include "patchlevel.h" #include "pyconfig.h" +#include "pymacconfig.h" #include diff --git a/Include/pymacconfig.h b/Include/pymacconfig.h new file mode 100644 index 00000000000..e864e72eb25 --- /dev/null +++ b/Include/pymacconfig.h @@ -0,0 +1,59 @@ +#ifndef PYMACCONFIG_H +#define PYMACCONFIG_H + /* + * This file moves some of the autoconf magic to compile-time + * when building on MacOSX. This is needed for building 4-way + * universal binaries and for 64-bit universal binaries because + * the values redefined below aren't configure-time constant but + * only compile-time constant in these scenarios. + */ + +#if defined(__APPLE__) + +# undef SIZEOF_LONG +# undef SIZEOF_PTHREAD_T +# undef SIZEOF_SIZE_T +# undef SIZEOF_TIME_T +# undef SIZEOF_VOID_P + +# undef VA_LIST_IS_ARRAY +# if defined(__LP64__) && defined(__x86_64__) +# define VA_LIST_IS_ARRAY 1 +# endif + +# undef HAVE_LARGEFILE_SUPPORT +# ifndef __LP64__ +# define HAVE_LARGEFILE_SUPPORT 1 +# endif + +# undef SIZEOF_LONG +# ifdef __LP64__ +# define SIZEOF_LONG 8 +# define SIZEOF_PTHREAD_T 8 +# define SIZEOF_SIZE_T 8 +# define SIZEOF_TIME_T 8 +# define SIZEOF_VOID_P 8 +# else +# define SIZEOF_LONG 4 +# define SIZEOF_PTHREAD_T 4 +# define SIZEOF_SIZE_T 4 +# define SIZEOF_TIME_T 4 +# define SIZEOF_VOID_P 4 +# endif + +# if defined(__LP64__) + /* MacOSX 10.4 (the first release to suppport 64-bit code + * at all) only supports 64-bit in the UNIX layer. + * Therefore surpress the toolbox-glue in 64-bit mode. + */ + + /* In 64-bit mode setpgrp always has no argments, in 32-bit + * mode that depends on the compilation environment + */ +# undef SETPGRP_HAVE_ARG + +# endif + +#endif /* defined(_APPLE__) */ + +#endif /* PYMACCONFIG_H */ diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index d2b2c9a347c..3a120dd5845 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -516,6 +516,26 @@ def get_config_vars(*args): flags = re.sub('-isysroot [^ \t]*', ' ', flags) _config_vars[key] = flags + else: + + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _config_vars[key] + flags = re.sub('-arch\s+\w+\s', ' ', flags) + flags = flags + ' ' + arch + _config_vars[key] = flags + if args: vals = [] for name in args: diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py index 25a042d075d..87ce9217fd5 100644 --- a/Lib/distutils/unixccompiler.py +++ b/Lib/distutils/unixccompiler.py @@ -63,7 +63,7 @@ def _darwin_compiler_fixup(compiler_so, cc_args): stripArch = '-arch' in cc_args stripSysroot = '-isysroot' in cc_args - if stripArch: + if stripArch or 'ARCHFLAGS' in os.environ: while True: try: index = compiler_so.index('-arch') @@ -72,6 +72,12 @@ def _darwin_compiler_fixup(compiler_so, cc_args): except ValueError: break + if 'ARCHFLAGS' in os.environ and not stripArch: + # User specified different -arch flags in the environ, + # see also distutils.sysconfig + compiler_so = compiler_so + ' ' + os.environ['ARCHFLAGS'] + + if stripSysroot: try: index = compiler_so.index('-isysroot') diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py index 72039a7e6a8..76798b95062 100644 --- a/Lib/distutils/util.py +++ b/Lib/distutils/util.py @@ -124,12 +124,19 @@ def get_platform (): osname = "macosx" - if (release + '.') < '10.4.' and \ - get_config_vars().get('UNIVERSALSDK', '').strip(): + if (release + '.') >= '10.4.' and \ + '-arch' in get_config_vars().get('CFLAGS', '').strip(): # The universal build will build fat binaries, but not on # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + machine = 'fat' + if '-arch x86_64' in get_config_vars().get('CFLAGS'): + machine = 'universal' + elif machine in ('PowerPC', 'Power_Macintosh'): # Pick a sane name for the PPC architecture. machine = 'ppc' diff --git a/Lib/test/test_macos.py b/Lib/test/test_macos.py new file mode 100644 index 00000000000..e65b1748244 --- /dev/null +++ b/Lib/test/test_macos.py @@ -0,0 +1,43 @@ +import unittest +import MacOS +import Carbon.File +from test import test_support +import os + +TESTFN2 = test_support.TESTFN + '2' + +class TestMacOS(unittest.TestCase): + + def testOpenRF(self): + try: + fp = open(test_support.TESTFN, 'w') + fp.write('hello world\n') + fp.close() + + rfp = MacOS.openrf(test_support.TESTFN, '*wb') + rfp.write('goodbye world\n') + rfp.close() + + + fp = open(test_support.TESTFN, 'r') + data = fp.read() + fp.close() + self.assertEquals(data, 'hello world\n') + + rfp = MacOS.openrf(test_support.TESTFN, '*rb') + data = rfp.read(100) + data2 = rfp.read(100) + rfp.close() + self.assertEquals(data, 'goodbye world\n') + self.assertEquals(data2, '') + + + finally: + os.unlink(test_support.TESTFN) + +def test_main(): + test_support.run_unittest(TestMacOS) + + +if __name__ == '__main__': + test_main() diff --git a/Mac/IDLE/idlemain.py b/Mac/IDLE/idlemain.py index aa75d4cb15e..9b5273899f6 100644 --- a/Mac/IDLE/idlemain.py +++ b/Mac/IDLE/idlemain.py @@ -13,7 +13,10 @@ # Make sure sys.executable points to the python interpreter inside the # framework, instead of at the helper executable inside the application # bundle (the latter works, but doesn't allow access to the window server) -sys.executable = os.path.join(sys.prefix, 'bin', 'python') +if sys.executable.endswith('-32'): + sys.executable = os.path.join(sys.prefix, 'bin', 'python-32') +else: + sys.executable = os.path.join(sys.prefix, 'bin', 'python') # Look for the -psn argument that the launcher adds and remove it, it will # only confuse the IDLE startup code. diff --git a/Mac/Makefile.in b/Mac/Makefile.in index 8cabb281c8e..d12adccbdb1 100644 --- a/Mac/Makefile.in +++ b/Mac/Makefile.in @@ -48,12 +48,42 @@ compileall=$(srcdir)/../Lib/compileall.py installapps: install_PythonLauncher install_IDLE checkapplepython install_pythonw \ install_versionedtools +installapps4way: install_Python4way install_BuildApplet install_PythonLauncher install_IDLE install_pythonw4way install_versionedtools + + install_pythonw: pythonw $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)" $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/python$(VERSION)" ln -sf python$(VERSION) "$(DESTDIR)$(prefix)/bin/python" ln -sf pythonw$(VERSION) "$(DESTDIR)$(prefix)/bin/pythonw" + +# Install 3 variants of python/pythonw: +# - 32-bit (i386 and ppc) +# - 64-bit (x86_64 and ppc64) +# - all (all four architectures) +# - Make 'python' and 'pythonw' aliases for the 32-bit variant +install_pythonw4way: pythonw-32 pythonw-64 pythonw + $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-64 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-64" + $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-64 "$(DESTDIR)$(prefix)/bin/python$(VERSION)-64" + ln -sf python$(VERSION)-64 "$(DESTDIR)$(prefix)/bin/python-64" + ln -sf pythonw$(VERSION)-64 "$(DESTDIR)$(prefix)/bin/pythonw-64" + + $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-32 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-32" + $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-32 "$(DESTDIR)$(prefix)/bin/python$(VERSION)-32" + ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python-32" + ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw-32" + + $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-all" + $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/python$(VERSION)-all" + ln -sf python$(VERSION)-all "$(DESTDIR)$(prefix)/bin/python-all" + ln -sf pythonw$(VERSION)-all "$(DESTDIR)$(prefix)/bin/pythonw-all" + + ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)" + ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python$(VERSION)" + ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw" + ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python" + # # Install unix tools in /usr/local/bin. These are just aliases for the # actual installation inside the framework. @@ -64,11 +94,16 @@ installunixtools: fi for fn in python pythonw idle pydoc python-config smtpd.py \ python$(VERSION) pythonw$(VERSION) idle$(VERSION) \ - pydoc$(VERSION) python-config$(VERSION) smtpd$(VERSION).py ;\ + pydoc$(VERSION) python$(VERSION)-config smtpd$(VERSION).py ;\ do \ ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\ done + +# TODO: install symlinks for -32, -64 and -all as well +installunixtools4way: installunixtools + + # # Like installunixtools, but only install links to the versioned binaries. # @@ -77,18 +112,20 @@ altinstallunixtools: $(INSTALL) -d -m $(DIRMODE) "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin" ;\ fi for fn in python$(VERSION) pythonw$(VERSION) idle$(VERSION) \ - pydoc$(VERSION) python-config$(VERSION) smtpd$(VERSION).py ;\ + pydoc$(VERSION) python$(VERSION)-config) smtpd$(VERSION).py ;\ do \ ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\ done +# TODO: -32, -64 and -all variants +altinstallunixtools4way: altinstallunixtools # By default most tools are installed without a version in their basename, to # make it easier to install (and use) several python versions side-by-side move # the tools to a version-specific name and add the non-versioned name as an # alias. install_versionedtools: - for fn in idle pydoc python-config ;\ + for fn in idle pydoc ;\ do \ if [ -h "$(DESTDIR)$(prefix)/bin/$${fn}" ]; then \ continue ;\ @@ -96,6 +133,10 @@ install_versionedtools: mv "$(DESTDIR)$(prefix)/bin/$${fn}" "$(DESTDIR)$(prefix)/bin/$${fn}$(VERSION)" ;\ ln -sf "$${fn}$(VERSION)" "$(DESTDIR)$(prefix)/bin/$${fn}" ;\ done + if [ ! -h "$(DESTDIR)$(prefix)/bin/python-config" ]; then \ + mv "$(DESTDIR)$(prefix)/bin/python-config" "$(DESTDIR)$(prefix)/bin/python$(VERSION)-config" ;\ + ln -sf "python$(VERSION)-config" "$(DESTDIR)$(prefix)/bin/python-config" ; \ + fi if [ ! -h "$(DESTDIR)$(prefix)/bin/smtpd.py" ]; then \ mv "$(DESTDIR)$(prefix)/bin/smtpd.py" "$(DESTDIR)$(prefix)/bin/smtpd$(VERSION).py" ;\ ln -sf "smtpd$(VERSION).py" "$(DESTDIR)$(prefix)/bin/smtpd.py" ;\ @@ -106,6 +147,13 @@ pythonw: $(srcdir)/Tools/pythonw.c Makefile $(CC) $(LDFLAGS) -o $@ $(srcdir)/Tools/pythonw.c \ -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"' +pythonw-32: $(srcdir)/Tools/pythonw.c Makefile + $(CC) $(LDFLAGS) -o $@ -arch i386 -arch ppc $(srcdir)/Tools/pythonw.c \ + -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-32"' + +pythonw-64: $(srcdir)/Tools/pythonw.c Makefile + $(CC) $(LDFLAGS) -o $@ -arch x86_64 -arch ppc64 $(srcdir)/Tools/pythonw.c \ + -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-64"' install_PythonLauncher: cd PythonLauncher && make install DESTDIR=$(DESTDIR) @@ -158,6 +206,12 @@ install_Python: done $(INSTALL_PROGRAM) $(STRIPFLAG) $(BUILDPYTHON) "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" +install_Python4way: install_Python + lipo -extract i386 -extract ppc7400 -output "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-32" "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" + lipo -extract x86_64 -extract ppc64 -output "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-64" "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" + + + install_IDLE: test -d "$(DESTDIR)$(PYTHONAPPSDIR)" || mkdir -p "$(DESTDIR)$(PYTHONAPPSDIR)" -test -d "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" && rm -r "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" diff --git a/Makefile.pre.in b/Makefile.pre.in index a6a49509a28..8d887440fdf 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -428,7 +428,7 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \ $(RESSRCDIR)/Info.plist $(INSTALL) -d -m $(DIRMODE) $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION) if test "${UNIVERSALSDK}"; then \ - $(CC) -o $(LDLIBRARY) -arch i386 -arch ppc -dynamiclib \ + $(CC) -o $(LDLIBRARY) @UNIVERSAL_ARCH_FLAGS@ -dynamiclib \ -isysroot "${UNIVERSALSDK}" \ -all_load $(LIBRARY) -Wl,-single_module \ -install_name $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \ @@ -1031,13 +1031,22 @@ frameworkinstallmaclib: frameworkinstallapps: cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)" +frameworkinstallapps4way: + cd Mac && $(MAKE) installapps4way DESTDIR="$(DESTDIR)" + # This install the unix python and pythonw tools in /usr/local/bin frameworkinstallunixtools: cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)" +frameworkinstallunixtools4way: + cd Mac && $(MAKE) installunixtools4way DESTDIR="$(DESTDIR)" + frameworkaltinstallunixtools: cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)" +frameworkaltinstallunixtools4way: + cd Mac && $(MAKE) altinstallunixtools4way DESTDIR="$(DESTDIR)" + # This installs the Demos and Tools into the applications directory. # It is not part of a normal frameworkinstall frameworkinstallextras: @@ -1182,7 +1191,7 @@ funny: # Perform some verification checks on any modified files. check: - ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py # Dependencies diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 6cf56a8dac9..beca0186d2f 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1778,6 +1778,7 @@ ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE }; #ifdef ffi_type_longdouble #undef ffi_type_longdouble #endif + /* This is already defined on OSX */ ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN, FFI_TYPE_LONGDOUBLE }; diff --git a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S b/Modules/_ctypes/libffi_osx/x86/x86-darwin.S index d91bdc084e3..040cec6f9ff 100644 --- a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S +++ b/Modules/_ctypes/libffi_osx/x86/x86-darwin.S @@ -179,7 +179,6 @@ epilogue: movl %ebp,%esp popl %ebp ret -.LFE1: .ffi_call_SYSV_end: #if 0 .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV @@ -220,7 +219,7 @@ epilogue: #else .long .LFB1 /* FDE initial location */ #endif - .long .LFE1-.LFB1 /* FDE address range */ + .long .ffi_call_SYSV_end-.LFB1 /* FDE address range */ #ifdef __PIC__ .byte 0x0 /* .uleb128 0x0; Augmentation size */ #endif diff --git a/configure.in b/configure.in index 1674c40a600..871592aba04 100644 --- a/configure.in +++ b/configure.in @@ -57,6 +57,12 @@ AC_DEFINE(__BSD_VISIBLE, 1, [Define on FreeBSD to activate all library features] # u_int on Irix 5.3. Defining _BSD_TYPES brings it back. AC_DEFINE(_BSD_TYPES, 1, [Define on Irix to enable u_int]) +# The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables +# certain features on Mac OS X, so we need _DARWIN_C_SOURCE to re-enable +# them. +AC_DEFINE(_DARWIN_C_SOURCE, 1, [Define on Darwin to activate all library features]) + + define_xopen_source=yes # Arguments passed to configure. @@ -86,6 +92,20 @@ AC_ARG_ENABLE(universalsdk, ]) AC_SUBST(UNIVERSALSDK) +UNIVERSAL_ARCHS="32-bit" +AC_MSG_CHECKING(for --with-universal-archs) +AC_ARG_WITH(universal-archs, + AC_HELP_STRING(--with-universal-archs=ARCH, select architectures for universal build ("32-bit", "64-bit" or "all")), +[ + AC_MSG_RESULT($withval) + UNIVERSAL_ARCHS="$withval" +], +[ + AC_MSG_RESULT(32-bit) +]) + + + AC_ARG_WITH(framework-name, AC_HELP_STRING(--with-framework-name=FRAMEWORK, specify an alternate name of the framework built with --enable-framework), @@ -127,9 +147,14 @@ AC_ARG_ENABLE(framework, PYTHONFRAMEWORKPREFIX=$enableval PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR FRAMEWORKINSTALLFIRST="frameworkinstallstructure" - FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" - FRAMEWORKALTINSTALLFIRST="${FRAMEWORKINSTALLFIRST} bininstall maninstall" - FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" + FRAMEWORKALTINSTALLFIRST="frameworkinstallstructure bininstall maninstall" + if test "$UNIVERSAL_ARCHS" = "all" + then + FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkinstallunixtools4way" + else + FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" + fi + if test "x${prefix}" = "xNONE" ; then FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" else @@ -159,6 +184,12 @@ AC_ARG_ENABLE(framework, FRAMEWORKUNIXTOOLSPREFIX="${prefix}" fi enable_framework= + + if test "$UNIVERSAL_ARCHS" = "all" + then + FRAMEWORKINSTALLLAST=update4wayuniversal + FRAMEWORKALTINSTALLLAST=update4wayuniversal + fi ]) AC_SUBST(PYTHONFRAMEWORK) AC_SUBST(PYTHONFRAMEWORKIDENTIFIER) @@ -782,6 +813,11 @@ then fi AC_SUBST(BASECFLAGS) + +# The -arch flags for universal builds on OSX +UNIVERSAL_ARCH_FLAGS= +AC_SUBST(UNIVERSAL_ARCH_FLAGS) + # tweak BASECFLAGS based on compiler and platform case $GCC in yes) @@ -820,7 +856,23 @@ yes) # -Wno-long-double, -no-cpp-precomp, and -mno-fused-madd # used to be here, but non-Apple gcc doesn't accept them. if test "${enable_universalsdk}"; then - BASECFLAGS="-arch ppc -arch i386 -isysroot ${UNIVERSALSDK} ${BASECFLAGS}" + UNIVERSAL_ARCH_FLAGS="" + if test "$UNIVERSAL_ARCHS" = "32-bit" ; then + UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386" + + elif test "$UNIVERSAL_ARCHS" = "64-bit" ; then + UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64" + + elif test "$UNIVERSAL_ARCHS" = "all" ; then + UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64" + + else + AC_MSG_ERROR([proper usage is --with-universalarch=32-bit|64-bit|all]) + + fi + + + BASECFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${BASECFLAGS}" fi ;; @@ -1495,6 +1547,12 @@ then if test ${cur_target} '>' 10.2; then cur_target=10.3 fi + if test "${UNIVERSAL_ARCHS}" = "all"; then + # Ensure that the default platform for a 4-way + # universal build is OSX 10.5, that's the first + # OS release where 4-way builds make sense. + cur_target='10.5' + fi CONFIGURE_MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET-${cur_target}} # Make sure that MACOSX_DEPLOYMENT_TARGET is set in the @@ -1505,10 +1563,10 @@ then export MACOSX_DEPLOYMENT_TARGET EXPORT_MACOSX_DEPLOYMENT_TARGET='' - if test ${MACOSX_DEPLOYMENT_TARGET-${cur_target}} '>' 10.2 + if test ${MACOSX_DEPLOYMENT_TARGET} '>' 10.2 then if test "${enable_universalsdk}"; then - LDFLAGS="-arch i386 -arch ppc -isysroot ${UNIVERSALSDK} ${LDFLAGS}" + LDFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${LDFLAGS}" fi LDSHARED='$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup' BLDSHARED="$LDSHARED" @@ -3098,23 +3156,6 @@ AC_MSG_RESULT($PY_UNICODE_TYPE) # check for endianness AC_C_BIGENDIAN -AH_VERBATIM([WORDS_BIGENDIAN], -[ - /* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). - - The block below does compile-time checking for endianness on platforms - that use GCC and therefore allows compiling fat binaries on OSX by using - '-arch ppc -arch i386' as the compile flags. The phrasing was choosen - such that the configure-result is used on systems that don't use GCC. - */ -#ifdef __BIG_ENDIAN__ -#define WORDS_BIGENDIAN 1 -#else -#ifndef __LITTLE_ENDIAN__ -#undef WORDS_BIGENDIAN -#endif -#endif]) # Check whether right shifting a negative integer extends the sign bit # or fills with zeros (like the Cray J90, according to Tim Peters). diff --git a/pyconfig.h.in b/pyconfig.h.in index d5ec2b01666..ee38b4b967e 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -489,6 +489,9 @@ /* Define if you have readline 4.2 */ #undef HAVE_RL_COMPLETION_MATCHES +/* Define when using libedit's readline emulation */ +#undef HAVE_RL_DISPM_VFUNC + /* Define if you have readline 4.0 */ #undef HAVE_RL_PRE_INPUT_HOOK @@ -976,22 +979,9 @@ /* Define to profile with the Pentium timestamp counter */ #undef WITH_TSC - - /* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). - - The block below does compile-time checking for endianness on platforms - that use GCC and therefore allows compiling fat binaries on OSX by using - '-arch ppc -arch i386' as the compile flags. The phrasing was choosen - such that the configure-result is used on systems that don't use GCC. - */ -#ifdef __BIG_ENDIAN__ -#define WORDS_BIGENDIAN 1 -#else -#ifndef __LITTLE_ENDIAN__ +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN -#endif -#endif /* Define to 1 if on AIX 3. System headers sometimes define this. @@ -1006,6 +996,9 @@ /* Define on Irix to enable u_int */ #undef _BSD_TYPES +/* Define on Darwin to activate all library features */ +#undef _DARWIN_C_SOURCE + /* This must be set to 64 on some systems to enable large file support. */ #undef _FILE_OFFSET_BITS diff --git a/setup.py b/setup.py index d73e765abd7..0519bf77bc0 100644 --- a/setup.py +++ b/setup.py @@ -241,6 +241,19 @@ def build_extension(self, ext): 'WARNING: skipping import check for Carbon-based "%s"' % ext.name) return + + if self.get_platform() == 'darwin' and ( + sys.maxint > 2**32 and '-arch' in ext.extra_link_args): + # Don't bother doing an import check when an extension was + # build with an explicit '-arch' flag on OSX. That's currently + # only used to build 32-bit only extensions in a 4-way + # universal build and loading 32-bit code into a 64-bit + # process will fail. + self.announce( + 'WARNING: skipping import check for "%s"' % + ext.name) + return + # Workaround for Cygwin: Cygwin currently has fork issues when many # modules have been imported if self.get_platform() == 'cygwin': @@ -507,10 +520,12 @@ def detect_modules(self): # readline do_readline = self.compiler.find_library_file(lib_dirs, 'readline') - if platform == 'darwin': + if platform == 'darwin': # and os.uname()[2] < '9.': # MacOSX 10.4 has a broken readline. Don't try to build # the readline module unless the user has installed a fixed # readline package + # FIXME: The readline emulation on 10.5 is better, but the + # readline module doesn't compile out of the box. if find_file('readline/rlconf.h', inc_dirs, []) is None: do_readline = False if do_readline: @@ -1242,11 +1257,29 @@ def detect_tkinter_darwin(self, inc_dirs, lib_dirs): include_dirs.append('/usr/X11R6/include') frameworks = ['-framework', 'Tcl', '-framework', 'Tk'] + # All existing framework builds of Tcl/Tk don't support 64-bit + # architectures. + cflags = sysconfig.get_config_vars('CFLAGS')[0] + archs = re.findall('-arch\s+(\w+)', cflags) + if 'x86_64' in archs or 'ppc64' in archs: + try: + archs.remove('x86_64') + except ValueError: + pass + try: + archs.remove('ppc64') + except ValueError: + pass + + for a in archs: + frameworks.append('-arch') + frameworks.append(a) + ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], define_macros=[('WITH_APPINIT', 1)], include_dirs = include_dirs, libraries = [], - extra_compile_args = frameworks, + extra_compile_args = frameworks[2:], extra_link_args = frameworks, ) self.extensions.append(ext) @@ -1377,6 +1410,7 @@ def configure_ctypes_darwin(self, ext): '_ctypes', 'libffi_osx')) sources = [os.path.join(ffi_srcdir, p) for p in ['ffi.c', + 'x86/darwin64.S', 'x86/x86-darwin.S', 'x86/x86-ffi_darwin.c', 'x86/x86-ffi64.c',