20
20
import tempfile
21
21
from gyp .common import GypError
22
22
23
+ PY3 = bytes != str
24
+
23
25
# Populated lazily by XcodeVersion, for efficiency, and to fix an issue when
24
26
# "xcodebuild" is called too quickly (it has been found to return incorrect
25
27
# version number).
@@ -498,7 +500,7 @@ def _GetSdkVersionInfoItem(self, sdk, infoitem):
498
500
# most sensible route and should still do the right thing.
499
501
try :
500
502
return GetStdoutQuiet (['xcrun' , '--sdk' , sdk , infoitem ])
501
- except :
503
+ except GypError :
502
504
pass
503
505
504
506
def _SdkRoot (self , configname ):
@@ -928,7 +930,8 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None):
928
930
# extensions and provide loader and main function.
929
931
# These flags reflect the compilation options used by xcode to compile
930
932
# extensions.
931
- if XcodeVersion () < '0900' :
933
+ xcode_version , _ = XcodeVersion ()
934
+ if xcode_version < '0900' :
932
935
ldflags .append ('-lpkstart' )
933
936
ldflags .append (sdk_root +
934
937
'/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit' )
@@ -1204,8 +1207,8 @@ def GetExtraPlistItems(self, configname=None):
1204
1207
cache = {}
1205
1208
cache ['BuildMachineOSBuild' ] = self ._BuildMachineOSBuild ()
1206
1209
1207
- xcode , xcode_build = XcodeVersion ()
1208
- cache ['DTXcode' ] = xcode
1210
+ xcode_version , xcode_build = XcodeVersion ()
1211
+ cache ['DTXcode' ] = xcode_version
1209
1212
cache ['DTXcodeBuild' ] = xcode_build
1210
1213
compiler = self .xcode_settings [configname ].get ('GCC_VERSION' )
1211
1214
if compiler is not None :
@@ -1216,10 +1219,10 @@ def GetExtraPlistItems(self, configname=None):
1216
1219
sdk_root = self ._DefaultSdkRoot ()
1217
1220
sdk_version = self ._GetSdkVersionInfoItem (sdk_root , '--show-sdk-version' )
1218
1221
cache ['DTSDKName' ] = sdk_root + (sdk_version or '' )
1219
- if xcode >= '0720' :
1222
+ if xcode_version >= '0720' :
1220
1223
cache ['DTSDKBuild' ] = self ._GetSdkVersionInfoItem (
1221
1224
sdk_root , '--show-sdk-build-version' )
1222
- elif xcode >= '0430' :
1225
+ elif xcode_version >= '0430' :
1223
1226
cache ['DTSDKBuild' ] = sdk_version
1224
1227
else :
1225
1228
cache ['DTSDKBuild' ] = cache ['BuildMachineOSBuild' ]
@@ -1254,7 +1257,7 @@ def _DefaultSdkRoot(self):
1254
1257
project, then the environment variable was empty. Starting with this
1255
1258
version, Xcode uses the name of the newest SDK installed.
1256
1259
"""
1257
- xcode_version , xcode_build = XcodeVersion ()
1260
+ xcode_version , _ = XcodeVersion ()
1258
1261
if xcode_version < '0500' :
1259
1262
return ''
1260
1263
default_sdk_path = self ._XcodeSdkPath ('' )
@@ -1263,7 +1266,7 @@ def _DefaultSdkRoot(self):
1263
1266
return default_sdk_root
1264
1267
try :
1265
1268
all_sdks = GetStdout (['xcodebuild' , '-showsdks' ])
1266
- except :
1269
+ except GypError :
1267
1270
# If xcodebuild fails, there will be no valid SDKs
1268
1271
return ''
1269
1272
for line in all_sdks .splitlines ():
@@ -1391,10 +1394,12 @@ def XcodeVersion():
1391
1394
# Xcode 3.2.6
1392
1395
# Component versions: DevToolsCore-1809.0; DevToolsSupport-1806.0
1393
1396
# BuildVersion: 10M2518
1394
- # Convert that to '0463', '4H1503'.
1397
+ # Convert that to ( '0463', '4H1503') or ('0326', '10M2518') .
1395
1398
global XCODE_VERSION_CACHE
1396
1399
if XCODE_VERSION_CACHE :
1397
1400
return XCODE_VERSION_CACHE
1401
+ version = ""
1402
+ build = ""
1398
1403
try :
1399
1404
version_list = GetStdoutQuiet (['xcodebuild' , '-version' ]).splitlines ()
1400
1405
# In some circumstances xcodebuild exits 0 but doesn't return
@@ -1404,21 +1409,16 @@ def XcodeVersion():
1404
1409
# checking that version.
1405
1410
if len (version_list ) < 2 :
1406
1411
raise GypError ("xcodebuild returned unexpected results" )
1407
- except :
1408
- version = CLTVersion ()
1409
- if version :
1410
- version = re . match ( r'(\d+\.\d+\.?\d*)' , version ). groups ()[ 0 ]
1411
- else :
1412
+ version = version_list [ 0 ]. split ()[ - 1 ] # Last word on first line
1413
+ build = version_list [ - 1 ]. split ()[ - 1 ] # Last word on last line
1414
+ except GypError : # Xcode not installed so look for XCode Command Line Tools
1415
+ version = CLTVersion () # macOS Catalina returns 11.0.0.0.1.1567737322
1416
+ if not version :
1412
1417
raise GypError ("No Xcode or CLT version detected!" )
1413
- # The CLT has no build information, so we return an empty string.
1414
- version_list = [version , '' ]
1415
- version = version_list [0 ]
1416
- build = version_list [- 1 ]
1417
- # Be careful to convert "4.2" to "0420":
1418
- version = version .split ()[- 1 ].replace ('.' , '' )
1419
- version = (version + '0' * (3 - len (version ))).zfill (4 )
1420
- if build :
1421
- build = build .split ()[- 1 ]
1418
+ # Be careful to convert "4.2.3" to "0423" and "11.0.0" to "1100":
1419
+ version = version .split ("." )[:3 ] # Just major, minor, micro
1420
+ version [0 ] = version [0 ].zfill (2 ) # Add a leading zero if major is one digit
1421
+ version = ("" .join (version ) + "00" )[:4 ] # Limit to exactly four characters
1422
1422
XCODE_VERSION_CACHE = (version , build )
1423
1423
return XCODE_VERSION_CACHE
1424
1424
@@ -1442,7 +1442,7 @@ def CLTVersion():
1442
1442
try :
1443
1443
output = GetStdout (['/usr/sbin/pkgutil' , '--pkg-info' , key ])
1444
1444
return re .search (regex , output ).groupdict ()['version' ]
1445
- except :
1445
+ except GypError :
1446
1446
continue
1447
1447
1448
1448
@@ -1453,6 +1453,8 @@ def GetStdoutQuiet(cmdlist):
1453
1453
job = subprocess .Popen (cmdlist , stdout = subprocess .PIPE ,
1454
1454
stderr = subprocess .PIPE )
1455
1455
out = job .communicate ()[0 ]
1456
+ if PY3 :
1457
+ out = out .decode ("utf-8" )
1456
1458
if job .returncode != 0 :
1457
1459
raise GypError ('Error %d running %s' % (job .returncode , cmdlist [0 ]))
1458
1460
return out .rstrip ('\n ' )
@@ -1463,6 +1465,8 @@ def GetStdout(cmdlist):
1463
1465
Raises |GypError| if the command return with a non-zero return code."""
1464
1466
job = subprocess .Popen (cmdlist , stdout = subprocess .PIPE )
1465
1467
out = job .communicate ()[0 ]
1468
+ if PY3 :
1469
+ out = out .decode ("utf-8" )
1466
1470
if job .returncode != 0 :
1467
1471
sys .stderr .write (out + '\n ' )
1468
1472
raise GypError ('Error %d running %s' % (job .returncode , cmdlist [0 ]))
@@ -1674,7 +1678,8 @@ def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration,
1674
1678
install_name_base = xcode_settings .GetInstallNameBase ()
1675
1679
if install_name_base :
1676
1680
env ['DYLIB_INSTALL_NAME_BASE' ] = install_name_base
1677
- if XcodeVersion () >= '0500' and not env .get ('SDKROOT' ):
1681
+ xcode_version , _ = XcodeVersion ()
1682
+ if xcode_version >= '0500' and not env .get ('SDKROOT' ):
1678
1683
sdk_root = xcode_settings ._SdkRoot (configuration )
1679
1684
if not sdk_root :
1680
1685
sdk_root = xcode_settings ._XcodeSdkPath ('' )
0 commit comments