1*58b9f456SAndroid Build Coastguard Worker#! /usr/bin/env python 2*58b9f456SAndroid Build Coastguard Worker# encoding: utf-8 3*58b9f456SAndroid Build Coastguard Worker 4*58b9f456SAndroid Build Coastguard Workerimport argparse 5*58b9f456SAndroid Build Coastguard Workerimport errno 6*58b9f456SAndroid Build Coastguard Workerimport logging 7*58b9f456SAndroid Build Coastguard Workerimport os 8*58b9f456SAndroid Build Coastguard Workerimport platform 9*58b9f456SAndroid Build Coastguard Workerimport re 10*58b9f456SAndroid Build Coastguard Workerimport sys 11*58b9f456SAndroid Build Coastguard Workerimport subprocess 12*58b9f456SAndroid Build Coastguard Workerimport tempfile 13*58b9f456SAndroid Build Coastguard Worker 14*58b9f456SAndroid Build Coastguard Workertry: 15*58b9f456SAndroid Build Coastguard Worker import winreg 16*58b9f456SAndroid Build Coastguard Workerexcept ImportError: 17*58b9f456SAndroid Build Coastguard Worker import _winreg as winreg 18*58b9f456SAndroid Build Coastguard Workertry: 19*58b9f456SAndroid Build Coastguard Worker import urllib.request as request 20*58b9f456SAndroid Build Coastguard Workerexcept ImportError: 21*58b9f456SAndroid Build Coastguard Worker import urllib as request 22*58b9f456SAndroid Build Coastguard Workertry: 23*58b9f456SAndroid Build Coastguard Worker import urllib.parse as parse 24*58b9f456SAndroid Build Coastguard Workerexcept ImportError: 25*58b9f456SAndroid Build Coastguard Worker import urlparse as parse 26*58b9f456SAndroid Build Coastguard Worker 27*58b9f456SAndroid Build Coastguard Workerclass EmptyLogger(object): 28*58b9f456SAndroid Build Coastguard Worker ''' 29*58b9f456SAndroid Build Coastguard Worker Provides an implementation that performs no logging 30*58b9f456SAndroid Build Coastguard Worker ''' 31*58b9f456SAndroid Build Coastguard Worker def debug(self, *k, **kw): 32*58b9f456SAndroid Build Coastguard Worker pass 33*58b9f456SAndroid Build Coastguard Worker def info(self, *k, **kw): 34*58b9f456SAndroid Build Coastguard Worker pass 35*58b9f456SAndroid Build Coastguard Worker def warn(self, *k, **kw): 36*58b9f456SAndroid Build Coastguard Worker pass 37*58b9f456SAndroid Build Coastguard Worker def error(self, *k, **kw): 38*58b9f456SAndroid Build Coastguard Worker pass 39*58b9f456SAndroid Build Coastguard Worker def critical(self, *k, **kw): 40*58b9f456SAndroid Build Coastguard Worker pass 41*58b9f456SAndroid Build Coastguard Worker def setLevel(self, *k, **kw): 42*58b9f456SAndroid Build Coastguard Worker pass 43*58b9f456SAndroid Build Coastguard Worker 44*58b9f456SAndroid Build Coastguard Workerurls = ( 45*58b9f456SAndroid Build Coastguard Worker 'http://downloads.sourceforge.net/project/mingw-w64/Toolchains%20' 46*58b9f456SAndroid Build Coastguard Worker 'targetting%20Win32/Personal%20Builds/mingw-builds/installer/' 47*58b9f456SAndroid Build Coastguard Worker 'repository.txt', 48*58b9f456SAndroid Build Coastguard Worker 'http://downloads.sourceforge.net/project/mingwbuilds/host-windows/' 49*58b9f456SAndroid Build Coastguard Worker 'repository.txt' 50*58b9f456SAndroid Build Coastguard Worker) 51*58b9f456SAndroid Build Coastguard Worker''' 52*58b9f456SAndroid Build Coastguard WorkerA list of mingw-build repositories 53*58b9f456SAndroid Build Coastguard Worker''' 54*58b9f456SAndroid Build Coastguard Worker 55*58b9f456SAndroid Build Coastguard Workerdef repository(urls = urls, log = EmptyLogger()): 56*58b9f456SAndroid Build Coastguard Worker ''' 57*58b9f456SAndroid Build Coastguard Worker Downloads and parse mingw-build repository files and parses them 58*58b9f456SAndroid Build Coastguard Worker ''' 59*58b9f456SAndroid Build Coastguard Worker log.info('getting mingw-builds repository') 60*58b9f456SAndroid Build Coastguard Worker versions = {} 61*58b9f456SAndroid Build Coastguard Worker re_sourceforge = re.compile(r'http://sourceforge.net/projects/([^/]+)/files') 62*58b9f456SAndroid Build Coastguard Worker re_sub = r'http://downloads.sourceforge.net/project/\1' 63*58b9f456SAndroid Build Coastguard Worker for url in urls: 64*58b9f456SAndroid Build Coastguard Worker log.debug(' - requesting: %s', url) 65*58b9f456SAndroid Build Coastguard Worker socket = request.urlopen(url) 66*58b9f456SAndroid Build Coastguard Worker repo = socket.read() 67*58b9f456SAndroid Build Coastguard Worker if not isinstance(repo, str): 68*58b9f456SAndroid Build Coastguard Worker repo = repo.decode(); 69*58b9f456SAndroid Build Coastguard Worker socket.close() 70*58b9f456SAndroid Build Coastguard Worker for entry in repo.split('\n')[:-1]: 71*58b9f456SAndroid Build Coastguard Worker value = entry.split('|') 72*58b9f456SAndroid Build Coastguard Worker version = tuple([int(n) for n in value[0].strip().split('.')]) 73*58b9f456SAndroid Build Coastguard Worker version = versions.setdefault(version, {}) 74*58b9f456SAndroid Build Coastguard Worker arch = value[1].strip() 75*58b9f456SAndroid Build Coastguard Worker if arch == 'x32': 76*58b9f456SAndroid Build Coastguard Worker arch = 'i686' 77*58b9f456SAndroid Build Coastguard Worker elif arch == 'x64': 78*58b9f456SAndroid Build Coastguard Worker arch = 'x86_64' 79*58b9f456SAndroid Build Coastguard Worker arch = version.setdefault(arch, {}) 80*58b9f456SAndroid Build Coastguard Worker threading = arch.setdefault(value[2].strip(), {}) 81*58b9f456SAndroid Build Coastguard Worker exceptions = threading.setdefault(value[3].strip(), {}) 82*58b9f456SAndroid Build Coastguard Worker revision = exceptions.setdefault(int(value[4].strip()[3:]), 83*58b9f456SAndroid Build Coastguard Worker re_sourceforge.sub(re_sub, value[5].strip())) 84*58b9f456SAndroid Build Coastguard Worker return versions 85*58b9f456SAndroid Build Coastguard Worker 86*58b9f456SAndroid Build Coastguard Workerdef find_in_path(file, path=None): 87*58b9f456SAndroid Build Coastguard Worker ''' 88*58b9f456SAndroid Build Coastguard Worker Attempts to find an executable in the path 89*58b9f456SAndroid Build Coastguard Worker ''' 90*58b9f456SAndroid Build Coastguard Worker if platform.system() == 'Windows': 91*58b9f456SAndroid Build Coastguard Worker file += '.exe' 92*58b9f456SAndroid Build Coastguard Worker if path is None: 93*58b9f456SAndroid Build Coastguard Worker path = os.environ.get('PATH', '') 94*58b9f456SAndroid Build Coastguard Worker if type(path) is type(''): 95*58b9f456SAndroid Build Coastguard Worker path = path.split(os.pathsep) 96*58b9f456SAndroid Build Coastguard Worker return list(filter(os.path.exists, 97*58b9f456SAndroid Build Coastguard Worker map(lambda dir, file=file: os.path.join(dir, file), path))) 98*58b9f456SAndroid Build Coastguard Worker 99*58b9f456SAndroid Build Coastguard Workerdef find_7zip(log = EmptyLogger()): 100*58b9f456SAndroid Build Coastguard Worker ''' 101*58b9f456SAndroid Build Coastguard Worker Attempts to find 7zip for unpacking the mingw-build archives 102*58b9f456SAndroid Build Coastguard Worker ''' 103*58b9f456SAndroid Build Coastguard Worker log.info('finding 7zip') 104*58b9f456SAndroid Build Coastguard Worker path = find_in_path('7z') 105*58b9f456SAndroid Build Coastguard Worker if not path: 106*58b9f456SAndroid Build Coastguard Worker key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\7-Zip') 107*58b9f456SAndroid Build Coastguard Worker path, _ = winreg.QueryValueEx(key, 'Path') 108*58b9f456SAndroid Build Coastguard Worker path = [os.path.join(path, '7z.exe')] 109*58b9f456SAndroid Build Coastguard Worker log.debug('found \'%s\'', path[0]) 110*58b9f456SAndroid Build Coastguard Worker return path[0] 111*58b9f456SAndroid Build Coastguard Worker 112*58b9f456SAndroid Build Coastguard Workerfind_7zip() 113*58b9f456SAndroid Build Coastguard Worker 114*58b9f456SAndroid Build Coastguard Workerdef unpack(archive, location, log = EmptyLogger()): 115*58b9f456SAndroid Build Coastguard Worker ''' 116*58b9f456SAndroid Build Coastguard Worker Unpacks a mingw-builds archive 117*58b9f456SAndroid Build Coastguard Worker ''' 118*58b9f456SAndroid Build Coastguard Worker sevenzip = find_7zip(log) 119*58b9f456SAndroid Build Coastguard Worker log.info('unpacking %s', os.path.basename(archive)) 120*58b9f456SAndroid Build Coastguard Worker cmd = [sevenzip, 'x', archive, '-o' + location, '-y'] 121*58b9f456SAndroid Build Coastguard Worker log.debug(' - %r', cmd) 122*58b9f456SAndroid Build Coastguard Worker with open(os.devnull, 'w') as devnull: 123*58b9f456SAndroid Build Coastguard Worker subprocess.check_call(cmd, stdout = devnull) 124*58b9f456SAndroid Build Coastguard Worker 125*58b9f456SAndroid Build Coastguard Workerdef download(url, location, log = EmptyLogger()): 126*58b9f456SAndroid Build Coastguard Worker ''' 127*58b9f456SAndroid Build Coastguard Worker Downloads and unpacks a mingw-builds archive 128*58b9f456SAndroid Build Coastguard Worker ''' 129*58b9f456SAndroid Build Coastguard Worker log.info('downloading MinGW') 130*58b9f456SAndroid Build Coastguard Worker log.debug(' - url: %s', url) 131*58b9f456SAndroid Build Coastguard Worker log.debug(' - location: %s', location) 132*58b9f456SAndroid Build Coastguard Worker 133*58b9f456SAndroid Build Coastguard Worker re_content = re.compile(r'attachment;[ \t]*filename=(")?([^"]*)(")?[\r\n]*') 134*58b9f456SAndroid Build Coastguard Worker 135*58b9f456SAndroid Build Coastguard Worker stream = request.urlopen(url) 136*58b9f456SAndroid Build Coastguard Worker try: 137*58b9f456SAndroid Build Coastguard Worker content = stream.getheader('Content-Disposition') or '' 138*58b9f456SAndroid Build Coastguard Worker except AttributeError: 139*58b9f456SAndroid Build Coastguard Worker content = stream.headers.getheader('Content-Disposition') or '' 140*58b9f456SAndroid Build Coastguard Worker matches = re_content.match(content) 141*58b9f456SAndroid Build Coastguard Worker if matches: 142*58b9f456SAndroid Build Coastguard Worker filename = matches.group(2) 143*58b9f456SAndroid Build Coastguard Worker else: 144*58b9f456SAndroid Build Coastguard Worker parsed = parse.urlparse(stream.geturl()) 145*58b9f456SAndroid Build Coastguard Worker filename = os.path.basename(parsed.path) 146*58b9f456SAndroid Build Coastguard Worker 147*58b9f456SAndroid Build Coastguard Worker try: 148*58b9f456SAndroid Build Coastguard Worker os.makedirs(location) 149*58b9f456SAndroid Build Coastguard Worker except OSError as e: 150*58b9f456SAndroid Build Coastguard Worker if e.errno == errno.EEXIST and os.path.isdir(location): 151*58b9f456SAndroid Build Coastguard Worker pass 152*58b9f456SAndroid Build Coastguard Worker else: 153*58b9f456SAndroid Build Coastguard Worker raise 154*58b9f456SAndroid Build Coastguard Worker 155*58b9f456SAndroid Build Coastguard Worker archive = os.path.join(location, filename) 156*58b9f456SAndroid Build Coastguard Worker with open(archive, 'wb') as out: 157*58b9f456SAndroid Build Coastguard Worker while True: 158*58b9f456SAndroid Build Coastguard Worker buf = stream.read(1024) 159*58b9f456SAndroid Build Coastguard Worker if not buf: 160*58b9f456SAndroid Build Coastguard Worker break 161*58b9f456SAndroid Build Coastguard Worker out.write(buf) 162*58b9f456SAndroid Build Coastguard Worker unpack(archive, location, log = log) 163*58b9f456SAndroid Build Coastguard Worker os.remove(archive) 164*58b9f456SAndroid Build Coastguard Worker 165*58b9f456SAndroid Build Coastguard Worker possible = os.path.join(location, 'mingw64') 166*58b9f456SAndroid Build Coastguard Worker if not os.path.exists(possible): 167*58b9f456SAndroid Build Coastguard Worker possible = os.path.join(location, 'mingw32') 168*58b9f456SAndroid Build Coastguard Worker if not os.path.exists(possible): 169*58b9f456SAndroid Build Coastguard Worker raise ValueError('Failed to find unpacked MinGW: ' + possible) 170*58b9f456SAndroid Build Coastguard Worker return possible 171*58b9f456SAndroid Build Coastguard Worker 172*58b9f456SAndroid Build Coastguard Workerdef root(location = None, arch = None, version = None, threading = None, 173*58b9f456SAndroid Build Coastguard Worker exceptions = None, revision = None, log = EmptyLogger()): 174*58b9f456SAndroid Build Coastguard Worker ''' 175*58b9f456SAndroid Build Coastguard Worker Returns the root folder of a specific version of the mingw-builds variant 176*58b9f456SAndroid Build Coastguard Worker of gcc. Will download the compiler if needed 177*58b9f456SAndroid Build Coastguard Worker ''' 178*58b9f456SAndroid Build Coastguard Worker 179*58b9f456SAndroid Build Coastguard Worker # Get the repository if we don't have all the information 180*58b9f456SAndroid Build Coastguard Worker if not (arch and version and threading and exceptions and revision): 181*58b9f456SAndroid Build Coastguard Worker versions = repository(log = log) 182*58b9f456SAndroid Build Coastguard Worker 183*58b9f456SAndroid Build Coastguard Worker # Determine some defaults 184*58b9f456SAndroid Build Coastguard Worker version = version or max(versions.keys()) 185*58b9f456SAndroid Build Coastguard Worker if not arch: 186*58b9f456SAndroid Build Coastguard Worker arch = platform.machine().lower() 187*58b9f456SAndroid Build Coastguard Worker if arch == 'x86': 188*58b9f456SAndroid Build Coastguard Worker arch = 'i686' 189*58b9f456SAndroid Build Coastguard Worker elif arch == 'amd64': 190*58b9f456SAndroid Build Coastguard Worker arch = 'x86_64' 191*58b9f456SAndroid Build Coastguard Worker if not threading: 192*58b9f456SAndroid Build Coastguard Worker keys = versions[version][arch].keys() 193*58b9f456SAndroid Build Coastguard Worker if 'posix' in keys: 194*58b9f456SAndroid Build Coastguard Worker threading = 'posix' 195*58b9f456SAndroid Build Coastguard Worker elif 'win32' in keys: 196*58b9f456SAndroid Build Coastguard Worker threading = 'win32' 197*58b9f456SAndroid Build Coastguard Worker else: 198*58b9f456SAndroid Build Coastguard Worker threading = keys[0] 199*58b9f456SAndroid Build Coastguard Worker if not exceptions: 200*58b9f456SAndroid Build Coastguard Worker keys = versions[version][arch][threading].keys() 201*58b9f456SAndroid Build Coastguard Worker if 'seh' in keys: 202*58b9f456SAndroid Build Coastguard Worker exceptions = 'seh' 203*58b9f456SAndroid Build Coastguard Worker elif 'sjlj' in keys: 204*58b9f456SAndroid Build Coastguard Worker exceptions = 'sjlj' 205*58b9f456SAndroid Build Coastguard Worker else: 206*58b9f456SAndroid Build Coastguard Worker exceptions = keys[0] 207*58b9f456SAndroid Build Coastguard Worker if revision == None: 208*58b9f456SAndroid Build Coastguard Worker revision = max(versions[version][arch][threading][exceptions].keys()) 209*58b9f456SAndroid Build Coastguard Worker if not location: 210*58b9f456SAndroid Build Coastguard Worker location = os.path.join(tempfile.gettempdir(), 'mingw-builds') 211*58b9f456SAndroid Build Coastguard Worker 212*58b9f456SAndroid Build Coastguard Worker # Get the download url 213*58b9f456SAndroid Build Coastguard Worker url = versions[version][arch][threading][exceptions][revision] 214*58b9f456SAndroid Build Coastguard Worker 215*58b9f456SAndroid Build Coastguard Worker # Tell the user whatzzup 216*58b9f456SAndroid Build Coastguard Worker log.info('finding MinGW %s', '.'.join(str(v) for v in version)) 217*58b9f456SAndroid Build Coastguard Worker log.debug(' - arch: %s', arch) 218*58b9f456SAndroid Build Coastguard Worker log.debug(' - threading: %s', threading) 219*58b9f456SAndroid Build Coastguard Worker log.debug(' - exceptions: %s', exceptions) 220*58b9f456SAndroid Build Coastguard Worker log.debug(' - revision: %s', revision) 221*58b9f456SAndroid Build Coastguard Worker log.debug(' - url: %s', url) 222*58b9f456SAndroid Build Coastguard Worker 223*58b9f456SAndroid Build Coastguard Worker # Store each specific revision differently 224*58b9f456SAndroid Build Coastguard Worker slug = '{version}-{arch}-{threading}-{exceptions}-rev{revision}' 225*58b9f456SAndroid Build Coastguard Worker slug = slug.format( 226*58b9f456SAndroid Build Coastguard Worker version = '.'.join(str(v) for v in version), 227*58b9f456SAndroid Build Coastguard Worker arch = arch, 228*58b9f456SAndroid Build Coastguard Worker threading = threading, 229*58b9f456SAndroid Build Coastguard Worker exceptions = exceptions, 230*58b9f456SAndroid Build Coastguard Worker revision = revision 231*58b9f456SAndroid Build Coastguard Worker ) 232*58b9f456SAndroid Build Coastguard Worker if arch == 'x86_64': 233*58b9f456SAndroid Build Coastguard Worker root_dir = os.path.join(location, slug, 'mingw64') 234*58b9f456SAndroid Build Coastguard Worker elif arch == 'i686': 235*58b9f456SAndroid Build Coastguard Worker root_dir = os.path.join(location, slug, 'mingw32') 236*58b9f456SAndroid Build Coastguard Worker else: 237*58b9f456SAndroid Build Coastguard Worker raise ValueError('Unknown MinGW arch: ' + arch) 238*58b9f456SAndroid Build Coastguard Worker 239*58b9f456SAndroid Build Coastguard Worker # Download if needed 240*58b9f456SAndroid Build Coastguard Worker if not os.path.exists(root_dir): 241*58b9f456SAndroid Build Coastguard Worker downloaded = download(url, os.path.join(location, slug), log = log) 242*58b9f456SAndroid Build Coastguard Worker if downloaded != root_dir: 243*58b9f456SAndroid Build Coastguard Worker raise ValueError('The location of mingw did not match\n%s\n%s' 244*58b9f456SAndroid Build Coastguard Worker % (downloaded, root_dir)) 245*58b9f456SAndroid Build Coastguard Worker 246*58b9f456SAndroid Build Coastguard Worker return root_dir 247*58b9f456SAndroid Build Coastguard Worker 248*58b9f456SAndroid Build Coastguard Workerdef str2ver(string): 249*58b9f456SAndroid Build Coastguard Worker ''' 250*58b9f456SAndroid Build Coastguard Worker Converts a version string into a tuple 251*58b9f456SAndroid Build Coastguard Worker ''' 252*58b9f456SAndroid Build Coastguard Worker try: 253*58b9f456SAndroid Build Coastguard Worker version = tuple(int(v) for v in string.split('.')) 254*58b9f456SAndroid Build Coastguard Worker if len(version) is not 3: 255*58b9f456SAndroid Build Coastguard Worker raise ValueError() 256*58b9f456SAndroid Build Coastguard Worker except ValueError: 257*58b9f456SAndroid Build Coastguard Worker raise argparse.ArgumentTypeError( 258*58b9f456SAndroid Build Coastguard Worker 'please provide a three digit version string') 259*58b9f456SAndroid Build Coastguard Worker return version 260*58b9f456SAndroid Build Coastguard Worker 261*58b9f456SAndroid Build Coastguard Workerdef main(): 262*58b9f456SAndroid Build Coastguard Worker ''' 263*58b9f456SAndroid Build Coastguard Worker Invoked when the script is run directly by the python interpreter 264*58b9f456SAndroid Build Coastguard Worker ''' 265*58b9f456SAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 266*58b9f456SAndroid Build Coastguard Worker description = 'Downloads a specific version of MinGW', 267*58b9f456SAndroid Build Coastguard Worker formatter_class = argparse.ArgumentDefaultsHelpFormatter 268*58b9f456SAndroid Build Coastguard Worker ) 269*58b9f456SAndroid Build Coastguard Worker parser.add_argument('--location', 270*58b9f456SAndroid Build Coastguard Worker help = 'the location to download the compiler to', 271*58b9f456SAndroid Build Coastguard Worker default = os.path.join(tempfile.gettempdir(), 'mingw-builds')) 272*58b9f456SAndroid Build Coastguard Worker parser.add_argument('--arch', required = True, choices = ['i686', 'x86_64'], 273*58b9f456SAndroid Build Coastguard Worker help = 'the target MinGW architecture string') 274*58b9f456SAndroid Build Coastguard Worker parser.add_argument('--version', type = str2ver, 275*58b9f456SAndroid Build Coastguard Worker help = 'the version of GCC to download') 276*58b9f456SAndroid Build Coastguard Worker parser.add_argument('--threading', choices = ['posix', 'win32'], 277*58b9f456SAndroid Build Coastguard Worker help = 'the threading type of the compiler') 278*58b9f456SAndroid Build Coastguard Worker parser.add_argument('--exceptions', choices = ['sjlj', 'seh', 'dwarf'], 279*58b9f456SAndroid Build Coastguard Worker help = 'the method to throw exceptions') 280*58b9f456SAndroid Build Coastguard Worker parser.add_argument('--revision', type=int, 281*58b9f456SAndroid Build Coastguard Worker help = 'the revision of the MinGW release') 282*58b9f456SAndroid Build Coastguard Worker group = parser.add_mutually_exclusive_group() 283*58b9f456SAndroid Build Coastguard Worker group.add_argument('-v', '--verbose', action='store_true', 284*58b9f456SAndroid Build Coastguard Worker help='increase the script output verbosity') 285*58b9f456SAndroid Build Coastguard Worker group.add_argument('-q', '--quiet', action='store_true', 286*58b9f456SAndroid Build Coastguard Worker help='only print errors and warning') 287*58b9f456SAndroid Build Coastguard Worker args = parser.parse_args() 288*58b9f456SAndroid Build Coastguard Worker 289*58b9f456SAndroid Build Coastguard Worker # Create the logger 290*58b9f456SAndroid Build Coastguard Worker logger = logging.getLogger('mingw') 291*58b9f456SAndroid Build Coastguard Worker handler = logging.StreamHandler() 292*58b9f456SAndroid Build Coastguard Worker formatter = logging.Formatter('%(message)s') 293*58b9f456SAndroid Build Coastguard Worker handler.setFormatter(formatter) 294*58b9f456SAndroid Build Coastguard Worker logger.addHandler(handler) 295*58b9f456SAndroid Build Coastguard Worker logger.setLevel(logging.INFO) 296*58b9f456SAndroid Build Coastguard Worker if args.quiet: 297*58b9f456SAndroid Build Coastguard Worker logger.setLevel(logging.WARN) 298*58b9f456SAndroid Build Coastguard Worker if args.verbose: 299*58b9f456SAndroid Build Coastguard Worker logger.setLevel(logging.DEBUG) 300*58b9f456SAndroid Build Coastguard Worker 301*58b9f456SAndroid Build Coastguard Worker # Get MinGW 302*58b9f456SAndroid Build Coastguard Worker root_dir = root(location = args.location, arch = args.arch, 303*58b9f456SAndroid Build Coastguard Worker version = args.version, threading = args.threading, 304*58b9f456SAndroid Build Coastguard Worker exceptions = args.exceptions, revision = args.revision, 305*58b9f456SAndroid Build Coastguard Worker log = logger) 306*58b9f456SAndroid Build Coastguard Worker 307*58b9f456SAndroid Build Coastguard Worker sys.stdout.write('%s\n' % os.path.join(root_dir, 'bin')) 308*58b9f456SAndroid Build Coastguard Worker 309*58b9f456SAndroid Build Coastguard Workerif __name__ == '__main__': 310*58b9f456SAndroid Build Coastguard Worker try: 311*58b9f456SAndroid Build Coastguard Worker main() 312*58b9f456SAndroid Build Coastguard Worker except IOError as e: 313*58b9f456SAndroid Build Coastguard Worker sys.stderr.write('IO error: %s\n' % e) 314*58b9f456SAndroid Build Coastguard Worker sys.exit(1) 315*58b9f456SAndroid Build Coastguard Worker except OSError as e: 316*58b9f456SAndroid Build Coastguard Worker sys.stderr.write('OS error: %s\n' % e) 317*58b9f456SAndroid Build Coastguard Worker sys.exit(1) 318*58b9f456SAndroid Build Coastguard Worker except KeyboardInterrupt as e: 319*58b9f456SAndroid Build Coastguard Worker sys.stderr.write('Killed\n') 320*58b9f456SAndroid Build Coastguard Worker sys.exit(1) 321