[Python-checkins] r46104 - python/trunk/Lib/distutils/sysconfig.py python/trunk/Lib/distutils/unixccompiler.py python/trunk/Lib/distutils/util.py

ronald.oussoren python-checkins at python.org
Tue May 23 14:01:12 CEST 2006


Author: ronald.oussoren
Date: Tue May 23 14:01:11 2006
New Revision: 46104

Modified:
   python/trunk/Lib/distutils/sysconfig.py
   python/trunk/Lib/distutils/unixccompiler.py
   python/trunk/Lib/distutils/util.py
Log:
Patch #1488098. 

This patchs makes it possible to create a universal build on OSX 10.4 and use 
the result to build extensions on 10.3. It also makes it possible to override
the '-arch' and '-isysroot' compiler arguments for specific extensions.


Modified: python/trunk/Lib/distutils/sysconfig.py
==============================================================================
--- python/trunk/Lib/distutils/sysconfig.py	(original)
+++ python/trunk/Lib/distutils/sysconfig.py	Tue May 23 14:01:11 2006
@@ -500,6 +500,21 @@
         _config_vars['prefix'] = PREFIX
         _config_vars['exec_prefix'] = EXEC_PREFIX
 
+        if sys.platform == 'darwin':
+            kernel_version = os.uname()[2] # Kernel version (8.4.3)
+            major_version = int(kernel_version.split('.')[0])
+
+            if major_version < 8:
+                # On Mac OS X before 10.4, check if -arch and -isysroot
+                # are in CFLAGS or LDFLAGS and remove them if they are.
+                # This is needed when building extensions on a 10.3 system
+                # using a universal build of python.
+                for key in ('LDFLAGS', 'BASECFLAGS'):
+                    flags = _config_vars[key]
+                    flags = re.sub('-arch\s+\w+\s', ' ', flags)
+                    flags = re.sub('-isysroot [^ \t]* ', ' ', flags)
+                    _config_vars[key] = flags
+
     if args:
         vals = []
         for name in args:

Modified: python/trunk/Lib/distutils/unixccompiler.py
==============================================================================
--- python/trunk/Lib/distutils/unixccompiler.py	(original)
+++ python/trunk/Lib/distutils/unixccompiler.py	Tue May 23 14:01:11 2006
@@ -42,6 +42,48 @@
 #     should just happily stuff them into the preprocessor/compiler/linker
 #     options and carry on.
 
+def _darwin_compiler_fixup(compiler_so, cc_args):
+    """
+    This function will strip '-isysroot PATH' and '-arch ARCH' from the
+    compile flags if the user has specified one them in extra_compile_flags.
+
+    This is needed because '-arch ARCH' adds another architecture to the
+    build, without a way to remove an architecture. Furthermore GCC will
+    barf if multiple '-isysroot' arguments are present.
+    """
+    stripArch = stripSysroot = 0
+
+    compiler_so = list(compiler_so)
+    kernel_version = os.uname()[2] # 8.4.3
+    major_version = int(kernel_version.split('.')[0])
+
+    if major_version < 8:
+        # OSX before 10.4.0, these don't support -arch and -isysroot at
+        # all.
+        stripArch = stripSysroot = True
+    else:
+        stripArch = '-arch' in cc_args
+        stripSysroot = '-isysroot' in cc_args
+
+    if stripArch:
+        while 1:
+            try:
+                index = compiler_so.index('-arch')
+                # Strip this argument and the next one:
+                del compiler_so[index:index+2]
+            except ValueError:
+                break
+
+    if stripSysroot:
+        try:
+            index = compiler_so.index('-isysroot')
+            # Strip this argument and the next one:
+            del compiler_so[index:index+1]
+        except ValueError:
+            pass
+
+    return compiler_so
+
 class UnixCCompiler(CCompiler):
 
     compiler_type = 'unix'
@@ -108,8 +150,11 @@
                 raise CompileError, msg
 
     def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+        compiler_so = self.compiler_so
+        if sys.platform == 'darwin':
+            compiler_so = _darwin_compiler_fixup(compiler_so, cc_args + extra_postargs)
         try:
-            self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
+            self.spawn(compiler_so + cc_args + [src, '-o', obj] +
                        extra_postargs)
         except DistutilsExecError, msg:
             raise CompileError, msg
@@ -172,7 +217,22 @@
                 else:
                     linker = self.linker_so[:]
                 if target_lang == "c++" and self.compiler_cxx:
-                    linker[0] = self.compiler_cxx[0]
+                    # skip over environment variable settings if /usr/bin/env
+                    # is used to set up the linker's environment.
+                    # This is needed on OSX. Note: this assumes that the
+                    # normal and C++ compiler have the same environment 
+                    # settings.
+                    i = 0
+                    if os.path.basename(linker[0]) == "env":
+                        i = 1
+                        while '=' in linker[i]:
+                            i = i + 1
+
+                    linker[i] = self.compiler_cxx[i]
+
+                if sys.platform == 'darwin':
+                    linker = _darwin_compiler_fixup(linker, ld_args)
+
                 self.spawn(linker + ld_args)
             except DistutilsExecError, msg:
                 raise LinkError, msg

Modified: python/trunk/Lib/distutils/util.py
==============================================================================
--- python/trunk/Lib/distutils/util.py	(original)
+++ python/trunk/Lib/distutils/util.py	Tue May 23 14:01:11 2006
@@ -67,6 +67,54 @@
         m = rel_re.match(release)
         if m:
             release = m.group()
+    elif osname[:6] == "darwin":
+        #
+        # For our purposes, we'll assume that the system version from 
+        # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set 
+        # to. This makes the compatibility story a bit more sane because the
+        # machine is going to compile and link as if it were 
+        # MACOSX_DEPLOYMENT_TARGET.
+        from distutils.sysconfig import get_config_vars
+        cfgvars = get_config_vars()
+
+        macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET')
+        if not macver:
+            macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET')
+
+        if not macver:
+            # Get the system version. Reading this plist is a documented
+            # way to get the system version (see the documentation for
+            # the Gestalt Manager)
+            try:
+                f = open('/System/Library/CoreServices/SystemVersion.plist')
+            except IOError:
+                # We're on a plain darwin box, fall back to the default
+                # behaviour.
+                pass
+            else:
+                m = re.search(
+                        r'<key>ProductUserVisibleVersion</key>\s*' +
+                        r'<string>(.*?)</string>', f.read())
+                f.close()
+                if m is not None:
+                     macver = '.'.join(m.group(1).split('.')[:2])
+                # else: fall back to the default behaviour
+
+        if macver:
+            from distutils.sysconfig import get_config_vars
+            release = macver
+            osname = "macosx"
+
+
+            if (release + '.') < '10.4.' and \
+                    get_config_vars().get('UNIVERSALSDK', '').strip():
+                # The universal build will build fat binaries, but not on
+                # systems before 10.4
+                machine = 'fat'
+
+            elif machine in ('PowerPC', 'Power_Macintosh'):
+                # Pick a sane name for the PPC architecture.
+                machine = 'ppc'
 
     return "%s-%s-%s" % (osname, release, machine)
 


More information about the Python-checkins mailing list