blob: 2a8441ed983d6395244e4d13c4b9f96321020218 [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
Jae Shin6e1a7962017-12-26 13:12:38 +0900154
Jae Shinca625dd2017-11-30 15:58:00 +0900155def update_buildfiles(buildfile_generator):
Jaewoong Jung6a5aaca2019-01-17 15:41:06 -0800156 logging.info('Generating root Android.bp file...')
157 buildfile_generator.generate_root_android_bp()
Jae Shinca625dd2017-11-30 15:58:00 +0900158
Jaewoong Jung6fbb9d22018-11-28 09:25:22 -0800159 logging.info('Generating common/Android.bp file...')
160 buildfile_generator.generate_common_android_bp()
161
Jae Shinbd82ebb2018-06-21 14:13:46 +0900162 logging.info('Generating Android.bp files...')
Jae Shinca625dd2017-11-30 15:58:00 +0900163 buildfile_generator.generate_android_bp()
164
165
Jae Shin5233fe12017-12-18 22:29:48 +0900166def check_gpl_license(license_checker):
167 try:
168 license_checker.check_gpl_projects()
169 except ValueError as error:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900170 logging.error('***CANNOT INSTALL VNDK SNAPSHOT***: {}'.format(error))
Jae Shin5233fe12017-12-18 22:29:48 +0900171 raise
172
173
Jae Shinca625dd2017-11-30 15:58:00 +0900174def commit(branch, build, version):
Jae Shinbd82ebb2018-06-21 14:13:46 +0900175 logging.info('Making commit...')
176 utils.check_call(['git', 'add', '.'])
Jae Shinca625dd2017-11-30 15:58:00 +0900177 message = textwrap.dedent("""\
178 Update VNDK snapshot v{version} to build {build}.
179
180 Taken from branch {branch}.""").format(
181 version=version, branch=branch, build=build)
Jae Shinbd82ebb2018-06-21 14:13:46 +0900182 utils.check_call(['git', 'commit', '-m', message])
Jae Shinca625dd2017-11-30 15:58:00 +0900183
184
185def get_args():
186 parser = argparse.ArgumentParser()
187 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900188 'vndk_version',
189 type=int,
Jae Shinca625dd2017-11-30 15:58:00 +0900190 help='VNDK snapshot version to install, e.g. "27".')
191 parser.add_argument('-b', '--branch', help='Branch to pull build from.')
192 parser.add_argument('--build', help='Build number to pull.')
193 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900194 '--local',
Jae Shin01268ff2018-06-18 15:29:09 +0900195 help=('Fetch local VNDK snapshot artifacts from specified local '
196 'directory instead of Android Build server. '
197 'Example: --local=/path/to/local/dir'))
Jae Shinca625dd2017-11-30 15:58:00 +0900198 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900199 '--use-current-branch',
200 action='store_true',
Jae Shinca625dd2017-11-30 15:58:00 +0900201 help='Perform the update in the current branch. Do not repo start.')
202 parser.add_argument(
Justin Yun5ff8cc22019-01-18 15:25:42 +0900203 '--remote',
204 default='aosp',
205 help=('Remote name to fetch and check if the revision of VNDK snapshot '
206 'is included in the source to conform GPL license. default=aosp'))
207 parser.add_argument(
Jae Shin94075212018-06-14 14:54:34 +0900208 '-v',
209 '--verbose',
210 action='count',
211 default=0,
Jae Shinca625dd2017-11-30 15:58:00 +0900212 help='Increase output verbosity, e.g. "-v", "-vv".')
213 return parser.parse_args()
214
215
216def main():
217 """Program entry point."""
218 args = get_args()
219
Jae Shinbd82ebb2018-06-21 14:13:46 +0900220 local = None
Jae Shinca625dd2017-11-30 15:58:00 +0900221 if args.local:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900222 local = os.path.expanduser(args.local)
223
224 if local:
Jae Shinca625dd2017-11-30 15:58:00 +0900225 if args.build or args.branch:
226 raise ValueError(
227 'When --local option is set, --branch or --build cannot be '
228 'specified.')
Jae Shinbd82ebb2018-06-21 14:13:46 +0900229 elif not os.path.isdir(local):
Jae Shinca625dd2017-11-30 15:58:00 +0900230 raise RuntimeError(
Jae Shin01268ff2018-06-18 15:29:09 +0900231 'The specified local directory, {}, does not exist.'.format(
Jae Shinbd82ebb2018-06-21 14:13:46 +0900232 local))
Jae Shinca625dd2017-11-30 15:58:00 +0900233 else:
234 if not (args.build and args.branch):
235 raise ValueError(
236 'Please provide both --branch and --build or set --local '
237 'option.')
238
Jae Shinaf0c0032018-06-21 11:54:05 +0900239 vndk_version = args.vndk_version
Jae Shinca625dd2017-11-30 15:58:00 +0900240
241 install_dir = os.path.join(PREBUILTS_VNDK_DIR, 'v{}'.format(vndk_version))
242 if not os.path.isdir(install_dir):
243 raise RuntimeError(
244 'The directory for VNDK snapshot version {ver} does not exist.\n'
245 'Please request a new git project for prebuilts/vndk/v{ver} '
246 'before installing new snapshot.'.format(ver=vndk_version))
247
Jae Shin94075212018-06-14 14:54:34 +0900248 utils.set_logging_config(args.verbose)
Jae Shinca625dd2017-11-30 15:58:00 +0900249
250 os.chdir(install_dir)
251
252 if not args.use_current_branch:
253 start_branch(args.build)
254
255 remove_old_snapshot(install_dir)
Jae Shin4db81a52017-12-29 13:24:54 +0900256 os.makedirs(utils.COMMON_DIR_PATH)
Jae Shin6e1a7962017-12-26 13:12:38 +0900257
Jae Shin25d3abf2018-04-18 18:00:26 +0900258 temp_artifact_dir = None
Jae Shinbd82ebb2018-06-21 14:13:46 +0900259 if not local:
Jae Shin25d3abf2018-04-18 18:00:26 +0900260 temp_artifact_dir = tempfile.mkdtemp()
261
Jae Shin25d3abf2018-04-18 18:00:26 +0900262 try:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900263 install_snapshot(args.branch, args.build, local, install_dir,
Jae Shin25d3abf2018-04-18 18:00:26 +0900264 temp_artifact_dir)
265 gather_notice_files(install_dir)
Justin Yunb59da8f2019-01-23 19:25:05 +0900266 post_processe_files_if_needed(vndk_version)
Jae Shin25d3abf2018-04-18 18:00:26 +0900267
268 buildfile_generator = GenBuildFile(install_dir, vndk_version)
269 update_buildfiles(buildfile_generator)
270
Jae Shinbd82ebb2018-06-21 14:13:46 +0900271 if not local:
Jae Shin25d3abf2018-04-18 18:00:26 +0900272 license_checker = GPLChecker(install_dir, ANDROID_BUILD_TOP,
Justin Yun5ff8cc22019-01-18 15:25:42 +0900273 temp_artifact_dir, args.remote)
Jae Shin25d3abf2018-04-18 18:00:26 +0900274 check_gpl_license(license_checker)
Jae Shinbd82ebb2018-06-21 14:13:46 +0900275 logging.info(
Jae Shin94075212018-06-14 14:54:34 +0900276 'Successfully updated VNDK snapshot v{}'.format(vndk_version))
277 except Exception as error:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900278 logging.error('FAILED TO INSTALL SNAPSHOT: {}'.format(error))
Jae Shin94075212018-06-14 14:54:34 +0900279 raise
Jae Shin25d3abf2018-04-18 18:00:26 +0900280 finally:
281 if temp_artifact_dir:
Jae Shinbd82ebb2018-06-21 14:13:46 +0900282 logging.info(
Jae Shin25d3abf2018-04-18 18:00:26 +0900283 'Deleting temp_artifact_dir: {}'.format(temp_artifact_dir))
284 shutil.rmtree(temp_artifact_dir)
285
Jae Shinbd82ebb2018-06-21 14:13:46 +0900286 if not local:
Jae Shinca625dd2017-11-30 15:58:00 +0900287 commit(args.branch, args.build, vndk_version)
Jae Shinbd82ebb2018-06-21 14:13:46 +0900288 logging.info(
289 'Successfully created commit for VNDK snapshot v{}'.format(
290 vndk_version))
Jae Shin94075212018-06-14 14:54:34 +0900291
Jae Shinbd82ebb2018-06-21 14:13:46 +0900292 logging.info('Done.')
Jae Shinca625dd2017-11-30 15:58:00 +0900293
294
295if __name__ == '__main__':
296 main()