1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*6777b538SAndroid Build Coastguard Worker# Copyright 2012 The Chromium Authors 3*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file. 5*6777b538SAndroid Build Coastguard Workerr"""Prints the lowest locally available SDK version greater than or equal to a 6*6777b538SAndroid Build Coastguard Workergiven minimum sdk version to standard output. 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard WorkerIf --print_sdk_path is passed, then the script will also print the SDK path. 9*6777b538SAndroid Build Coastguard WorkerIf --print_bin_path is passed, then the script will also print the path to the 10*6777b538SAndroid Build Coastguard Workertoolchain bin dir. 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard WorkerUsage: 13*6777b538SAndroid Build Coastguard Worker python find_sdk.py \ 14*6777b538SAndroid Build Coastguard Worker [--print_sdk_path] \ 15*6777b538SAndroid Build Coastguard Worker [--print_bin_path] \ 16*6777b538SAndroid Build Coastguard Worker 10.6 # Ignores SDKs < 10.6 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard WorkerSample Output: 19*6777b538SAndroid Build Coastguard Worker/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk 20*6777b538SAndroid Build Coastguard Worker/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ 21*6777b538SAndroid Build Coastguard Worker10.14 22*6777b538SAndroid Build Coastguard Worker""" 23*6777b538SAndroid Build Coastguard Worker 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Workerimport os 26*6777b538SAndroid Build Coastguard Workerimport plistlib 27*6777b538SAndroid Build Coastguard Workerimport re 28*6777b538SAndroid Build Coastguard Workerimport subprocess 29*6777b538SAndroid Build Coastguard Workerimport sys 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Workerfrom optparse import OptionParser 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard Worker 34*6777b538SAndroid Build Coastguard Workerclass SdkError(Exception): 35*6777b538SAndroid Build Coastguard Worker def __init__(self, value): 36*6777b538SAndroid Build Coastguard Worker self.value = value 37*6777b538SAndroid Build Coastguard Worker def __str__(self): 38*6777b538SAndroid Build Coastguard Worker return repr(self.value) 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Workerdef parse_version(version_str): 42*6777b538SAndroid Build Coastguard Worker """'10.6' => [10, 6]""" 43*6777b538SAndroid Build Coastguard Worker return [int(s) for s in re.findall(r'(\d+)', version_str)] 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker 46*6777b538SAndroid Build Coastguard Workerdef main(): 47*6777b538SAndroid Build Coastguard Worker parser = OptionParser() 48*6777b538SAndroid Build Coastguard Worker parser.add_option("--print_sdk_path", 49*6777b538SAndroid Build Coastguard Worker action="store_true", dest="print_sdk_path", default=False, 50*6777b538SAndroid Build Coastguard Worker help="Additionally print the path the SDK (appears first).") 51*6777b538SAndroid Build Coastguard Worker parser.add_option("--print_bin_path", 52*6777b538SAndroid Build Coastguard Worker action="store_true", dest="print_bin_path", default=False, 53*6777b538SAndroid Build Coastguard Worker help="Additionally print the path the toolchain bin dir.") 54*6777b538SAndroid Build Coastguard Worker parser.add_option("--print_sdk_build", 55*6777b538SAndroid Build Coastguard Worker action="store_true", dest="print_sdk_build", default=False, 56*6777b538SAndroid Build Coastguard Worker help="Additionally print the build version of the SDK.") 57*6777b538SAndroid Build Coastguard Worker options, args = parser.parse_args() 58*6777b538SAndroid Build Coastguard Worker if len(args) != 1: 59*6777b538SAndroid Build Coastguard Worker parser.error('Please specify a minimum SDK version') 60*6777b538SAndroid Build Coastguard Worker min_sdk_version = args[0] 61*6777b538SAndroid Build Coastguard Worker 62*6777b538SAndroid Build Coastguard Worker 63*6777b538SAndroid Build Coastguard Worker job = subprocess.Popen(['xcode-select', '-print-path'], 64*6777b538SAndroid Build Coastguard Worker stdout=subprocess.PIPE, 65*6777b538SAndroid Build Coastguard Worker stderr=subprocess.STDOUT) 66*6777b538SAndroid Build Coastguard Worker out, err = job.communicate() 67*6777b538SAndroid Build Coastguard Worker if job.returncode != 0: 68*6777b538SAndroid Build Coastguard Worker print(out, file=sys.stderr) 69*6777b538SAndroid Build Coastguard Worker print(err, file=sys.stderr) 70*6777b538SAndroid Build Coastguard Worker raise Exception('Error %d running xcode-select' % job.returncode) 71*6777b538SAndroid Build Coastguard Worker dev_dir = out.decode('UTF-8').rstrip() 72*6777b538SAndroid Build Coastguard Worker sdk_dir = os.path.join( 73*6777b538SAndroid Build Coastguard Worker dev_dir, 'Platforms/MacOSX.platform/Developer/SDKs') 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker if not os.path.isdir(sdk_dir): 76*6777b538SAndroid Build Coastguard Worker raise SdkError('Install Xcode, launch it, accept the license ' + 77*6777b538SAndroid Build Coastguard Worker 'agreement, and run `sudo xcode-select -s /path/to/Xcode.app` ' + 78*6777b538SAndroid Build Coastguard Worker 'to continue.') 79*6777b538SAndroid Build Coastguard Worker sdks = [re.findall('^MacOSX(\d+\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)] 80*6777b538SAndroid Build Coastguard Worker sdks = [s[0] for s in sdks if s] # [['10.5'], ['10.6']] => ['10.5', '10.6'] 81*6777b538SAndroid Build Coastguard Worker sdks = [s for s in sdks # ['10.5', '10.6'] => ['10.6'] 82*6777b538SAndroid Build Coastguard Worker if parse_version(s) >= parse_version(min_sdk_version)] 83*6777b538SAndroid Build Coastguard Worker if not sdks: 84*6777b538SAndroid Build Coastguard Worker raise Exception('No %s+ SDK found' % min_sdk_version) 85*6777b538SAndroid Build Coastguard Worker best_sdk = sorted(sdks, key=parse_version)[0] 86*6777b538SAndroid Build Coastguard Worker sdk_name = 'MacOSX' + best_sdk + '.sdk' 87*6777b538SAndroid Build Coastguard Worker sdk_path = os.path.join(sdk_dir, sdk_name) 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker if options.print_sdk_path: 90*6777b538SAndroid Build Coastguard Worker print(sdk_path) 91*6777b538SAndroid Build Coastguard Worker 92*6777b538SAndroid Build Coastguard Worker if options.print_bin_path: 93*6777b538SAndroid Build Coastguard Worker bin_path = 'Toolchains/XcodeDefault.xctoolchain/usr/bin/' 94*6777b538SAndroid Build Coastguard Worker print(os.path.join(dev_dir, bin_path)) 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker if options.print_sdk_build: 97*6777b538SAndroid Build Coastguard Worker system_version_plist = os.path.join(sdk_path, 98*6777b538SAndroid Build Coastguard Worker 'System/Library/CoreServices/SystemVersion.plist') 99*6777b538SAndroid Build Coastguard Worker with open(system_version_plist, 'rb') as f: 100*6777b538SAndroid Build Coastguard Worker system_version_info = plistlib.load(f) 101*6777b538SAndroid Build Coastguard Worker if 'ProductBuildVersion' not in system_version_info: 102*6777b538SAndroid Build Coastguard Worker raise Exception('Failed to determine ProductBuildVersion' + 103*6777b538SAndroid Build Coastguard Worker 'for SDK at path %s' % system_version_plist) 104*6777b538SAndroid Build Coastguard Worker print(system_version_info['ProductBuildVersion']) 105*6777b538SAndroid Build Coastguard Worker 106*6777b538SAndroid Build Coastguard Worker print(best_sdk) 107*6777b538SAndroid Build Coastguard Worker 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__': 110*6777b538SAndroid Build Coastguard Worker if sys.platform != 'darwin': 111*6777b538SAndroid Build Coastguard Worker raise Exception("This script only runs on Mac") 112*6777b538SAndroid Build Coastguard Worker sys.exit(main()) 113