xref: /aosp_15_r20/external/libcxx/utils/google-benchmark/mingw.py (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
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