2020import tempfile
2121from gyp .common import GypError
2222
23+ PY3 = bytes != str
24+
2325# Populated lazily by XcodeVersion, for efficiency, and to fix an issue when
2426# "xcodebuild" is called too quickly (it has been found to return incorrect
2527# version number).
@@ -498,7 +500,7 @@ def _GetSdkVersionInfoItem(self, sdk, infoitem):
498500# most sensible route and should still do the right thing.
499501try :
500502return GetStdoutQuiet (['xcrun' , '--sdk' , sdk , infoitem ])
501- except :
503+ except GypError :
502504pass
503505
504506def _SdkRoot (self , configname ):
@@ -928,7 +930,8 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None):
928930# extensions and provide loader and main function.
929931# These flags reflect the compilation options used by xcode to compile
930932# extensions.
931- if XcodeVersion () < '0900' :
933+ xcode_version , _ = XcodeVersion ()
934+ if xcode_version < '0900' :
932935ldflags .append ('-lpkstart' )
933936ldflags .append (sdk_root +
934937'/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit' )
@@ -1204,8 +1207,8 @@ def GetExtraPlistItems(self, configname=None):
12041207cache = {}
12051208cache ['BuildMachineOSBuild' ] = self ._BuildMachineOSBuild ()
12061209
1207- xcode , xcode_build = XcodeVersion ()
1208- cache ['DTXcode' ] = xcode
1210+ xcode_version , xcode_build = XcodeVersion ()
1211+ cache ['DTXcode' ] = xcode_version
12091212cache ['DTXcodeBuild' ] = xcode_build
12101213compiler = self .xcode_settings [configname ].get ('GCC_VERSION' )
12111214if compiler is not None :
@@ -1216,10 +1219,10 @@ def GetExtraPlistItems(self, configname=None):
12161219sdk_root = self ._DefaultSdkRoot ()
12171220sdk_version = self ._GetSdkVersionInfoItem (sdk_root , '--show-sdk-version' )
12181221cache ['DTSDKName' ] = sdk_root + (sdk_version or '' )
1219- if xcode >= '0720' :
1222+ if xcode_version >= '0720' :
12201223cache ['DTSDKBuild' ] = self ._GetSdkVersionInfoItem (
12211224sdk_root , '--show-sdk-build-version' )
1222- elif xcode >= '0430' :
1225+ elif xcode_version >= '0430' :
12231226cache ['DTSDKBuild' ] = sdk_version
12241227else :
12251228cache ['DTSDKBuild' ] = cache ['BuildMachineOSBuild' ]
@@ -1254,7 +1257,7 @@ def _DefaultSdkRoot(self):
12541257 project, then the environment variable was empty. Starting with this
12551258 version, Xcode uses the name of the newest SDK installed.
12561259 """
1257- xcode_version , xcode_build = XcodeVersion ()
1260+ xcode_version , _ = XcodeVersion ()
12581261if xcode_version < '0500' :
12591262return ''
12601263default_sdk_path = self ._XcodeSdkPath ('' )
@@ -1263,7 +1266,7 @@ def _DefaultSdkRoot(self):
12631266return default_sdk_root
12641267try :
12651268all_sdks = GetStdout (['xcodebuild' , '-showsdks' ])
1266- except :
1269+ except GypError :
12671270# If xcodebuild fails, there will be no valid SDKs
12681271return ''
12691272for line in all_sdks .splitlines ():
@@ -1391,10 +1394,12 @@ def XcodeVersion():
13911394# Xcode 3.2.6
13921395# Component versions: DevToolsCore-1809.0; DevToolsSupport-1806.0
13931396# BuildVersion: 10M2518
1394- # Convert that to '0463', '4H1503'.
1397+ # Convert that to ( '0463', '4H1503') or ('0326', '10M2518') .
13951398global XCODE_VERSION_CACHE
13961399if XCODE_VERSION_CACHE :
13971400return XCODE_VERSION_CACHE
1401+ version = ""
1402+ build = ""
13981403try :
13991404version_list = GetStdoutQuiet (['xcodebuild' , '-version' ]).splitlines ()
14001405# In some circumstances xcodebuild exits 0 but doesn't return
@@ -1404,21 +1409,16 @@ def XcodeVersion():
14041409# checking that version.
14051410if len (version_list ) < 2 :
14061411raise 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 :
14121417raise 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
14221422XCODE_VERSION_CACHE = (version , build )
14231423return XCODE_VERSION_CACHE
14241424
@@ -1442,7 +1442,7 @@ def CLTVersion():
14421442try :
14431443output = GetStdout (['/usr/sbin/pkgutil' , '--pkg-info' , key ])
14441444return re .search (regex , output ).groupdict ()['version' ]
1445- except :
1445+ except GypError :
14461446continue
14471447
14481448
@@ -1453,6 +1453,8 @@ def GetStdoutQuiet(cmdlist):
14531453job = subprocess .Popen (cmdlist , stdout = subprocess .PIPE ,
14541454stderr = subprocess .PIPE )
14551455out = job .communicate ()[0 ]
1456+ if PY3 :
1457+ out = out .decode ("utf-8" )
14561458if job .returncode != 0 :
14571459raise GypError ('Error %d running %s' % (job .returncode , cmdlist [0 ]))
14581460return out .rstrip ('\n ' )
@@ -1463,6 +1465,8 @@ def GetStdout(cmdlist):
14631465 Raises |GypError| if the command return with a non-zero return code."""
14641466job = subprocess .Popen (cmdlist , stdout = subprocess .PIPE )
14651467out = job .communicate ()[0 ]
1468+ if PY3 :
1469+ out = out .decode ("utf-8" )
14661470if job .returncode != 0 :
14671471sys .stderr .write (out + '\n ' )
14681472raise GypError ('Error %d running %s' % (job .returncode , cmdlist [0 ]))
@@ -1674,7 +1678,8 @@ def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration,
16741678install_name_base = xcode_settings .GetInstallNameBase ()
16751679if install_name_base :
16761680env ['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' ):
16781683sdk_root = xcode_settings ._SdkRoot (configuration )
16791684if not sdk_root :
16801685sdk_root = xcode_settings ._XcodeSdkPath ('' )
0 commit comments