From b310700976524b4b99ee319c947ca40468716fc9 Mon Sep 17 00:00:00 2001 From: Joshua Root Date: Wed, 22 Apr 2020 17:44:10 +1000 Subject: bpo-38360: macOS: support alternate form of -isysroot flag (GH-16480) It is possible to use either '-isysroot /some/path' (with a space) or '-isysroot/some/path' (no space in between). Support both forms in places where special handling of -isysroot is done, rather than just the first form. Co-authored-by: Ned Deily --- Lib/_osx_support.py | 39 +++++++++++------ Lib/distutils/unixccompiler.py | 2 +- Lib/test/test__osx_support.py | 51 ++++++++++++++++++++++ .../Build/2020-04-22-02-33-54.bpo-38360.74C68u.rst | 1 + setup.py | 2 +- 5 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2020-04-22-02-33-54.bpo-38360.74C68u.rst diff --git a/Lib/_osx_support.py b/Lib/_osx_support.py index db6674e..e9efce7 100644 --- a/Lib/_osx_support.py +++ b/Lib/_osx_support.py @@ -211,7 +211,7 @@ def _remove_universal_flags(_config_vars): if cv in _config_vars and cv not in os.environ: flags = _config_vars[cv] flags = re.sub(r'-arch\s+\w+\s', ' ', flags, flags=re.ASCII) - flags = re.sub('-isysroot [^ \t]*', ' ', flags) + flags = re.sub(r'-isysroot\s*\S+', ' ', flags) _save_modified_value(_config_vars, cv, flags) return _config_vars @@ -287,7 +287,7 @@ def _check_for_unavailable_sdk(_config_vars): # to /usr and /System/Library by either a standalone CLT # package or the CLT component within Xcode. cflags = _config_vars.get('CFLAGS', '') - m = re.search(r'-isysroot\s+(\S+)', cflags) + m = re.search(r'-isysroot\s*(\S+)', cflags) if m is not None: sdk = m.group(1) if not os.path.exists(sdk): @@ -295,7 +295,7 @@ def _check_for_unavailable_sdk(_config_vars): # Do not alter a config var explicitly overridden by env var if cv in _config_vars and cv not in os.environ: flags = _config_vars[cv] - flags = re.sub(r'-isysroot\s+\S+(?:\s|$)', ' ', flags) + flags = re.sub(r'-isysroot\s*\S+(?:\s|$)', ' ', flags) _save_modified_value(_config_vars, cv, flags) return _config_vars @@ -320,7 +320,7 @@ def compiler_fixup(compiler_so, cc_args): stripArch = stripSysroot = True else: stripArch = '-arch' in cc_args - stripSysroot = '-isysroot' in cc_args + stripSysroot = any(arg for arg in cc_args if arg.startswith('-isysroot')) if stripArch or 'ARCHFLAGS' in os.environ: while True: @@ -338,23 +338,34 @@ def compiler_fixup(compiler_so, cc_args): if stripSysroot: while True: - try: - index = compiler_so.index('-isysroot') + indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')] + if not indices: + break + index = indices[0] + if compiler_so[index] == '-isysroot': # Strip this argument and the next one: del compiler_so[index:index+2] - except ValueError: - break + else: + # It's '-isysroot/some/path' in one arg + del compiler_so[index:index+1] # Check if the SDK that is used during compilation actually exists, # the universal build requires the usage of a universal SDK and not all # users have that installed by default. sysroot = None - if '-isysroot' in cc_args: - idx = cc_args.index('-isysroot') - sysroot = cc_args[idx+1] - elif '-isysroot' in compiler_so: - idx = compiler_so.index('-isysroot') - sysroot = compiler_so[idx+1] + argvar = cc_args + indices = [i for i,x in enumerate(cc_args) if x.startswith('-isysroot')] + if not indices: + argvar = compiler_so + indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')] + + for idx in indices: + if argvar[idx] == '-isysroot': + sysroot = argvar[idx+1] + break + else: + sysroot = argvar[idx][len('-isysroot'):] + break if sysroot and not os.path.isdir(sysroot): from distutils import log diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py index d10a78d..4d7a6de 100644 --- a/Lib/distutils/unixccompiler.py +++ b/Lib/distutils/unixccompiler.py @@ -288,7 +288,7 @@ class UnixCCompiler(CCompiler): # vs # /usr/lib/libedit.dylib cflags = sysconfig.get_config_var('CFLAGS') - m = re.search(r'-isysroot\s+(\S+)', cflags) + m = re.search(r'-isysroot\s*(\S+)', cflags) if m is None: sysroot = '/' else: diff --git a/Lib/test/test__osx_support.py b/Lib/test/test__osx_support.py index 388a2b1..1a5d649 100644 --- a/Lib/test/test__osx_support.py +++ b/Lib/test/test__osx_support.py @@ -174,6 +174,29 @@ class Test_OSXSupport(unittest.TestCase): _osx_support._remove_universal_flags( config_vars)) + def test__remove_universal_flags_alternate(self): + # bpo-38360: also test the alternate single-argument form of -isysroot + config_vars = { + 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ', + 'LDFLAGS': '-arch ppc -arch i386 -g', + 'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.4u.sdk', + 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', + 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' + '-isysroot/Developer/SDKs/MacOSX10.4u.sdk -g', + } + expected_vars = { + 'CFLAGS': '-fno-strict-aliasing -g -O3 ', + 'LDFLAGS': ' -g', + 'CPPFLAGS': '-I. ', + 'BLDSHARED': 'gcc-4.0 -bundle -g', + 'LDSHARED': 'gcc-4.0 -bundle -g', + } + self.add_expected_saved_initial_values(config_vars, expected_vars) + + self.assertEqual(expected_vars, + _osx_support._remove_universal_flags( + config_vars)) + def test__remove_unsupported_archs(self): config_vars = { 'CC': 'clang', @@ -261,6 +284,34 @@ class Test_OSXSupport(unittest.TestCase): _osx_support._check_for_unavailable_sdk( config_vars)) + def test__check_for_unavailable_sdk_alternate(self): + # bpo-38360: also test the alternate single-argument form of -isysroot + config_vars = { + 'CC': 'clang', + 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ' + '-isysroot/Developer/SDKs/MacOSX10.1.sdk', + 'LDFLAGS': '-arch ppc -arch i386 -g', + 'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.1.sdk', + 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', + 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' + '-isysroot/Developer/SDKs/MacOSX10.1.sdk -g', + } + expected_vars = { + 'CC': 'clang', + 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ' + ' ', + 'LDFLAGS': '-arch ppc -arch i386 -g', + 'CPPFLAGS': '-I. ', + 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', + 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' + ' -g', + } + self.add_expected_saved_initial_values(config_vars, expected_vars) + + self.assertEqual(expected_vars, + _osx_support._check_for_unavailable_sdk( + config_vars)) + def test_get_platform_osx(self): # Note, get_platform_osx is currently tested more extensively # indirectly by test_sysconfig and test_distutils diff --git a/Misc/NEWS.d/next/Build/2020-04-22-02-33-54.bpo-38360.74C68u.rst b/Misc/NEWS.d/next/Build/2020-04-22-02-33-54.bpo-38360.74C68u.rst new file mode 100644 index 0000000..e96ca14 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2020-04-22-02-33-54.bpo-38360.74C68u.rst @@ -0,0 +1 @@ +Support single-argument form of macOS -isysroot flag. diff --git a/setup.py b/setup.py index d241dc0..8783721 100644 --- a/setup.py +++ b/setup.py @@ -170,7 +170,7 @@ def macosx_sdk_root(): return MACOS_SDK_ROOT cflags = sysconfig.get_config_var('CFLAGS') - m = re.search(r'-isysroot\s+(\S+)', cflags) + m = re.search(r'-isysroot\s*(\S+)', cflags) if m is not None: MACOS_SDK_ROOT = m.group(1) else: -- cgit v0.12