blob: cd0fcfd0272618fbdf426bac0e0bb5d5cf04aa2f [file] [log] [blame]
Inseob Kimb462b9c2020-08-11 15:38:20 +09001#!/usr/bin/env python3
Jae Shinca625dd2017-11-30 15:58:00 +09002#
3# Copyright (C) 2017 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17"""Installs VNDK snapshot under prebuilts/vndk/v{version}."""
18
19import argparse
20import glob
21import logging
22import os
Jae Shin6e1a7962017-12-26 13:12:38 +090023import re
Jae Shinca625dd2017-11-30 15:58:00 +090024import shutil
25import subprocess
26import sys
27import tempfile
28import textwrap
29
Jae Shin5233fe12017-12-18 22:29:48 +090030import utils
31
32from check_gpl_license import GPLChecker
Jae Shinca625dd2017-11-30 15:58:00 +090033from gen_buildfiles import GenBuildFile
34
Jae Shin5233fe12017-12-18 22:29:48 +090035ANDROID_BUILD_TOP = utils.get_android_build_top()
Jae Shin5233fe12017-12-18 22:29:48 +090036PREBUILTS_VNDK_DIR = utils.join_realpath(ANDROID_BUILD_TOP, 'prebuilts/vndk')
Jae Shinca625dd2017-11-30 15:58:00 +090037
Jae Shinca625dd2017-11-30 15:58:00 +090038
Jae Shinca625dd2017-11-30 15:58:00 +090039def start_branch(build):
40 branch_name = 'update-' + (build or 'local')
Jae Shinbd82ebb2018-06-21 14:13:46 +090041 logging.info('Creating branch {branch} in {dir}'.format(
Jae Shinca625dd2017-11-30 15:58:00 +090042 branch=branch_name, dir=os.getcwd()))
Jae Shinbd82ebb2018-06-21 14:13:46 +090043 utils.check_call(['repo', 'start', branch_name, '.'])
Jae Shinca625dd2017-11-30 15:58:00 +090044
45
46def remove_old_snapshot(install_dir):
Jae Shinbd82ebb2018-06-21 14:13:46 +090047 logging.info('Removing any old files in {}'.format(install_dir))
Jae Shinca625dd2017-11-30 15:58:00 +090048 for file in glob.glob('{}/*'.format(install_dir)):
49 try:
50 if os.path.isfile(file):
51 os.unlink(file)
52 elif os.path.isdir(file):
53 shutil.rmtree(file)
54 except Exception as error:
Jae Shinbd82ebb2018-06-21 14:13:46 +090055 logging.error('Error: {}'.format(error))
Jae Shinca625dd2017-11-30 15:58:00 +090056 sys.exit(1)
57
58
Jae Shin01268ff2018-06-18 15:29:09 +090059def install_snapshot(branch, build, local_dir, install_dir, temp_artifact_dir):
Jae Shinba7456d2017-12-15 20:03:20 +090060 """Installs VNDK snapshot build artifacts to prebuilts/vndk/v{version}.
61
Jae Shin01268ff2018-06-18 15:29:09 +090062 1) Fetch build artifacts from Android Build server or from local_dir
Jae Shinba7456d2017-12-15 20:03:20 +090063 2) Unzip build artifacts
64
65 Args:
66 branch: string or None, branch name of build artifacts
67 build: string or None, build number of build artifacts
Jae Shin01268ff2018-06-18 15:29:09 +090068 local_dir: string or None, local dir to pull artifacts from
Jae Shinba7456d2017-12-15 20:03:20 +090069 install_dir: string, directory to install VNDK snapshot
Jae Shin25d3abf2018-04-18 18:00:26 +090070 temp_artifact_dir: string, temp directory to hold build artifacts fetched
71 from Android Build server. For 'local' option, is set to None.
Jae Shinba7456d2017-12-15 20:03:20 +090072 """
Jae Shinca625dd2017-11-30 15:58:00 +090073 artifact_pattern = 'android-vndk-*.zip'
74
Jae Shin25d3abf2018-04-18 18:00:26 +090075 if branch and build:
76 artifact_dir = temp_artifact_dir
77 os.chdir(temp_artifact_dir)
Jae Shinbd82ebb2018-06-21 14:13:46 +090078 logging.info('Fetching {pattern} from {branch} (bid: {build})'.format(
Jae Shin25d3abf2018-04-18 18:00:26 +090079 pattern=artifact_pattern, branch=branch, build=build))
80 utils.fetch_artifact(branch, build, artifact_pattern)
Jae Shinca625dd2017-11-30 15:58:00 +090081
Jae Shin25d3abf2018-04-18 18:00:26 +090082 manifest_pattern = 'manifest_{}.xml'.format(build)
Jae Shinbd82ebb2018-06-21 14:13:46 +090083 logging.info('Fetching {file} from {branch} (bid: {build})'.format(
Jae Shin25d3abf2018-04-18 18:00:26 +090084 file=manifest_pattern, branch=branch, build=build))
85 utils.fetch_artifact(branch, build, manifest_pattern,
86 utils.MANIFEST_FILE_NAME)
Jae Shinca625dd2017-11-30 15:58:00 +090087
Jae Shin25d3abf2018-04-18 18:00:26 +090088 os.chdir(install_dir)
Jae Shin01268ff2018-06-18 15:29:09 +090089 elif local_dir:
Jae Shinbd82ebb2018-06-21 14:13:46 +090090 logging.info('Fetching local VNDK snapshot from {}'.format(local_dir))
Jae Shin01268ff2018-06-18 15:29:09 +090091 artifact_dir = local_dir
Jae Shinca625dd2017-11-30 15:58:00 +090092
Jae Shin25d3abf2018-04-18 18:00:26 +090093 artifacts = glob.glob(os.path.join(artifact_dir, artifact_pattern))
Jae Shin25d3abf2018-04-18 18:00:26 +090094 for artifact in artifacts:
Jae Shinbd82ebb2018-06-21 14:13:46 +090095 logging.info('Unzipping VNDK snapshot: {}'.format(artifact))
96 utils.check_call(['unzip', '-qn', artifact, '-d', install_dir])
Jae Shinca625dd2017-11-30 15:58:00 +090097
Inseob Kimdeb5beb2021-09-24 13:17:06 +090098 # rename {install_dir}/{arch}/include/out/soong/.intermediates
99 for soong_intermediates_dir in glob.glob(install_dir + '/*/include/' + utils.SOONG_INTERMEDIATES_DIR):
100 generated_headers_dir = soong_intermediates_dir.replace(
101 utils.SOONG_INTERMEDIATES_DIR,
102 utils.GENERATED_HEADERS_DIR
103 )
104 os.rename(soong_intermediates_dir, generated_headers_dir)
Jae Shinca625dd2017-11-30 15:58:00 +0900105
Jae Shin4db81a52017-12-29 13:24:54 +0900106def gather_notice_files(install_dir):
107 """Gathers all NOTICE files to a common NOTICE_FILES directory."""
Jae Shinba7456d2017-12-15 20:03:20 +0900108
Jae Shin4db81a52017-12-29 13:24:54 +0900109 common_notices_dir = utils.NOTICE_FILES_DIR_PATH
Jae Shinbd82ebb2018-06-21 14:13:46 +0900110 logging.info('Creating {} directory to gather all NOTICE files...'.format(
Jae Shin94075212018-06-14 14:54:34 +0900111 common_notices_dir))
Jae Shin4db81a52017-12-29 13:24:54 +0900112 os.makedirs(common_notices_dir)
Jae Shinaf0c0032018-06-21 11:54:05 +0900113 for arch in utils.get_snapshot_archs(install_dir):
114 notices_dir_per_arch = os.path.join(arch, utils.NOTICE_FILES_DIR_NAME)
115 if os.path.isdir(notices_dir_per_arch):
Jae Shinba7456d2017-12-15 20:03:20 +0900116 for notice_file in glob.glob(
Justin Yun9e48f542023-04-17 12:23:01 +0900117 '{}/**'.format(notices_dir_per_arch), recursive=True):
118 if os.path.isfile(notice_file):
119 rel_path = os.path.relpath(notice_file, notices_dir_per_arch)
120 target_path = os.path.join(common_notices_dir, rel_path)
121 if not os.path.isfile(target_path):
122 os.makedirs(os.path.dirname(target_path), exist_ok=True)
123 shutil.copy(notice_file, target_path)
Jae Shinaf0c0032018-06-21 11:54:05 +0900124 shutil.rmtree(notices_dir_per_arch)
Jae Shinba7456d2017-12-15 20:03:20 +0900125
126
Justin Yunb59da8f2019-01-23 19:25:05 +0900127def post_processe_files_if_needed(vndk_version):
Justin Yunef95d092020-11-30 10:19:43 +0900128 """Renames vndkcore.libraries.txt and vndksp.libraries.txt
Justin Yunb59da8f2019-01-23 19:25:05 +0900129 files to have version suffix.
Justin Yunba2a7e12020-11-27 20:14:28 +0900130 Create empty vndkproduct.libraries.txt file if not exist.
Jae Shin6e1a7962017-12-26 13:12:38 +0900131
Jae Shin89e386f2018-01-16 20:28:33 +0900132 Args:
Jae Shinaf0c0032018-06-21 11:54:05 +0900133 vndk_version: int, version of VNDK snapshot
Jae Shin6e1a7962017-12-26 13:12:38 +0900134 """
Justin Yunb59da8f2019-01-23 19:25:05 +0900135 def add_version_suffix(file_name):
Justin Yunef95d092020-11-30 10:19:43 +0900136 logging.info('Rename {} to have version suffix'.format(file_name))
Justin Yunb59da8f2019-01-23 19:25:05 +0900137 target_files = glob.glob(
138 os.path.join(utils.CONFIG_DIR_PATH_PATTERN, file_name))
139 for target_file in target_files:
140 name, ext = os.path.splitext(target_file)
141 os.rename(target_file, name + '.' + str(vndk_version) + ext)
Justin Yunba2a7e12020-11-27 20:14:28 +0900142 def create_empty_file_if_not_exist(file_name):
143 target_dirs = glob.glob(utils.CONFIG_DIR_PATH_PATTERN)
144 for dir in target_dirs:
145 path = os.path.join(dir, file_name)
146 if os.path.isfile(path):
147 continue
148 logging.info('Creating empty file: {}'.format(path))
149 open(path, 'a').close()
Justin Yunb59da8f2019-01-23 19:25:05 +0900150
Justin Yunba2a7e12020-11-27 20:14:28 +0900151 files_to_add_version_suffix = ('vndkcore.libraries.txt',
152 'vndkprivate.libraries.txt')
153 files_to_create_if_not_exist = ('vndkproduct.libraries.txt',)
154 for file_to_rename in files_to_add_version_suffix:
Kiyoung Kimb04fe602019-10-07 13:42:57 +0900155 add_version_suffix(file_to_rename)
Justin Yunba2a7e12020-11-27 20:14:28 +0900156 for file_to_create in files_to_create_if_not_exist:
157 create_empty_file_if_not_exist(file_to_create)
Kiyoung Kimb04fe602019-10-07 13:42:57 +0900158
Jae Shin6e1a7962017-12-26 13:12:38 +0900159
Jae Shinca625dd2017-11-30 15:58:00 +0900160def update_buildfiles(buildfile_generator):
Justin Yun9e48f542023-04-17 12:23:01 +0900161 # To parse json information, read and generate arch android.bp using
162 # generate_android_bp() first.
163 logging.info('Generating Android.bp files...')
164 buildfile_generator.generate_android_bp()
165
Jaewoong Jung6a5aaca2019-01-17 15:41:06 -0800166 logging.info('Generating root Android.bp file...')
167 buildfile_generator.generate_root_android_bp()
Jae Shinca625dd2017-11-30 15:58:00 +0900168
Jaewoong Jung6fbb9d22018-11-28 09:25:22 -0800169 logging.info('Generating common/Android.bp file...')
170 buildfile_generator.generate_common_android_bp()
171
Rob Seymour2ff1e6f2022-02-03 16:22:10 +0000172def copy_owners(root_dir, install_dir):
Justin Yun084664b2021-10-26 13:27:21 +0900173 path = os.path.dirname(__file__)
Rob Seymour2ff1e6f2022-02-03 16:22:10 +0000174 shutil.copy(os.path.join(root_dir, path, 'OWNERS'), install_dir)
Jae Shinca625dd2017-11-30 15:58:00 +0900175
Jae Shin5233fe12017-12-18 22:29:48 +0900176def check_gpl_license(license_checker):
177 try:
178 license_checker.check_gpl_projects()
179 except ValueError as error:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900180 logging.error('***CANNOT INSTALL VNDK SNAPSHOT***: {}'.format(error))
Jae Shin5233fe12017-12-18 22:29:48 +0900181 raise
182
183
Jae Shinca625dd2017-11-30 15:58:00 +0900184def commit(branch, build, version):
Jae Shinbd82ebb2018-06-21 14:13:46 +0900185 logging.info('Making commit...')
186 utils.check_call(['git', 'add', '.'])
Jae Shinca625dd2017-11-30 15:58:00 +0900187 message = textwrap.dedent("""\
188 Update VNDK snapshot v{version} to build {build}.
189
190 Taken from branch {branch}.""").format(
191 version=version, branch=branch, build=build)
Jae Shinbd82ebb2018-06-21 14:13:46 +0900192 utils.check_call(['git', 'commit', '-m', message])
Jae Shinca625dd2017-11-30 15:58:00 +0900193
194
Justin Yun9d2e85e2022-11-25 15:18:11 +0900195def run(vndk_version, branch, build_id, local, use_current_branch, remote,
196 verbose):
197 ''' Fetch and updtate the VNDK snapshots
198
199 Args:
200 vndk_version: int, VNDK snapshot version to install.
201 branch: string, Branch to pull build from.
202 build: string, Build number to pull.
203 local: string, Fetch local VNDK snapshot artifacts from specified local
204 directory instead of Android Build server.
205 use-current-branch: boolean, Perform the update in the current branch.
206 Do not repo start.
207 remote: string, Remote name to fetch and check if the revision of VNDK
208 snapshot is included in the source to conform GPL license.
209 verbose: int, Increase log output verbosity.
210 '''
211 local_path = None
212 if local:
213 local_path = os.path.abspath(os.path.expanduser(local))
214
215 if local_path:
216 if build_id or branch:
217 raise ValueError(
218 'When --local option is set, --branch or --build cannot be '
219 'specified.')
220 elif not os.path.isdir(local_path):
221 raise RuntimeError(
222 'The specified local directory, {}, does not exist.'.format(
223 local_path))
224 else:
225 if not (build_id and branch):
226 raise ValueError(
227 'Please provide both --branch and --build or set --local '
228 'option.')
229
230 install_dir = os.path.join(PREBUILTS_VNDK_DIR, 'v{}'.format(vndk_version))
231 if not os.path.isdir(install_dir):
232 raise RuntimeError(
233 'The directory for VNDK snapshot version {ver} does not exist.\n'
234 'Please request a new git project for prebuilts/vndk/v{ver} '
235 'before installing new snapshot.'.format(ver=vndk_version))
236
237 utils.set_logging_config(verbose)
238 root_dir = os.getcwd()
239 os.chdir(install_dir)
240
241 if not use_current_branch:
242 start_branch(build_id)
243
244 remove_old_snapshot(install_dir)
245 os.makedirs(utils.COMMON_DIR_PATH)
246
247 temp_artifact_dir = None
248 if not local_path:
249 temp_artifact_dir = tempfile.mkdtemp()
250
251 try:
252 install_snapshot(branch, build_id, local_path, install_dir,
253 temp_artifact_dir)
254 gather_notice_files(install_dir)
255 post_processe_files_if_needed(vndk_version)
256
257 buildfile_generator = GenBuildFile(install_dir, vndk_version)
258 update_buildfiles(buildfile_generator)
259
260 copy_owners(root_dir, install_dir)
261
262 if not local_path and not branch.startswith('android'):
263 license_checker = GPLChecker(install_dir, ANDROID_BUILD_TOP,
Justin Yun9e48f542023-04-17 12:23:01 +0900264 buildfile_generator.modules_with_restricted_lic,
Justin Yun9d2e85e2022-11-25 15:18:11 +0900265 temp_artifact_dir, remote)
266 check_gpl_license(license_checker)
267 logging.info(
268 'Successfully updated VNDK snapshot v{}'.format(vndk_version))
269 except Exception as error:
270 logging.error('FAILED TO INSTALL SNAPSHOT: {}'.format(error))
271 raise
272 finally:
273 if temp_artifact_dir:
274 logging.info(
275 'Deleting temp_artifact_dir: {}'.format(temp_artifact_dir))
276 shutil.rmtree(temp_artifact_dir)
277
278 if not local_path:
279 commit(branch, build_id, vndk_version)
280 logging.info(
281 'Successfully created commit for VNDK snapshot v{}'.format(
282 vndk_version))
283
284 logging.info('Done.')
285
286
Jae Shinca625dd2017-11-30 15:58:00 +0900287def get_args():
288 parser = argparse.ArgumentParser()
289 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900290 'vndk_version',
Justin Yunef95d092020-11-30 10:19:43 +0900291 type=utils.vndk_version_int,
292 help='VNDK snapshot version to install, e.g. "{}".'.format(
293 utils.MINIMUM_VNDK_VERSION))
Jae Shinca625dd2017-11-30 15:58:00 +0900294 parser.add_argument('-b', '--branch', help='Branch to pull build from.')
295 parser.add_argument('--build', help='Build number to pull.')
296 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900297 '--local',
Jae Shin01268ff2018-06-18 15:29:09 +0900298 help=('Fetch local VNDK snapshot artifacts from specified local '
299 'directory instead of Android Build server. '
300 'Example: --local=/path/to/local/dir'))
Jae Shinca625dd2017-11-30 15:58:00 +0900301 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900302 '--use-current-branch',
303 action='store_true',
Jae Shinca625dd2017-11-30 15:58:00 +0900304 help='Perform the update in the current branch. Do not repo start.')
305 parser.add_argument(
Justin Yun5ff8cc22019-01-18 15:25:42 +0900306 '--remote',
307 default='aosp',
308 help=('Remote name to fetch and check if the revision of VNDK snapshot '
309 'is included in the source to conform GPL license. default=aosp'))
310 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900311 '-v',
312 '--verbose',
313 action='count',
314 default=0,
Jae Shinca625dd2017-11-30 15:58:00 +0900315 help='Increase output verbosity, e.g. "-v", "-vv".')
316 return parser.parse_args()
317
318
319def main():
320 """Program entry point."""
321 args = get_args()
Justin Yun9d2e85e2022-11-25 15:18:11 +0900322 run(args.vndk_version, args.branch, args.build, args.local,
323 args.use_current_branch, args.remote, args.verbose)
Jae Shinca625dd2017-11-30 15:58:00 +0900324
325
326if __name__ == '__main__':
327 main()