mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
58f8eba372
commit
b02daf794b
|
@ -500,6 +500,21 @@ def get_config_vars(*args):
|
||||||
_config_vars['prefix'] = PREFIX
|
_config_vars['prefix'] = PREFIX
|
||||||
_config_vars['exec_prefix'] = EXEC_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:
|
if args:
|
||||||
vals = []
|
vals = []
|
||||||
for name in args:
|
for name in args:
|
||||||
|
|
|
@ -42,6 +42,48 @@ from distutils import log
|
||||||
# should just happily stuff them into the preprocessor/compiler/linker
|
# should just happily stuff them into the preprocessor/compiler/linker
|
||||||
# options and carry on.
|
# 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):
|
class UnixCCompiler(CCompiler):
|
||||||
|
|
||||||
compiler_type = 'unix'
|
compiler_type = 'unix'
|
||||||
|
@ -108,8 +150,11 @@ class UnixCCompiler(CCompiler):
|
||||||
raise CompileError, msg
|
raise CompileError, msg
|
||||||
|
|
||||||
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
|
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:
|
try:
|
||||||
self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
|
self.spawn(compiler_so + cc_args + [src, '-o', obj] +
|
||||||
extra_postargs)
|
extra_postargs)
|
||||||
except DistutilsExecError, msg:
|
except DistutilsExecError, msg:
|
||||||
raise CompileError, msg
|
raise CompileError, msg
|
||||||
|
@ -172,7 +217,22 @@ class UnixCCompiler(CCompiler):
|
||||||
else:
|
else:
|
||||||
linker = self.linker_so[:]
|
linker = self.linker_so[:]
|
||||||
if target_lang == "c++" and self.compiler_cxx:
|
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)
|
self.spawn(linker + ld_args)
|
||||||
except DistutilsExecError, msg:
|
except DistutilsExecError, msg:
|
||||||
raise LinkError, msg
|
raise LinkError, msg
|
||||||
|
|
|
@ -67,6 +67,54 @@ def get_platform ():
|
||||||
m = rel_re.match(release)
|
m = rel_re.match(release)
|
||||||
if m:
|
if m:
|
||||||
release = m.group()
|
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)
|
return "%s-%s-%s" % (osname, release, machine)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue