Skip to content

Commit e994cb5

Browse files
committed
src: more macos cleanup
1 parent 14ed35f commit e994cb5

File tree

3 files changed

+78
-158
lines changed

3 files changed

+78
-158
lines changed

gyp/XCodeDetect.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"""Simplify access to Xcode information."""
2-
2+
import re
33
import subprocess
44
from common import memoize
55

66

7+
@memoize
78
def run(*cmd_args):
89
return subprocess.check_output(cmd_args, stderr=subprocess.PIPE).decode('utf-8').strip()
910

@@ -13,7 +14,7 @@ def Version():
1314
version = ''
1415
try:
1516
lines = run('xcodebuild', '-version').splitlines()
16-
version = ''.join(lines[0].decode('utf-8').split()[-1].split('.'))
17+
version = ''.join(lines[0].split()[-1].split('.'))
1718
version = (version + '0' * (3 - len(version))).zfill(4)
1819
except subprocess.CalledProcessError:
1920
pass
@@ -73,3 +74,8 @@ def GetIOSCodeSignIdentityKey(identity):
7374
assert len(match_lines) == 1, ("Not exactly one codesigning fingerprints for identity: %s \n%s" % (identity, output))
7475
fingerprint = match_lines[0].split()[1]
7576
return fingerprint
77+
78+
79+
@memoize
80+
def BuildMachineOSBuild():
81+
return run(['sw_vers', '-buildVersion'])

gyp/common.py

-16
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import filecmp
1010
import os.path
1111
import re
12-
import subprocess
1312
import tempfile
1413
import sys
1514

@@ -605,18 +604,3 @@ def CrossCompileRequested():
605604
os.environ.get('AR_target') or
606605
os.environ.get('CC_target') or
607606
os.environ.get('CXX_target'))
608-
609-
610-
def GetStdout(cmdlist, with_stderr=False):
611-
"""
612-
Returns the content of standard output returned by invoking |cmdlist|.
613-
Raises |GypError| if the command return with a non-zero return code.
614-
"""
615-
job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
616-
out, err = job.communicate()
617-
if job.returncode != 0:
618-
if with_stderr:
619-
print(out, file=sys.stderr)
620-
print(err, file=sys.stderr)
621-
raise GypError('Error %d running %s' % (job.returncode, cmdlist[0]))
622-
return out.rstrip('\n')

gyp/xcode_emulation.py

+70-140
Original file line numberDiff line numberDiff line change
@@ -15,85 +15,11 @@
1515
import re
1616
import shlex
1717

18-
from gyp.common import GypError, GetStdout, TopologicallySorted, EncodePOSIXShellList, CycleError
18+
from gyp.common import GypError, TopologicallySorted, EncodePOSIXShellList, CycleError, memoize
1919
import XCodeDetect
2020

21-
# Populated lazily by XCodeDetect.Version, for efficiency, and to fix an issue when
22-
# "xcodebuild" is called too quickly (it has been found to return incorrect
23-
# version number).
24-
XCODE_VERSION_CACHE = None
25-
26-
# Populated lazily by GetXcodeArchsDefault, to an |XcodeArchsDefault| instance
27-
# corresponding to the installed version of Xcode.
28-
XCODE_ARCHS_DEFAULT_CACHE = None
29-
30-
31-
def XcodeArchsVariableMapping(archs, archs_including_64_bit=None):
32-
"""Constructs a dictionary with expansion for $(ARCHS_STANDARD) variable,
33-
and optionally for $(ARCHS_STANDARD_INCLUDING_64_BIT)."""
34-
mapping = {'$(ARCHS_STANDARD)': archs}
35-
if archs_including_64_bit:
36-
mapping['$(ARCHS_STANDARD_INCLUDING_64_BIT)'] = archs_including_64_bit
37-
return mapping
38-
39-
40-
class XcodeArchsDefault(object):
41-
"""A class to resolve ARCHS variable from xcode_settings, resolving Xcode
42-
macros and implementing filtering by VALID_ARCHS. The expansion of macros
43-
depends on the SDKROOT used ("macosx", "iphoneos", "iphonesimulator") and
44-
on the version of Xcode.
45-
"""
46-
47-
# Match variable like $(ARCHS_STANDARD).
48-
variable_pattern = re.compile(r'\$\([a-zA-Z_][a-zA-Z0-9_]*\)$')
49-
50-
def __init__(self, default, mac, iphonesimulator, iphoneos):
51-
self._default = (default,)
52-
self._archs = {'mac': mac, 'ios': iphoneos, 'iossim': iphonesimulator}
53-
54-
def _VariableMapping(self, sdkroot):
55-
"""Returns the dictionary of variable mapping depending on the SDKROOT."""
56-
sdkroot = sdkroot.lower()
57-
if 'iphoneos' in sdkroot:
58-
return self._archs['ios']
59-
elif 'iphonesimulator' in sdkroot:
60-
return self._archs['iossim']
61-
else:
62-
return self._archs['mac']
63-
64-
def _ExpandArchs(self, archs, sdkroot):
65-
"""Expands variables references in ARCHS, and remove duplicates."""
66-
variable_mapping = self._VariableMapping(sdkroot)
67-
expanded_archs = []
68-
for arch in archs:
69-
if self.variable_pattern.match(arch):
70-
variable = arch
71-
try:
72-
variable_expansion = variable_mapping[variable]
73-
for arch2 in variable_expansion:
74-
if arch2 not in expanded_archs:
75-
expanded_archs.append(arch2)
76-
except KeyError as e:
77-
print('Warning: Ignoring unsupported variable "%s".' % variable)
78-
print(e)
79-
elif arch not in expanded_archs:
80-
expanded_archs.append(arch)
81-
return expanded_archs
82-
83-
def ActiveArchs(self, archs, valid_archs, sdkroot):
84-
"""Expands variables references in ARCHS, and filter by VALID_ARCHS if it
85-
is defined (if not set, Xcode accept any value in ARCHS, otherwise, only
86-
values present in VALID_ARCHS are kept)."""
87-
expanded_archs = self._ExpandArchs(archs or self._default, sdkroot or '')
88-
if valid_archs:
89-
filtered_archs = []
90-
for arch in expanded_archs:
91-
if arch in valid_archs:
92-
filtered_archs.append(arch)
93-
expanded_archs = filtered_archs
94-
return expanded_archs
95-
9621

22+
@memoize
9723
def GetXcodeArchsDefault():
9824
"""Returns the |XcodeArchsDefault| object to use to expand ARCHS for the
9925
installed version of Xcode. The default values used by Xcode for ARCHS
@@ -114,9 +40,71 @@ def GetXcodeArchsDefault():
11440
All thoses rules are coded in the construction of the |XcodeArchsDefault|
11541
object to use depending on the version of Xcode detected. The object is
11642
for performance reason."""
117-
global XCODE_ARCHS_DEFAULT_CACHE
118-
if XCODE_ARCHS_DEFAULT_CACHE:
119-
return XCODE_ARCHS_DEFAULT_CACHE
43+
44+
class XcodeArchsDefault(object):
45+
"""A class to resolve ARCHS variable from xcode_settings, resolving Xcode
46+
macros and implementing filtering by VALID_ARCHS. The expansion of macros
47+
depends on the SDKROOT used ("macosx", "iphoneos", "iphonesimulator") and
48+
on the version of Xcode.
49+
"""
50+
51+
# Match variable like $(ARCHS_STANDARD).
52+
variable_pattern = re.compile(r'\$\([a-zA-Z_][a-zA-Z0-9_]*\)$')
53+
54+
def __init__(self, default, mac, iphonesimulator, iphoneos):
55+
self._default = (default,)
56+
self._archs = {'mac': mac, 'ios': iphoneos, 'iossim': iphonesimulator}
57+
58+
def _VariableMapping(self, sdkroot):
59+
"""Returns the dictionary of variable mapping depending on the SDKROOT."""
60+
sdkroot = sdkroot.lower()
61+
if 'iphoneos' in sdkroot:
62+
return self._archs['ios']
63+
elif 'iphonesimulator' in sdkroot:
64+
return self._archs['iossim']
65+
else:
66+
return self._archs['mac']
67+
68+
def _ExpandArchs(self, archs, sdkroot):
69+
"""Expands variables references in ARCHS, and remove duplicates."""
70+
variable_mapping = self._VariableMapping(sdkroot)
71+
expanded_archs = []
72+
for arch in archs:
73+
if self.variable_pattern.match(arch):
74+
variable = arch
75+
try:
76+
variable_expansion = variable_mapping[variable]
77+
for arch2 in variable_expansion:
78+
if arch2 not in expanded_archs:
79+
expanded_archs.append(arch2)
80+
except KeyError as e:
81+
print('Warning: Ignoring unsupported variable "%s".' % variable)
82+
print(e)
83+
elif arch not in expanded_archs:
84+
expanded_archs.append(arch)
85+
return expanded_archs
86+
87+
def ActiveArchs(self, archs, valid_archs, sdkroot):
88+
"""Expands variables references in ARCHS, and filter by VALID_ARCHS if it
89+
is defined (if not set, Xcode accept any value in ARCHS, otherwise, only
90+
values present in VALID_ARCHS are kept)."""
91+
expanded_archs = self._ExpandArchs(archs or self._default, sdkroot or '')
92+
if valid_archs:
93+
filtered_archs = []
94+
for arch in expanded_archs:
95+
if arch in valid_archs:
96+
filtered_archs.append(arch)
97+
expanded_archs = filtered_archs
98+
return expanded_archs
99+
100+
def XcodeArchsVariableMapping(archs, archs_including_64_bit=None):
101+
"""Constructs a dictionary with expansion for $(ARCHS_STANDARD) variable,
102+
and optionally for $(ARCHS_STANDARD_INCLUDING_64_BIT)."""
103+
mapping = {'$(ARCHS_STANDARD)': archs}
104+
if archs_including_64_bit:
105+
mapping['$(ARCHS_STANDARD_INCLUDING_64_BIT)'] = archs_including_64_bit
106+
return mapping
107+
120108
xcode_version = XCodeDetect.Version()
121109
if xcode_version < '0500':
122110
XCODE_ARCHS_DEFAULT_CACHE = XcodeArchsDefault(
@@ -175,48 +163,14 @@ def _MapLinkerFlagFilename(ldflag, gyp_to_build_path):
175163
regex = re.compile('(?:-Wl,)?' + '[ ,]'.join(flag_pattern))
176164
m = regex.match(ldflag)
177165
if m:
178-
ldflag = ldflag[:m.start(1)] + gyp_to_build_path(m.group(1)) + \
179-
ldflag[m.end(1):]
166+
ldflag = ldflag[:m.start(1)] + gyp_to_build_path(m.group(1)) + ldflag[m.end(1):]
180167
# Required for ffmpeg (no idea why they don't use LIBRARY_SEARCH_PATHS,
181168
# TODO(thakis): Update ffmpeg.gyp):
182169
if ldflag.startswith('-L'):
183170
ldflag = '-L' + gyp_to_build_path(ldflag[len('-L'):])
184171
return ldflag
185172

186173

187-
def _BuildMachineOSBuild():
188-
return GetStdout(['sw_vers', '-buildVersion'])
189-
190-
191-
def _DefaultSdkRoot():
192-
"""Returns the default SDKROOT to use.
193-
194-
Prior to version 5.0.0, if SDKROOT was not explicitly set in the Xcode
195-
project, then the environment variable was empty. Starting with this
196-
version, Xcode uses the name of the newest SDK installed.
197-
"""
198-
xcode_version = XCodeDetect.Version()
199-
if xcode_version < '0500':
200-
return ''
201-
default_sdk_path = XCodeDetect.GetSdkVersionInfoItem('', '--show-sdk-path')
202-
default_sdk_root = XcodeSettings._sdk_root_cache.get(default_sdk_path)
203-
if default_sdk_root:
204-
return default_sdk_root
205-
try:
206-
all_sdks = GetStdout(['xcodebuild', '-showsdks'])
207-
except:
208-
# If xcodebuild fails, there will be no valid SDKs
209-
return ''
210-
for line in all_sdks.splitlines():
211-
items = line.split()
212-
if len(items) >= 3 and items[-2] == '-sdk':
213-
sdk_root = items[-1]
214-
sdk_path = XCodeDetect.GetSdkVersionInfoItem(sdk_root, '--show-sdk-path')
215-
if sdk_path == default_sdk_path:
216-
return sdk_root
217-
return ''
218-
219-
220174
class XcodeSettings(object):
221175
"""A class that understands the gyp 'xcode_settings' object."""
222176

@@ -1175,7 +1129,7 @@ def GetExtraPlistItems(self, configname=None):
11751129
if configname not in XcodeSettings._plist_cache:
11761130
xcode = XCodeDetect.Version()
11771131
cache = {
1178-
'BuildMachineOSBuild': _BuildMachineOSBuild(),
1132+
'BuildMachineOSBuild': XCodeDetect.BuildMachineOSBuild(),
11791133
'DTXcode': xcode
11801134
}
11811135
compiler = self.xcode_settings[configname].get('GCC_VERSION')
@@ -1184,7 +1138,7 @@ def GetExtraPlistItems(self, configname=None):
11841138

11851139
sdk_root = self._SdkRoot(configname)
11861140
if not sdk_root:
1187-
sdk_root = _DefaultSdkRoot()
1141+
sdk_root = XCodeDetect.GetSdkVersionInfoItem('macosx', '--show-sdk-path')
11881142
sdk_version = XCodeDetect.GetSdkVersionInfoItem(sdk_root, '--show-sdk-version')
11891143
cache['DTSDKName'] = sdk_root + (sdk_version or '')
11901144
if xcode >= '0720':
@@ -1322,30 +1276,6 @@ def GetPchBuildCommands(self, arch=None):
13221276
]
13231277

13241278

1325-
# This function ported from the logic in Homebrew's CLT version check
1326-
def CLTVersion():
1327-
"""Returns the version of command-line tools from pkgutil."""
1328-
# pkgutil output looks like
1329-
# package-id: com.apple.pkg.CLTools_Executables
1330-
# version: 5.0.1.0.1.1382131676
1331-
# volume: /
1332-
# location: /
1333-
# install-time: 1382544035
1334-
# groups: com.apple.FindSystemFiles.pkg-group com.apple.DevToolsBoth.pkg-group com.apple.DevToolsNonRelocatableShared.pkg-group
1335-
STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo"
1336-
FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI"
1337-
MAVERICKS_PKG_ID = "com.apple.pkg.CLTools_Executables"
1338-
1339-
regex = re.compile('version: (?P<version>.+)')
1340-
for key in [MAVERICKS_PKG_ID, STANDALONE_PKG_ID, FROM_XCODE_PKG_ID]:
1341-
# noinspection PyBroadException
1342-
try:
1343-
output = GetStdout(['/usr/sbin/pkgutil', '--pkg-info', key])
1344-
return re.search(regex, output).groupdict()['version']
1345-
except Exception:
1346-
pass
1347-
1348-
13491279
def MergeGlobalXcodeSettingsToSpec(global_dict, spec):
13501280
"""Merges the global xcode_settings dictionary into each configuration of the
13511281
target represented by spec. For keys that are both in the global and the local

0 commit comments

Comments
 (0)