summaryrefslogtreecommitdiffstats
path: root/Lib/distutils
diff options
context:
space:
mode:
authorRonald Oussoren <ronaldoussoren@mac.com>2006-05-23 12:01:11 (GMT)
committerRonald Oussoren <ronaldoussoren@mac.com>2006-05-23 12:01:11 (GMT)
commitb02daf794b9be0041dc39207f18211ec8321ec77 (patch)
tree421b1ca9eec422f78d0bd54b9066069eca2ca797 /Lib/distutils
parent58f8eba372be06d20541b5e58244e92071e7417e (diff)
downloadcpython-b02daf794b9be0041dc39207f18211ec8321ec77.zip
cpython-b02daf794b9be0041dc39207f18211ec8321ec77.tar.gz
cpython-b02daf794b9be0041dc39207f18211ec8321ec77.tar.bz2
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.
Diffstat (limited to 'Lib/distutils')
-rw-r--r--Lib/distutils/sysconfig.py15
-rw-r--r--Lib/distutils/unixccompiler.py64
-rw-r--r--Lib/distutils/util.py48
3 files changed, 125 insertions, 2 deletions
diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
index 2a18d2b..2ba3c4d 100644
--- a/Lib/distutils/sysconfig.py
+++ b/Lib/distutils/sysconfig.py
@@ -500,6 +500,21 @@ def get_config_vars(*args):
_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:
diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py
index 56998c3..e612cfc 100644
--- a/Lib/distutils/unixccompiler.py
+++ b/Lib/distutils/unixccompiler.py
@@ -42,6 +42,48 @@ from distutils import log
# 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 @@ class UnixCCompiler(CCompiler):
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 @@ class UnixCCompiler(CCompiler):
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
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
index 061092b..623c41e 100644
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -67,6 +67,54 @@ def get_platform ():
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)