xref: /aosp_15_r20/external/clang/update-prebuilts.py (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li#!/usr/bin/env python
2*67e74705SXin Li#
3*67e74705SXin Li# Copyright (C) 2015 The Android Open Source Project
4*67e74705SXin Li#
5*67e74705SXin Li# Licensed under the Apache License, Version 2.0 (the "License");
6*67e74705SXin Li# you may not use this file except in compliance with the License.
7*67e74705SXin Li# You may obtain a copy of the License at
8*67e74705SXin Li#
9*67e74705SXin Li#      http://www.apache.org/licenses/LICENSE-2.0
10*67e74705SXin Li#
11*67e74705SXin Li# Unless required by applicable law or agreed to in writing, software
12*67e74705SXin Li# distributed under the License is distributed on an "AS IS" BASIS,
13*67e74705SXin Li# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*67e74705SXin Li# See the License for the specific language governing permissions and
15*67e74705SXin Li# limitations under the License.
16*67e74705SXin Li#
17*67e74705SXin Li
18*67e74705SXin Li"""Update the prebuilt clang from the build server."""
19*67e74705SXin Lifrom __future__ import print_function
20*67e74705SXin Li
21*67e74705SXin Liimport argparse
22*67e74705SXin Liimport inspect
23*67e74705SXin Liimport os
24*67e74705SXin Liimport shutil
25*67e74705SXin Liimport subprocess
26*67e74705SXin Liimport sys
27*67e74705SXin Li
28*67e74705SXin Li
29*67e74705SXin LiTHIS_DIR = os.path.realpath(os.path.dirname(__name__))
30*67e74705SXin LiANDROID_DIR = os.path.realpath(os.path.join(THIS_DIR, '../..'))
31*67e74705SXin Li
32*67e74705SXin LiBRANCH = 'aosp-llvm'
33*67e74705SXin Li
34*67e74705SXin Li
35*67e74705SXin Lidef android_path(*args):
36*67e74705SXin Li    return os.path.join(ANDROID_DIR, *args)
37*67e74705SXin Li
38*67e74705SXin Li
39*67e74705SXin Liclass ArgParser(argparse.ArgumentParser):
40*67e74705SXin Li    def __init__(self):
41*67e74705SXin Li        super(ArgParser, self).__init__(
42*67e74705SXin Li            description=inspect.getdoc(sys.modules[__name__]))
43*67e74705SXin Li
44*67e74705SXin Li        self.add_argument(
45*67e74705SXin Li            'build', metavar='BUILD',
46*67e74705SXin Li            help='Build number to pull from the build server.')
47*67e74705SXin Li
48*67e74705SXin Li        self.add_argument(
49*67e74705SXin Li            '-b', '--bug', type=int,
50*67e74705SXin Li            help='Bug to reference in commit message.')
51*67e74705SXin Li
52*67e74705SXin Li        self.add_argument(
53*67e74705SXin Li            '--use-current-branch', action='store_true',
54*67e74705SXin Li            help='Do not repo start a new branch for the update.')
55*67e74705SXin Li
56*67e74705SXin Li
57*67e74705SXin Lidef host_to_build_host(host):
58*67e74705SXin Li    """Gets the build host name for an NDK host tag.
59*67e74705SXin Li
60*67e74705SXin Li    The Windows builds are done from Linux.
61*67e74705SXin Li    """
62*67e74705SXin Li    return {
63*67e74705SXin Li        'darwin': 'mac',
64*67e74705SXin Li        'linux': 'linux',
65*67e74705SXin Li        'windows': 'linux',
66*67e74705SXin Li    }[host]
67*67e74705SXin Li
68*67e74705SXin Li
69*67e74705SXin Lidef build_name(host):
70*67e74705SXin Li    """Gets the build name for a given host.
71*67e74705SXin Li
72*67e74705SXin Li    The build name is either "linux" or "darwin", with any Windows builds
73*67e74705SXin Li    coming from "linux".
74*67e74705SXin Li    """
75*67e74705SXin Li    return {
76*67e74705SXin Li        'darwin': 'darwin',
77*67e74705SXin Li        'linux': 'linux',
78*67e74705SXin Li        'windows': 'linux',
79*67e74705SXin Li    }[host]
80*67e74705SXin Li
81*67e74705SXin Li
82*67e74705SXin Lidef manifest_name(build_number):
83*67e74705SXin Li    """Returns the manifest file name for a given build.
84*67e74705SXin Li
85*67e74705SXin Li    >>> manifest_name('1234')
86*67e74705SXin Li    'manifest_1234.xml'
87*67e74705SXin Li    """
88*67e74705SXin Li    return 'manifest_{}.xml'.format(build_number)
89*67e74705SXin Li
90*67e74705SXin Li
91*67e74705SXin Lidef package_name(build_number, host):
92*67e74705SXin Li    """Returns the file name for a given package configuration.
93*67e74705SXin Li
94*67e74705SXin Li    >>> package_name('1234', 'linux')
95*67e74705SXin Li    'clang-1234-linux-x86.tar.bz2'
96*67e74705SXin Li    """
97*67e74705SXin Li    return 'clang-{}-{}-x86.tar.bz2'.format(build_number, host)
98*67e74705SXin Li
99*67e74705SXin Li
100*67e74705SXin Lidef download_build(host, build_number, download_dir):
101*67e74705SXin Li    filename = package_name(build_number, host)
102*67e74705SXin Li    return download_file(host, build_number, filename, download_dir)
103*67e74705SXin Li
104*67e74705SXin Li
105*67e74705SXin Lidef download_manifest(host, build_number, download_dir):
106*67e74705SXin Li    filename = manifest_name(build_number)
107*67e74705SXin Li    return download_file(host, build_number, filename, download_dir)
108*67e74705SXin Li
109*67e74705SXin Li
110*67e74705SXin Lidef download_file(host, build_number, pkg_name, download_dir):
111*67e74705SXin Li    url_base = 'https://android-build-uber.corp.google.com'
112*67e74705SXin Li    path = 'builds/{branch}-{build_host}-{build_name}/{build_num}'.format(
113*67e74705SXin Li        branch=BRANCH,
114*67e74705SXin Li        build_host=host_to_build_host(host),
115*67e74705SXin Li        build_name=build_name(host),
116*67e74705SXin Li        build_num=build_number)
117*67e74705SXin Li
118*67e74705SXin Li    url = '{}/{}/{}'.format(url_base, path, pkg_name)
119*67e74705SXin Li
120*67e74705SXin Li    TIMEOUT = '60'  # In seconds.
121*67e74705SXin Li    out_file_path = os.path.join(download_dir, pkg_name)
122*67e74705SXin Li    with open(out_file_path, 'w') as out_file:
123*67e74705SXin Li        print('Downloading {} to {}'.format(url, out_file_path))
124*67e74705SXin Li        subprocess.check_call(
125*67e74705SXin Li            ['sso_client', '--location', '--request_timeout', TIMEOUT, url],
126*67e74705SXin Li            stdout=out_file)
127*67e74705SXin Li    return out_file_path
128*67e74705SXin Li
129*67e74705SXin Li
130*67e74705SXin Lidef extract_package(package, install_dir):
131*67e74705SXin Li    cmd = ['tar', 'xf', package, '-C', install_dir]
132*67e74705SXin Li    print('Extracting {}...'.format(package))
133*67e74705SXin Li    subprocess.check_call(cmd)
134*67e74705SXin Li
135*67e74705SXin Li
136*67e74705SXin Lidef update_clang(host, build_number, use_current_branch, download_dir, bug):
137*67e74705SXin Li    host_tag = host + '-x86'
138*67e74705SXin Li    prebuilt_dir = android_path('prebuilts/clang/host', host_tag)
139*67e74705SXin Li    os.chdir(prebuilt_dir)
140*67e74705SXin Li
141*67e74705SXin Li    if not use_current_branch:
142*67e74705SXin Li        subprocess.check_call(
143*67e74705SXin Li            ['repo', 'start', 'update-clang-{}'.format(build_number), '.'])
144*67e74705SXin Li
145*67e74705SXin Li    package = download_build(host, build_number, download_dir)
146*67e74705SXin Li    manifest = download_manifest(host, build_number, download_dir)
147*67e74705SXin Li
148*67e74705SXin Li    install_subdir = 'clang-' + build_number
149*67e74705SXin Li    extract_package(package, prebuilt_dir)
150*67e74705SXin Li    shutil.copy(manifest, prebuilt_dir + '/' +  install_subdir)
151*67e74705SXin Li
152*67e74705SXin Li    print('Adding files to index...')
153*67e74705SXin Li    subprocess.check_call(['git', 'add', install_subdir])
154*67e74705SXin Li
155*67e74705SXin Li    version_file_path = os.path.join(install_subdir, 'AndroidVersion.txt')
156*67e74705SXin Li    with open(version_file_path) as version_file:
157*67e74705SXin Li        version = version_file.read().strip()
158*67e74705SXin Li
159*67e74705SXin Li    print('Committing update...')
160*67e74705SXin Li    message_lines = [
161*67e74705SXin Li        'Update prebuilt Clang to build {}.'.format(build_number),
162*67e74705SXin Li        '',
163*67e74705SXin Li        'Built from version {}.'.format(version),
164*67e74705SXin Li    ]
165*67e74705SXin Li    if bug is not None:
166*67e74705SXin Li        message_lines.append('')
167*67e74705SXin Li        message_lines.append('Bug: http://b/{}'.format(bug))
168*67e74705SXin Li    message = '\n'.join(message_lines)
169*67e74705SXin Li    subprocess.check_call(['git', 'commit', '-m', message])
170*67e74705SXin Li
171*67e74705SXin Li
172*67e74705SXin Lidef main():
173*67e74705SXin Li    args = ArgParser().parse_args()
174*67e74705SXin Li
175*67e74705SXin Li    download_dir = os.path.realpath('.download')
176*67e74705SXin Li    if os.path.isdir(download_dir):
177*67e74705SXin Li        shutil.rmtree(download_dir)
178*67e74705SXin Li    os.makedirs(download_dir)
179*67e74705SXin Li
180*67e74705SXin Li    try:
181*67e74705SXin Li        hosts = ('darwin', 'linux', 'windows')
182*67e74705SXin Li        for host in hosts:
183*67e74705SXin Li            update_clang(host, args.build, args.use_current_branch,
184*67e74705SXin Li                         download_dir, args.bug)
185*67e74705SXin Li    finally:
186*67e74705SXin Li        shutil.rmtree(download_dir)
187*67e74705SXin Li
188*67e74705SXin Li
189*67e74705SXin Liif __name__ == '__main__':
190*67e74705SXin Li    main()
191