118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily"""Shared OS X support functions."""
218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilyimport os
418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilyimport re
518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilyimport sys
618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily__all__ = [
818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    'compiler_fixup',
918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    'customize_config_vars',
1018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    'customize_compiler',
1118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    'get_platform_osx',
1218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily]
1318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
1418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily# configuration variables that may contain universal build flags,
1518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily# like "-arch" or "-isdkroot", that may need customization for
1618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily# the user environment
1718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily_UNIVERSAL_CONFIG_VARS = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS',
1818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                            'BLDSHARED', 'LDSHARED', 'CC', 'CXX',
1918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                            'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
2018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                            'PY_CORE_CFLAGS')
2118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
2218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily# configuration variables that may contain compiler calls
2318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily_COMPILER_CONFIG_VARS = ('BLDSHARED', 'LDSHARED', 'CC', 'CXX')
2418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
2518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily# prefix added to original configuration variable names
2618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily_INITPRE = '_OSX_SUPPORT_INITIAL_'
2718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
2818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
2918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _find_executable(executable, path=None):
3018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Tries to find 'executable' in the directories listed in 'path'.
3118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
3218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    A string listing directories separated by 'os.pathsep'; defaults to
3318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    os.environ['PATH'].  Returns the complete filename or None if not found.
3418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """
3518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if path is None:
3618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        path = os.environ['PATH']
3718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
3818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    paths = path.split(os.pathsep)
3918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    base, ext = os.path.splitext(executable)
4018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
4118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'):
4218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        executable = executable + '.exe'
4318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
4418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if not os.path.isfile(executable):
4518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        for p in paths:
4618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            f = os.path.join(p, executable)
4718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            if os.path.isfile(f):
4818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                # the file exists, we have a shot at spawn working
4918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                return f
5018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        return None
5118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    else:
5218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        return executable
5318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
5418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
5518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _read_output(commandstring):
56fb77386ffb3cbed8ba5c6864bab885a803f50985Ned Deily    """Output from successful command execution or None"""
5718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Similar to os.popen(commandstring, "r").read(),
5818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # but without actually using os.popen because that
5918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # function is not usable during python bootstrap.
6018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # tempfile is also not available then.
6118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    import contextlib
6218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    try:
6318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        import tempfile
6418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        fp = tempfile.NamedTemporaryFile()
6518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    except ImportError:
6618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        fp = open("/tmp/_osx_support.%s"%(
6718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            os.getpid(),), "w+b")
6818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
6918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    with contextlib.closing(fp) as fp:
7018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name)
71fb77386ffb3cbed8ba5c6864bab885a803f50985Ned Deily        return fp.read().strip() if not os.system(cmd) else None
7218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
7318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
7418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _find_build_tool(toolname):
7518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Find a build tool on current path or using xcrun"""
7618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return (_find_executable(toolname)
7718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                or _read_output("/usr/bin/xcrun -find %s" % (toolname,))
7818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                or ''
7918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            )
8018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
8118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily_SYSTEM_VERSION = None
8218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
8318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _get_system_version():
8418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Return the OS X system version as a string"""
8518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Reading this plist is a documented way to get the system
8618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # version (see the documentation for the Gestalt Manager)
8718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # We avoid using platform.mac_ver to avoid possible bootstrap issues during
8818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # the build of Python itself (distutils is used to build standard library
8918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # extensions).
9018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
9118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    global _SYSTEM_VERSION
9218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
9318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if _SYSTEM_VERSION is None:
9418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        _SYSTEM_VERSION = ''
9518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        try:
9618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            f = open('/System/Library/CoreServices/SystemVersion.plist')
9718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        except IOError:
9818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # We're on a plain darwin box, fall back to the default
9918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # behaviour.
10018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            pass
10118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        else:
10218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            try:
10318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                m = re.search(r'<key>ProductUserVisibleVersion</key>\s*'
10418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                              r'<string>(.*?)</string>', f.read())
10518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            finally:
10618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                f.close()
10718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            if m is not None:
10818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                _SYSTEM_VERSION = '.'.join(m.group(1).split('.')[:2])
10918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # else: fall back to the default behaviour
11018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
11118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return _SYSTEM_VERSION
11218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
11318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _remove_original_values(_config_vars):
11418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Remove original unmodified values for testing"""
11518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # This is needed for higher-level cross-platform tests of get_platform.
11618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    for k in list(_config_vars):
11718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        if k.startswith(_INITPRE):
11818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            del _config_vars[k]
11918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
12018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _save_modified_value(_config_vars, cv, newvalue):
12118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Save modified and original unmodified value of configuration var"""
12218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
12318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    oldvalue = _config_vars.get(cv, '')
12418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if (oldvalue != newvalue) and (_INITPRE + cv not in _config_vars):
12518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        _config_vars[_INITPRE + cv] = oldvalue
12618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    _config_vars[cv] = newvalue
12718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
12818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _supports_universal_builds():
12918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Returns True if universal builds are supported on this system"""
13018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # As an approximation, we assume that if we are running on 10.4 or above,
13118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # then we are running with an Xcode environment that supports universal
13218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # builds, in particular -isysroot and -arch arguments to the compiler. This
13318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # is in support of allowing 10.4 universal builds to run on 10.3.x systems.
13418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
13518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    osx_version = _get_system_version()
13618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if osx_version:
13718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        try:
13818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            osx_version = tuple(int(i) for i in osx_version.split('.'))
13918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        except ValueError:
14018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            osx_version = ''
14118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return bool(osx_version >= (10, 4)) if osx_version else False
14218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
14318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
14418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _find_appropriate_compiler(_config_vars):
14518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Find appropriate C compiler for extension module builds"""
14618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
14718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Issue #13590:
14818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #    The OSX location for the compiler varies between OSX
14918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #    (or rather Xcode) releases.  With older releases (up-to 10.5)
15018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #    the compiler is in /usr/bin, with newer releases the compiler
15118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #    can only be found inside Xcode.app if the "Command Line Tools"
15218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #    are not installed.
15318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #
154b1d867f14965e2369d31a3fcdab5bca34b4d81b4Martin Panter    #    Furthermore, the compiler that can be used varies between
155f5469cff1f90381819291bcddcc70f5aaf2da141Ezio Melotti    #    Xcode releases. Up to Xcode 4 it was possible to use 'gcc-4.2'
15618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #    as the compiler, after that 'clang' should be used because
15718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #    gcc-4.2 is either not present, or a copy of 'llvm-gcc' that
15818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #    miscompiles Python.
15918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
1608d496add74530767cad3aa8b5b371b9a7f0b8498Martin Panter    # skip checks if the compiler was overridden with a CC env variable
16118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if 'CC' in os.environ:
16218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        return _config_vars
16318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
16418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # The CC config var might contain additional arguments.
16518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Ignore them while searching.
16618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    cc = oldcc = _config_vars['CC'].split()[0]
16718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if not _find_executable(cc):
16818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # Compiler is not found on the shell search PATH.
16918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # Now search for clang, first on PATH (if the Command LIne
17018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # Tools have been installed in / or if the user has provided
17118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # another location via CC).  If not found, try using xcrun
17218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # to find an uninstalled clang (within a selected Xcode).
17318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
17418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # NOTE: Cannot use subprocess here because of bootstrap
17518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # issues when building Python itself (and os.popen is
17618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # implemented on top of subprocess and is therefore not
17718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # usable as well)
17818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
17918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        cc = _find_build_tool('clang')
18018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
18118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    elif os.path.basename(cc).startswith('gcc'):
18218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # Compiler is GCC, check if it is LLVM-GCC
18318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        data = _read_output("'%s' --version"
18418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                             % (cc.replace("'", "'\"'\"'"),))
18584889012820d5bfa02d77898a433e214b22b187aNed Deily        if data and 'llvm-gcc' in data:
18618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # Found LLVM-GCC, fall back to clang
18718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            cc = _find_build_tool('clang')
18818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
18918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if not cc:
19018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        raise SystemError(
19118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily               "Cannot locate working compiler")
19218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
19318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if cc != oldcc:
19418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # Found a replacement compiler.
195f5469cff1f90381819291bcddcc70f5aaf2da141Ezio Melotti        # Modify config vars using new compiler, if not already explicitly
1968d496add74530767cad3aa8b5b371b9a7f0b8498Martin Panter        # overridden by an env variable, preserving additional arguments.
19718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        for cv in _COMPILER_CONFIG_VARS:
19818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            if cv in _config_vars and cv not in os.environ:
19918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                cv_split = _config_vars[cv].split()
20018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                cv_split[0] = cc if cv != 'CXX' else cc + '++'
20118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                _save_modified_value(_config_vars, cv, ' '.join(cv_split))
20218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
20318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return _config_vars
20418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
20518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
20618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _remove_universal_flags(_config_vars):
20718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Remove all universal build arguments from config vars"""
20818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
20918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    for cv in _UNIVERSAL_CONFIG_VARS:
2108d496add74530767cad3aa8b5b371b9a7f0b8498Martin Panter        # Do not alter a config var explicitly overridden by env var
21118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        if cv in _config_vars and cv not in os.environ:
21218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            flags = _config_vars[cv]
21318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            flags = re.sub('-arch\s+\w+\s', ' ', flags)
21418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            flags = re.sub('-isysroot [^ \t]*', ' ', flags)
21518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            _save_modified_value(_config_vars, cv, flags)
21618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
21718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return _config_vars
21818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
21918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
22018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _remove_unsupported_archs(_config_vars):
22118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Remove any unsupported archs from config vars"""
22218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Different Xcode releases support different sets for '-arch'
22318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # flags. In particular, Xcode 4.x no longer supports the
22418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # PPC architectures.
22518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #
22618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # This code automatically removes '-arch ppc' and '-arch ppc64'
22718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # when these are not supported. That makes it possible to
22818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # build extensions on OSX 10.7 and later with the prebuilt
22918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # 32-bit installer on the python.org website.
23018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
2318d496add74530767cad3aa8b5b371b9a7f0b8498Martin Panter    # skip checks if the compiler was overridden with a CC env variable
23218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if 'CC' in os.environ:
23318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        return _config_vars
23418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
23518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if re.search('-arch\s+ppc', _config_vars['CFLAGS']) is not None:
23618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # NOTE: Cannot use subprocess here because of bootstrap
23718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # issues when building Python itself
2387c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily        status = os.system(
2397c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            """echo 'int main{};' | """
2407c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            """'%s' -c -arch ppc -x c -o /dev/null /dev/null 2>/dev/null"""
2417c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            %(_config_vars['CC'].replace("'", "'\"'\"'"),))
2427c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily        if status:
2437c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            # The compile failed for some reason.  Because of differences
2447c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            # across Xcode and compiler versions, there is no reliable way
2457c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            # to be sure why it failed.  Assume here it was due to lack of
2467c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            # PPC support and remove the related '-arch' flags from each
2478d496add74530767cad3aa8b5b371b9a7f0b8498Martin Panter            # config variables not explicitly overridden by an environment
2487c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            # variable.  If the error was for some other reason, we hope the
2497c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            # failure will show up again when trying to compile an extension
2507c5ba45fd87443f3bc50e6dd486fc88704a2428aNed Deily            # module.
25118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            for cv in _UNIVERSAL_CONFIG_VARS:
25218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                if cv in _config_vars and cv not in os.environ:
25318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                    flags = _config_vars[cv]
25418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                    flags = re.sub('-arch\s+ppc\w*\s', ' ', flags)
25518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                    _save_modified_value(_config_vars, cv, flags)
25618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
25718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return _config_vars
25818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
25918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
26018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _override_all_archs(_config_vars):
26118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Allow override of all archs with ARCHFLAGS env var"""
26218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # NOTE: This name was introduced by Apple in OSX 10.5 and
26318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # is used by several scripting languages distributed with
26418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # that OS release.
26518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if 'ARCHFLAGS' in os.environ:
26618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        arch = os.environ['ARCHFLAGS']
26718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        for cv in _UNIVERSAL_CONFIG_VARS:
26818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            if cv in _config_vars and '-arch' in _config_vars[cv]:
26918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                flags = _config_vars[cv]
27018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                flags = re.sub('-arch\s+\w+\s', ' ', flags)
27118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                flags = flags + ' ' + arch
27218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                _save_modified_value(_config_vars, cv, flags)
27318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
27418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return _config_vars
27518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
27618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
27718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef _check_for_unavailable_sdk(_config_vars):
27818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Remove references to any SDKs not available"""
27918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # If we're on OSX 10.5 or later and the user tries to
28018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # compile an extension using an SDK that is not present
28118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # on the current machine it is better to not use an SDK
28218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # than to fail.  This is particularly important with
283f5469cff1f90381819291bcddcc70f5aaf2da141Ezio Melotti    # the standalone Command Line Tools alternative to a
28418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # full-blown Xcode install since the CLT packages do not
28518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # provide SDKs.  If the SDK is not present, it is assumed
28618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # that the header files and dev libs have been installed
28718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # to /usr and /System/Library by either a standalone CLT
28818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # package or the CLT component within Xcode.
28918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    cflags = _config_vars.get('CFLAGS', '')
29018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    m = re.search(r'-isysroot\s+(\S+)', cflags)
29118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if m is not None:
29218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        sdk = m.group(1)
29318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        if not os.path.exists(sdk):
29418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            for cv in _UNIVERSAL_CONFIG_VARS:
2958d496add74530767cad3aa8b5b371b9a7f0b8498Martin Panter                # Do not alter a config var explicitly overridden by env var
29618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                if cv in _config_vars and cv not in os.environ:
29718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                    flags = _config_vars[cv]
29818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                    flags = re.sub(r'-isysroot\s+\S+(?:\s|$)', ' ', flags)
29918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                    _save_modified_value(_config_vars, cv, flags)
30018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
30118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return _config_vars
30218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
30318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
30418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef compiler_fixup(compiler_so, cc_args):
30518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """
30618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    This function will strip '-isysroot PATH' and '-arch ARCH' from the
30718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    compile flags if the user has specified one them in extra_compile_flags.
30818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
30918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    This is needed because '-arch ARCH' adds another architecture to the
31018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    build, without a way to remove an architecture. Furthermore GCC will
31118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    barf if multiple '-isysroot' arguments are present.
31218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """
31318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    stripArch = stripSysroot = False
31418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
31518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    compiler_so = list(compiler_so)
31618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
31718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if not _supports_universal_builds():
31818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # OSX before 10.4.0, these don't support -arch and -isysroot at
31918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # all.
32018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        stripArch = stripSysroot = True
32118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    else:
32218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        stripArch = '-arch' in cc_args
32318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        stripSysroot = '-isysroot' in cc_args
32418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
32518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if stripArch or 'ARCHFLAGS' in os.environ:
32618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        while True:
32718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            try:
32818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                index = compiler_so.index('-arch')
32918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                # Strip this argument and the next one:
33018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                del compiler_so[index:index+2]
33118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            except ValueError:
33218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                break
33318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
33418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if 'ARCHFLAGS' in os.environ and not stripArch:
33518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # User specified different -arch flags in the environ,
33618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # see also distutils.sysconfig
33718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        compiler_so = compiler_so + os.environ['ARCHFLAGS'].split()
33818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
33918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if stripSysroot:
34018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        while True:
34118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            try:
34218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                index = compiler_so.index('-isysroot')
34318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                # Strip this argument and the next one:
34418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                del compiler_so[index:index+2]
34518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            except ValueError:
34618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                break
34718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
34818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Check if the SDK that is used during compilation actually exists,
34918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # the universal build requires the usage of a universal SDK and not all
35018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # users have that installed by default.
35118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    sysroot = None
35218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if '-isysroot' in cc_args:
35318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        idx = cc_args.index('-isysroot')
35418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        sysroot = cc_args[idx+1]
35518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    elif '-isysroot' in compiler_so:
35618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        idx = compiler_so.index('-isysroot')
35718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        sysroot = compiler_so[idx+1]
35818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
35918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if sysroot and not os.path.isdir(sysroot):
36018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        from distutils import log
36118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        log.warn("Compiling with an SDK that doesn't seem to exist: %s",
36218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                sysroot)
36318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        log.warn("Please check your Xcode installation")
36418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
36518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return compiler_so
36618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
36718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
36818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef customize_config_vars(_config_vars):
36918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Customize Python build configuration variables.
37018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
37118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    Called internally from sysconfig with a mutable mapping
37218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    containing name/value pairs parsed from the configured
37318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    makefile used to build this interpreter.  Returns
37418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    the mapping updated as needed to reflect the environment
37518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    in which the interpreter is running; in the case of
37618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    a Python from a binary installer, the installed
37718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    environment may be very different from the build
37818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    environment, i.e. different OS levels, different
37918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    built tools, different available CPU architectures.
38018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
38118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    This customization is performed whenever
38218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    distutils.sysconfig.get_config_vars() is first
38318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    called.  It may be used in environments where no
38418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    compilers are present, i.e. when installing pure
38518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    Python dists.  Customization of compiler paths
38618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    and detection of unavailable archs is deferred
387f5469cff1f90381819291bcddcc70f5aaf2da141Ezio Melotti    until the first extension module build is
38818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    requested (in distutils.sysconfig.customize_compiler).
38918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
39018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    Currently called from distutils.sysconfig
39118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """
39218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
39318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if not _supports_universal_builds():
39418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # On Mac OS X before 10.4, check if -arch and -isysroot
39518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # are in CFLAGS or LDFLAGS and remove them if they are.
39618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # This is needed when building extensions on a 10.3 system
39718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # using a universal build of python.
39818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        _remove_universal_flags(_config_vars)
39918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
40018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Allow user to override all archs with ARCHFLAGS env var
40118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    _override_all_archs(_config_vars)
40218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
40318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Remove references to sdks that are not found
40418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    _check_for_unavailable_sdk(_config_vars)
40518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
40618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return _config_vars
40718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
40818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
40918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef customize_compiler(_config_vars):
41018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Customize compiler path and configuration variables.
41118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
41218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    This customization is performed when the first
41318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    extension module build is requested
41418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    in distutils.sysconfig.customize_compiler).
41518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """
41618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
41718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Find a compiler to use for extension module builds
41818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    _find_appropriate_compiler(_config_vars)
41918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
42018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Remove ppc arch flags if not supported here
42118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    _remove_unsupported_archs(_config_vars)
42218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
42318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # Allow user to override all archs with ARCHFLAGS env var
42418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    _override_all_archs(_config_vars)
42518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
42618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return _config_vars
42718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
42818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
42918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deilydef get_platform_osx(_config_vars, osname, release, machine):
43018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    """Filter values for get_platform()"""
43118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # called from get_platform() in sysconfig and distutils.util
43218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    #
43318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # For our purposes, we'll assume that the system version from
43418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
43518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # to. This makes the compatibility story a bit more sane because the
43618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # machine is going to compile and link as if it were
43718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    # MACOSX_DEPLOYMENT_TARGET.
43818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
43918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    macver = _config_vars.get('MACOSX_DEPLOYMENT_TARGET', '')
44018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    macrelease = _get_system_version() or macver
44118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    macver = macver or macrelease
44218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
44318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    if macver:
44418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        release = macver
44518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        osname = "macosx"
44618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
44718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # Use the original CFLAGS value, if available, so that we
44818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # return the same machine type for the platform string.
44918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # Otherwise, distutils may consider this a cross-compiling
45018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        # case and disallow installs.
45118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        cflags = _config_vars.get(_INITPRE+'CFLAGS',
45218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                                    _config_vars.get('CFLAGS', ''))
4531f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily        if macrelease:
4541f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily            try:
4551f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily                macrelease = tuple(int(i) for i in macrelease.split('.')[0:2])
4561f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily            except ValueError:
4571f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily                macrelease = (10, 0)
4581f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily        else:
4591f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily            # assume no universal support
4601f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily            macrelease = (10, 0)
4611f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily
4621f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily        if (macrelease >= (10, 4)) and '-arch' in cflags.strip():
46318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # The universal build will build fat binaries, but not on
46418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # systems before 10.4
46518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
46618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            machine = 'fat'
46718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
46818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            archs = re.findall('-arch\s+(\S+)', cflags)
46918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            archs = tuple(sorted(set(archs)))
47018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
47118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            if len(archs) == 1:
47218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                machine = archs[0]
47318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            elif archs == ('i386', 'ppc'):
47418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                machine = 'fat'
47518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            elif archs == ('i386', 'x86_64'):
47618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                machine = 'intel'
47718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            elif archs == ('i386', 'ppc', 'x86_64'):
47818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                machine = 'fat3'
47918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            elif archs == ('ppc64', 'x86_64'):
48018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                machine = 'fat64'
48118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
48218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                machine = 'universal'
48318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            else:
48418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                raise ValueError(
48518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                   "Don't know machine value for archs=%r" % (archs,))
48618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
48718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        elif machine == 'i386':
48818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # On OSX the machine type returned by uname is always the
48918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # 32-bit variant, even if the executable architecture is
49018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # the 64-bit variant
49118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            if sys.maxint >= 2**32:
49218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                machine = 'x86_64'
49318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
49418fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily        elif machine in ('PowerPC', 'Power_Macintosh'):
49518fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # Pick a sane name for the PPC architecture.
49618fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            # See 'i386' case
49718fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            if sys.maxint >= 2**32:
49818fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                machine = 'ppc64'
49918fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily            else:
50018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily                machine = 'ppc'
50118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily
50218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily    return (osname, release, machine)
503