Index: Lib/distutils/sysconfig.py =================================================================== --- Lib/distutils/sysconfig.py (revision 45968) +++ Lib/distutils/sysconfig.py (working copy) @@ -500,6 +500,20 @@ _config_vars['prefix'] = PREFIX _config_vars['exec_prefix'] = EXEC_PREFIX + if sys.platform == 'darwin': + kern = int(os.uname()[2].split('.')[0]) + + if kern < 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: Index: Lib/distutils/util.py =================================================================== --- Lib/distutils/util.py (revision 45968) +++ Lib/distutils/util.py (working copy) @@ -68,6 +68,59 @@ 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'ProductUserVisibleVersion\s*' + + r'(.*?)', 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' + + + pass return "%s-%s-%s" % (osname, release, machine) # get_platform () Index: Lib/distutils/unixccompiler.py =================================================================== --- Lib/distutils/unixccompiler.py (revision 45968) +++ Lib/distutils/unixccompiler.py (working copy) @@ -42,6 +42,49 @@ # 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 = int(os.uname()[2].split('.')[0]) + if kernel < 8: + # OSX before 10.4.0, these don't support -arch and -isysroot at + # all. + stripArch = stripSysroot = 1 + else: + if '-arch' in cc_args: + stripArch = 1 + + if '-isysroot' in cc_args: + stripSysroot = 1 + + if stripArch: + while 1: + try: + idx = compiler_so.index('-arch') + # Strip this argument and the next one: + del compiler_so[idx:idx+2] + except ValueError: + break + + if stripSysroot: + try: + idx = compiler_so.index('-isysroot') + # Strip this argument and the next one: + del compiler_so[idx:idx+1] + except ValueError: + pass + + return compiler_so + class UnixCCompiler(CCompiler): compiler_type = 'unix' @@ -108,8 +151,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 +218,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