blob: 3c8bb6aa2e8990f6476525306cc40a809705384b [file] [log] [blame]
Jae Shinca625dd2017-11-30 15:58:00 +09001#!/usr/bin/env python
2#
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
98
Jae Shin4db81a52017-12-29 13:24:54 +090099def gather_notice_files(install_dir):
100 """Gathers all NOTICE files to a common NOTICE_FILES directory."""
Jae Shinba7456d2017-12-15 20:03:20 +0900101
Jae Shin4db81a52017-12-29 13:24:54 +0900102 common_notices_dir = utils.NOTICE_FILES_DIR_PATH
Jae Shinbd82ebb2018-06-21 14:13:46 +0900103 logging.info('Creating {} directory to gather all NOTICE files...'.format(
Jae Shin94075212018-06-14 14:54:34 +0900104 common_notices_dir))
Jae Shin4db81a52017-12-29 13:24:54 +0900105 os.makedirs(common_notices_dir)
Jae Shinaf0c0032018-06-21 11:54:05 +0900106 for arch in utils.get_snapshot_archs(install_dir):
107 notices_dir_per_arch = os.path.join(arch, utils.NOTICE_FILES_DIR_NAME)
108 if os.path.isdir(notices_dir_per_arch):
Jae Shinba7456d2017-12-15 20:03:20 +0900109 for notice_file in glob.glob(
Jae Shinaf0c0032018-06-21 11:54:05 +0900110 '{}/*.txt'.format(notices_dir_per_arch)):
Jae Shin5233fe12017-12-18 22:29:48 +0900111 if not os.path.isfile(
Jae Shin4db81a52017-12-29 13:24:54 +0900112 os.path.join(common_notices_dir,
Jae Shin5233fe12017-12-18 22:29:48 +0900113 os.path.basename(notice_file))):
Jae Shin4db81a52017-12-29 13:24:54 +0900114 shutil.copy(notice_file, common_notices_dir)
Jae Shinaf0c0032018-06-21 11:54:05 +0900115 shutil.rmtree(notices_dir_per_arch)
Jae Shinba7456d2017-12-15 20:03:20 +0900116
117
Justin Yunb59da8f2019-01-23 19:25:05 +0900118def post_processe_files_if_needed(vndk_version):
Jae Shin89e386f2018-01-16 20:28:33 +0900119 """For O-MR1, replaces unversioned VNDK directories with versioned ones.
Justin Yunb59da8f2019-01-23 19:25:05 +0900120 Also, renames ld.config.txt, llndk.libraries.txt and vndksp.libraries.txt
121 files to have version suffix.
Jae Shin6e1a7962017-12-26 13:12:38 +0900122
123 Unversioned VNDK directories: /system/${LIB}/vndk[-sp]
Jae Shin89e386f2018-01-16 20:28:33 +0900124 Versioned VNDK directories: /system/${LIB}/vndk[-sp]-27
125
126 Args:
Jae Shinaf0c0032018-06-21 11:54:05 +0900127 vndk_version: int, version of VNDK snapshot
Jae Shin6e1a7962017-12-26 13:12:38 +0900128 """
Justin Yunb59da8f2019-01-23 19:25:05 +0900129 def add_version_suffix(file_name):
130 logging.info('Rename {} to have version suffix'.format(vndk_version))
131 target_files = glob.glob(
132 os.path.join(utils.CONFIG_DIR_PATH_PATTERN, file_name))
133 for target_file in target_files:
134 name, ext = os.path.splitext(target_file)
135 os.rename(target_file, name + '.' + str(vndk_version) + ext)
Jae Shinaf0c0032018-06-21 11:54:05 +0900136 if vndk_version == 27:
137 logging.info('Revising ld.config.txt for O-MR1...')
Jae Shin89e386f2018-01-16 20:28:33 +0900138 re_pattern = '(system\/\${LIB}\/vndk(?:-sp)?)([:/]|$)'
139 VNDK_INSTALL_DIR_RE = re.compile(re_pattern, flags=re.MULTILINE)
140 ld_config_txt_paths = glob.glob(
141 os.path.join(utils.CONFIG_DIR_PATH_PATTERN, 'ld.config*'))
142 for ld_config_file in ld_config_txt_paths:
143 with open(ld_config_file, 'r') as file:
144 revised = VNDK_INSTALL_DIR_RE.sub(r'\1-27\2', file.read())
145 with open(ld_config_file, 'w') as file:
146 file.write(revised)
Jae Shin6e1a7962017-12-26 13:12:38 +0900147
Justin Yunb59da8f2019-01-23 19:25:05 +0900148 files_to_add_version_suffix = ('ld.config.txt',
149 'llndk.libraries.txt',
150 'vndksp.libraries.txt')
151 for file_to_rename in files_to_add_version_suffix:
152 add_version_suffix(file_to_rename)
153
Kiyoung Kimb04fe602019-10-07 13:42:57 +0900154 files_to_enforce_version_suffix = ('vndkcore.libraries.txt',
155 'vndkprivate.libraries.txt')
156 for file_to_rename in files_to_enforce_version_suffix:
157 add_version_suffix(file_to_rename)
158
Jae Shin6e1a7962017-12-26 13:12:38 +0900159
Jae Shinca625dd2017-11-30 15:58:00 +0900160def update_buildfiles(buildfile_generator):
Jaewoong Jung6a5aaca2019-01-17 15:41:06 -0800161 logging.info('Generating root Android.bp file...')
162 buildfile_generator.generate_root_android_bp()
Jae Shinca625dd2017-11-30 15:58:00 +0900163
Jaewoong Jung6fbb9d22018-11-28 09:25:22 -0800164 logging.info('Generating common/Android.bp file...')
165 buildfile_generator.generate_common_android_bp()
166
Jae Shinbd82ebb2018-06-21 14:13:46 +0900167 logging.info('Generating Android.bp files...')
Jae Shinca625dd2017-11-30 15:58:00 +0900168 buildfile_generator.generate_android_bp()
169
170
Jae Shin5233fe12017-12-18 22:29:48 +0900171def check_gpl_license(license_checker):
172 try:
173 license_checker.check_gpl_projects()
174 except ValueError as error:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900175 logging.error('***CANNOT INSTALL VNDK SNAPSHOT***: {}'.format(error))
Jae Shin5233fe12017-12-18 22:29:48 +0900176 raise
177
178
Jae Shinca625dd2017-11-30 15:58:00 +0900179def commit(branch, build, version):
Jae Shinbd82ebb2018-06-21 14:13:46 +0900180 logging.info('Making commit...')
181 utils.check_call(['git', 'add', '.'])
Jae Shinca625dd2017-11-30 15:58:00 +0900182 message = textwrap.dedent("""\
183 Update VNDK snapshot v{version} to build {build}.
184
185 Taken from branch {branch}.""").format(
186 version=version, branch=branch, build=build)
Jae Shinbd82ebb2018-06-21 14:13:46 +0900187 utils.check_call(['git', 'commit', '-m', message])
Jae Shinca625dd2017-11-30 15:58:00 +0900188
189
190def get_args():
191 parser = argparse.ArgumentParser()
192 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900193 'vndk_version',
194 type=int,
Jae Shinca625dd2017-11-30 15:58:00 +0900195 help='VNDK snapshot version to install, e.g. "27".')
196 parser.add_argument('-b', '--branch', help='Branch to pull build from.')
197 parser.add_argument('--build', help='Build number to pull.')
198 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900199 '--local',
Jae Shin01268ff2018-06-18 15:29:09 +0900200 help=('Fetch local VNDK snapshot artifacts from specified local '
201 'directory instead of Android Build server. '
202 'Example: --local=/path/to/local/dir'))
Jae Shinca625dd2017-11-30 15:58:00 +0900203 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900204 '--use-current-branch',
205 action='store_true',
Jae Shinca625dd2017-11-30 15:58:00 +0900206 help='Perform the update in the current branch. Do not repo start.')
207 parser.add_argument(
Justin Yun5ff8cc22019-01-18 15:25:42 +0900208 '--remote',
209 default='aosp',
210 help=('Remote name to fetch and check if the revision of VNDK snapshot '
211 'is included in the source to conform GPL license. default=aosp'))
212 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900213 '-v',
214 '--verbose',
215 action='count',
216 default=0,
Jae Shinca625dd2017-11-30 15:58:00 +0900217 help='Increase output verbosity, e.g. "-v", "-vv".')
218 return parser.parse_args()
219
220
221def main():
222 """Program entry point."""
223 args = get_args()
224
Jae Shinbd82ebb2018-06-21 14:13:46 +0900225 local = None
Jae Shinca625dd2017-11-30 15:58:00 +0900226 if args.local:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900227 local = os.path.expanduser(args.local)
228
229 if local:
Jae Shinca625dd2017-11-30 15:58:00 +0900230 if args.build or args.branch:
231 raise ValueError(
232 'When --local option is set, --branch or --build cannot be '
233 'specified.')
Jae Shinbd82ebb2018-06-21 14:13:46 +0900234 elif not os.path.isdir(local):
Jae Shinca625dd2017-11-30 15:58:00 +0900235 raise RuntimeError(
Jae Shin01268ff2018-06-18 15:29:09 +0900236 'The specified local directory, {}, does not exist.'.format(
Jae Shinbd82ebb2018-06-21 14:13:46 +0900237 local))
Jae Shinca625dd2017-11-30 15:58:00 +0900238 else:
239 if not (args.build and args.branch):
240 raise ValueError(
241 'Please provide both --branch and --build or set --local '
242 'option.')
243
Jae Shinaf0c0032018-06-21 11:54:05 +0900244 vndk_version = args.vndk_version
Jae Shinca625dd2017-11-30 15:58:00 +0900245
246 install_dir = os.path.join(PREBUILTS_VNDK_DIR, 'v{}'.format(vndk_version))
247 if not os.path.isdir(install_dir):
248 raise RuntimeError(
249 'The directory for VNDK snapshot version {ver} does not exist.\n'
250 'Please request a new git project for prebuilts/vndk/v{ver} '
251 'before installing new snapshot.'.format(ver=vndk_version))
252
Jae Shin94075212018-06-14 14:54:34 +0900253 utils.set_logging_config(args.verbose)
Jae Shinca625dd2017-11-30 15:58:00 +0900254
255 os.chdir(install_dir)
256
257 if not args.use_current_branch:
258 start_branch(args.build)
259
260 remove_old_snapshot(install_dir)
Jae Shin4db81a52017-12-29 13:24:54 +0900261 os.makedirs(utils.COMMON_DIR_PATH)
Jae Shin6e1a7962017-12-26 13:12:38 +0900262
Jae Shin25d3abf2018-04-18 18:00:26 +0900263 temp_artifact_dir = None
Jae Shinbd82ebb2018-06-21 14:13:46 +0900264 if not local:
Jae Shin25d3abf2018-04-18 18:00:26 +0900265 temp_artifact_dir = tempfile.mkdtemp()
266
Jae Shin25d3abf2018-04-18 18:00:26 +0900267 try:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900268 install_snapshot(args.branch, args.build, local, install_dir,
Jae Shin25d3abf2018-04-18 18:00:26 +0900269 temp_artifact_dir)
270 gather_notice_files(install_dir)
Justin Yunb59da8f2019-01-23 19:25:05 +0900271 post_processe_files_if_needed(vndk_version)
Jae Shin25d3abf2018-04-18 18:00:26 +0900272
273 buildfile_generator = GenBuildFile(install_dir, vndk_version)
274 update_buildfiles(buildfile_generator)
275
Jae Shinbd82ebb2018-06-21 14:13:46 +0900276 if not local:
Jae Shin25d3abf2018-04-18 18:00:26 +0900277 license_checker = GPLChecker(install_dir, ANDROID_BUILD_TOP,
Justin Yun5ff8cc22019-01-18 15:25:42 +0900278 temp_artifact_dir, args.remote)
Jae Shin25d3abf2018-04-18 18:00:26 +0900279 check_gpl_license(license_checker)
Jae Shinbd82ebb2018-06-21 14:13:46 +0900280 logging.info(
Jae Shin94075212018-06-14 14:54:34 +0900281 'Successfully updated VNDK snapshot v{}'.format(vndk_version))
282 except Exception as error:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900283 logging.error('FAILED TO INSTALL SNAPSHOT: {}'.format(error))
Jae Shin94075212018-06-14 14:54:34 +0900284 raise
Jae Shin25d3abf2018-04-18 18:00:26 +0900285 finally:
286 if temp_artifact_dir:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900287 logging.info(
Jae Shin25d3abf2018-04-18 18:00:26 +0900288 'Deleting temp_artifact_dir: {}'.format(temp_artifact_dir))
289 shutil.rmtree(temp_artifact_dir)
290
Jae Shinbd82ebb2018-06-21 14:13:46 +0900291 if not local:
Jae Shinca625dd2017-11-30 15:58:00 +0900292 commit(args.branch, args.build, vndk_version)
Jae Shinbd82ebb2018-06-21 14:13:46 +0900293 logging.info(
294 'Successfully created commit for VNDK snapshot v{}'.format(
295 vndk_version))
Jae Shin94075212018-06-14 14:54:34 +0900296
Jae Shinbd82ebb2018-06-21 14:13:46 +0900297 logging.info('Done.')
Jae Shinca625dd2017-11-30 15:58:00 +0900298
299
300if __name__ == '__main__':
301 main()