blob: 94ae353edaa632d9a47daab7731916920ee1eab6 [file] [log] [blame]
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001#!/usr/bin/env python
2#
3# Copyright (C) 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# 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, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16
17"""
18This script merges two partial target files packages (one of which contains
19system files, and the other contains non-system files) together, producing a
20complete target files package that can be used to generate an OTA package.
21
22Usage: merge_target_files.py [args]
23
24 --system-target-files system-target-files-zip-archive
25 The input target files package containing system bits. This is a zip
26 archive.
27
Daniel Norman2c99c5b2019-03-07 13:01:48 -080028 --system-item-list system-item-list-file
29 The optional path to a newline-separated config file that replaces the
30 contents of default_system_item_list if provided.
31
32 --system-misc-info-keys system-misc-info-keys-file
33 The optional path to a newline-separated config file that replaces the
34 contents of default_system_misc_info_keys if provided.
35
Bill Peckhame9eb5f92019-02-01 15:52:10 -080036 --other-target-files other-target-files-zip-archive
37 The input target files package containing other bits. This is a zip
38 archive.
39
Daniel Norman2c99c5b2019-03-07 13:01:48 -080040 --other-item-list other-item-list-file
41 The optional path to a newline-separated config file that replaces the
42 contents of default_other_item_list if provided.
43
Bill Peckhame9eb5f92019-02-01 15:52:10 -080044 --output-target-files output-target-files-package
45 The output merged target files package. Also a zip archive.
46"""
47
48from __future__ import print_function
49
Bill Peckhame9eb5f92019-02-01 15:52:10 -080050import fnmatch
51import logging
52import os
53import sys
54import zipfile
55
56import common
57import add_img_to_target_files
58
59logger = logging.getLogger(__name__)
60OPTIONS = common.OPTIONS
61OPTIONS.verbose = True
Bill Peckhamf753e152019-02-19 18:02:46 -080062OPTIONS.system_target_files = None
Daniel Norman2c99c5b2019-03-07 13:01:48 -080063OPTIONS.system_item_list = None
64OPTIONS.system_misc_info_keys = None
Bill Peckhamf753e152019-02-19 18:02:46 -080065OPTIONS.other_target_files = None
Daniel Norman2c99c5b2019-03-07 13:01:48 -080066OPTIONS.other_item_list = None
Bill Peckhamf753e152019-02-19 18:02:46 -080067OPTIONS.output_target_files = None
68OPTIONS.keep_tmp = False
Bill Peckhame9eb5f92019-02-01 15:52:10 -080069
Daniel Norman2c99c5b2019-03-07 13:01:48 -080070# default_system_item_list is a list of items to extract from the partial
Bill Peckhame9eb5f92019-02-01 15:52:10 -080071# system target files package as is, meaning these items will land in the
72# output target files package exactly as they appear in the input partial
73# system target files package.
74
Daniel Norman2c99c5b2019-03-07 13:01:48 -080075default_system_item_list = [
Bill Peckhame9eb5f92019-02-01 15:52:10 -080076 'META/apkcerts.txt',
77 'META/filesystem_config.txt',
78 'META/root_filesystem_config.txt',
79 'META/system_manifest.xml',
80 'META/system_matrix.xml',
81 'META/update_engine_config.txt',
82 'PRODUCT/*',
83 'ROOT/*',
84 'SYSTEM/*',
85]
86
87# system_extract_special_item_list is a list of items to extract from the
88# partial system target files package that need some special processing, such
89# as some sort of combination with items from the partial other target files
90# package.
91
92system_extract_special_item_list = [
93 'META/*',
94]
95
Daniel Norman2c99c5b2019-03-07 13:01:48 -080096# default_system_misc_info_keys is a list of keys to obtain from the system instance of
Bill Peckhame9eb5f92019-02-01 15:52:10 -080097# META/misc_info.txt. The remaining keys from the other instance.
98
Daniel Norman2c99c5b2019-03-07 13:01:48 -080099default_system_misc_info_keys = [
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800100 'avb_system_hashtree_enable',
101 'avb_system_add_hashtree_footer_args',
102 'avb_system_key_path',
103 'avb_system_algorithm',
104 'avb_system_rollback_index_location',
105 'avb_product_hashtree_enable',
106 'avb_product_add_hashtree_footer_args',
107 'avb_product_services_hashtree_enable',
108 'avb_product_services_add_hashtree_footer_args',
109 'system_root_image',
110 'root_dir',
111 'ab_update',
112 'default_system_dev_certificate',
113 'system_size',
114]
115
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800116# default_other_item_list is a list of items to extract from the partial
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800117# other target files package as is, meaning these items will land in the output
118# target files package exactly as they appear in the input partial other target
119# files package.
120
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800121default_other_item_list = [
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800122 'META/boot_filesystem_config.txt',
123 'META/otakeys.txt',
124 'META/releasetools.py',
125 'META/vendor_filesystem_config.txt',
126 'META/vendor_manifest.xml',
127 'META/vendor_matrix.xml',
128 'BOOT/*',
129 'DATA/*',
130 'ODM/*',
131 'OTA/android-info.txt',
132 'PREBUILT_IMAGES/*',
133 'RADIO/*',
134 'VENDOR/*',
135]
136
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800137# other_extract_special_item_list is a list of items to extract from the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800138# partial other target files package that need some special processing, such as
139# some sort of combination with items from the partial system target files
140# package.
141
142other_extract_special_item_list = [
143 'META/*',
144]
145
146
147def extract_items(target_files, target_files_temp_dir, extract_item_list):
148 """Extract items from target files to temporary directory.
149
150 This function extracts from the specified target files zip archive into the
151 specified temporary directory, the items specified in the extract item list.
152
153 Args:
154 target_files: The target files zip archive from which to extract items.
155
156 target_files_temp_dir: The temporary directory where the extracted items
157 will land.
158
159 extract_item_list: A list of items to extract.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800160 """
161
162 logger.info('extracting from %s', target_files)
163
164 # Filter the extract_item_list to remove any items that do not exist in the
165 # zip file. Otherwise, the extraction step will fail.
166
167 with zipfile.ZipFile(
168 target_files,
169 'r',
170 allowZip64=True) as target_files_zipfile:
171 target_files_namelist = target_files_zipfile.namelist()
172
173 filtered_extract_item_list = []
174 for pattern in extract_item_list:
175 matching_namelist = fnmatch.filter(target_files_namelist, pattern)
176 if not matching_namelist:
177 logger.warning('no match for %s', pattern)
178 else:
179 filtered_extract_item_list.append(pattern)
180
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800181 # Extract from target_files into target_files_temp_dir the
182 # filtered_extract_item_list.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800183
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800184 common.UnzipToDir(
185 target_files,
186 target_files_temp_dir,
187 filtered_extract_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800188
189
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800190def read_config_list(config_file_path):
191 """Reads a config file into a list of strings.
192
193 Expects the file to be newline-separated.
194
195 Args:
196 config_file_path: The path to the config file to open and read.
197 """
198 with open(config_file_path) as config_file:
199 return config_file.read().splitlines()
200
201
Daniel Normane5964522019-03-19 10:32:03 -0700202def validate_config_lists(system_item_list, other_item_list):
203 """Performs validations on the merge config lists.
204
205 Args:
206 system_item_list: The list of items to extract from the partial
207 system target files package as is.
208
209 other_item_list: The list of items to extract from the partial
210 other target files package as is.
211
212 Returns:
213 False if a validation fails, otherwise true.
214 """
215 default_combined_item_set = set(default_system_item_list)
216 default_combined_item_set.update(default_other_item_list)
217
218 combined_item_set = set(system_item_list)
219 combined_item_set.update(other_item_list)
220
221 # Check that the merge config lists are not missing any item specified
222 # by the default config lists.
223 difference = default_combined_item_set.difference(combined_item_set)
224 if difference:
225 logger.error('Missing merge config items: %s' % list(difference))
226 logger.error('Please ensure missing items are in either the '
227 'system-item-list or other-item-list files provided to '
228 'this script.')
229 return False
230
231 return True
232
233
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800234def process_ab_partitions_txt(
235 system_target_files_temp_dir,
236 other_target_files_temp_dir,
237 output_target_files_temp_dir):
238 """Perform special processing for META/ab_partitions.txt
239
240 This function merges the contents of the META/ab_partitions.txt files from
241 the system directory and the other directory, placing the merged result in
242 the output directory. The precondition in that the files are already
243 extracted. The post condition is that the output META/ab_partitions.txt
244 contains the merged content. The format for each ab_partitions.txt a one
245 partition name per line. The output file contains the union of the parition
246 names.
247
248 Args:
249 system_target_files_temp_dir: The name of a directory containing the
250 special items extracted from the system target files package.
251
252 other_target_files_temp_dir: The name of a directory containing the
253 special items extracted from the other target files package.
254
255 output_target_files_temp_dir: The name of a directory that will be used
256 to create the output target files package after all the special cases
257 are processed.
258 """
259
260 system_ab_partitions_txt = os.path.join(
261 system_target_files_temp_dir, 'META', 'ab_partitions.txt')
262
263 other_ab_partitions_txt = os.path.join(
264 other_target_files_temp_dir, 'META', 'ab_partitions.txt')
265
266 with open(system_ab_partitions_txt) as f:
267 system_ab_partitions = f.read().splitlines()
268
269 with open(other_ab_partitions_txt) as f:
270 other_ab_partitions = f.read().splitlines()
271
272 output_ab_partitions = set(system_ab_partitions + other_ab_partitions)
273
274 output_ab_partitions_txt = os.path.join(
275 output_target_files_temp_dir, 'META', 'ab_partitions.txt')
276
277 with open(output_ab_partitions_txt, 'w') as output:
278 for partition in sorted(output_ab_partitions):
279 output.write('%s\n' % partition)
280
281
282def process_misc_info_txt(
283 system_target_files_temp_dir,
284 other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800285 output_target_files_temp_dir,
286 system_misc_info_keys):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800287 """Perform special processing for META/misc_info.txt
288
289 This function merges the contents of the META/misc_info.txt files from the
290 system directory and the other directory, placing the merged result in the
291 output directory. The precondition in that the files are already extracted.
292 The post condition is that the output META/misc_info.txt contains the merged
293 content.
294
295 Args:
296 system_target_files_temp_dir: The name of a directory containing the
297 special items extracted from the system target files package.
298
299 other_target_files_temp_dir: The name of a directory containing the
300 special items extracted from the other target files package.
301
302 output_target_files_temp_dir: The name of a directory that will be used
303 to create the output target files package after all the special cases
304 are processed.
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800305
306 system_misc_info_keys: A list of keys to obtain from the system instance
307 of META/misc_info.txt. The remaining keys from the other instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800308 """
309
310 def read_helper(d):
311 misc_info_txt = os.path.join(d, 'META', 'misc_info.txt')
312 with open(misc_info_txt) as f:
313 return list(f.read().splitlines())
314
315 system_info_dict = common.LoadDictionaryFromLines(
316 read_helper(system_target_files_temp_dir))
317
318 # We take most of the misc info from the other target files.
319
320 merged_info_dict = common.LoadDictionaryFromLines(
321 read_helper(other_target_files_temp_dir))
322
323 # Replace certain values in merged_info_dict with values from
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800324 # system_info_dict.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800325
326 for key in system_misc_info_keys:
327 merged_info_dict[key] = system_info_dict[key]
328
329 output_misc_info_txt = os.path.join(
330 output_target_files_temp_dir,
331 'META', 'misc_info.txt')
332
333 sorted_keys = sorted(merged_info_dict.keys())
334
335 with open(output_misc_info_txt, 'w') as output:
336 for key in sorted_keys:
337 output.write('{}={}\n'.format(key, merged_info_dict[key]))
338
339
340def process_file_contexts_bin(temp_dir, output_target_files_temp_dir):
341 """Perform special processing for META/file_contexts.bin.
342
343 This function combines plat_file_contexts and vendor_file_contexts, which are
344 expected to already be extracted in temp_dir, to produce a merged
345 file_contexts.bin that will land in temp_dir at META/file_contexts.bin.
346
347 Args:
348 temp_dir: The name of a scratch directory that this function can use for
349 intermediate files generated during processing.
350
351 output_target_files_temp_dir: The name of the working directory that must
352 already contain plat_file_contexts and vendor_file_contexts (in the
353 appropriate sub directories), and to which META/file_contexts.bin will be
354 written.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800355 """
356
357 # To create a merged file_contexts.bin file, we use the system and vendor
358 # file contexts files as input, the m4 tool to combine them, the sorting tool
359 # to sort, and finally the sefcontext_compile tool to generate the final
360 # output. We currently omit a checkfc step since the files had been checked
361 # as part of the build.
362
363 # The m4 step concatenates the two input files contexts files. Since m4
364 # writes to stdout, we receive that into an array of bytes, and then write it
365 # to a file.
366
367 # Collect the file contexts that we're going to combine from SYSTEM, VENDOR,
368 # PRODUCT, and ODM. We require SYSTEM and VENDOR, but others are optional.
369
370 file_contexts_list = []
371
372 for partition in ['SYSTEM', 'VENDOR', 'PRODUCT', 'ODM']:
373 prefix = 'plat' if partition == 'SYSTEM' else partition.lower()
374
375 file_contexts = os.path.join(
376 output_target_files_temp_dir,
377 partition, 'etc', 'selinux', prefix + '_file_contexts')
378
379 mandatory = partition in ['SYSTEM', 'VENDOR']
380
381 if mandatory or os.path.isfile(file_contexts):
382 file_contexts_list.append(file_contexts)
383 else:
384 logger.warning('file not found: %s', file_contexts)
385
386 command = ['m4', '--fatal-warnings', '-s'] + file_contexts_list
387
388 merged_content = common.RunAndCheckOutput(command, verbose=False)
389
390 merged_file_contexts_txt = os.path.join(temp_dir, 'merged_file_contexts.txt')
391
392 with open(merged_file_contexts_txt, 'wb') as f:
393 f.write(merged_content)
394
395 # The sort step sorts the concatenated file.
396
397 sorted_file_contexts_txt = os.path.join(temp_dir, 'sorted_file_contexts.txt')
398 command = ['fc_sort', merged_file_contexts_txt, sorted_file_contexts_txt]
Bill Peckham889b0c62019-02-21 18:53:37 -0800399 common.RunAndWait(command, verbose=True)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800400
401 # Finally, the compile step creates the final META/file_contexts.bin.
402
403 file_contexts_bin = os.path.join(
404 output_target_files_temp_dir,
405 'META', 'file_contexts.bin')
406
407 command = [
408 'sefcontext_compile',
409 '-o', file_contexts_bin,
410 sorted_file_contexts_txt,
411 ]
412
Bill Peckham889b0c62019-02-21 18:53:37 -0800413 common.RunAndWait(command, verbose=True)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800414
415
416def process_special_cases(
417 temp_dir,
418 system_target_files_temp_dir,
419 other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800420 output_target_files_temp_dir,
421 system_misc_info_keys):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800422 """Perform special-case processing for certain target files items.
423
424 Certain files in the output target files package require special-case
425 processing. This function performs all that special-case processing.
426
427 Args:
428 temp_dir: The name of a scratch directory that this function can use for
429 intermediate files generated during processing.
430
431 system_target_files_temp_dir: The name of a directory containing the
432 special items extracted from the system target files package.
433
434 other_target_files_temp_dir: The name of a directory containing the
435 special items extracted from the other target files package.
436
437 output_target_files_temp_dir: The name of a directory that will be used
438 to create the output target files package after all the special cases
439 are processed.
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800440
441 system_misc_info_keys: A list of keys to obtain from the system instance
442 of META/misc_info.txt. The remaining keys from the other instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800443 """
444
445 process_ab_partitions_txt(
446 system_target_files_temp_dir=system_target_files_temp_dir,
447 other_target_files_temp_dir=other_target_files_temp_dir,
448 output_target_files_temp_dir=output_target_files_temp_dir)
449
450 process_misc_info_txt(
451 system_target_files_temp_dir=system_target_files_temp_dir,
452 other_target_files_temp_dir=other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800453 output_target_files_temp_dir=output_target_files_temp_dir,
454 system_misc_info_keys=system_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800455
Bill Peckham889b0c62019-02-21 18:53:37 -0800456 process_file_contexts_bin(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800457 temp_dir=temp_dir,
458 output_target_files_temp_dir=output_target_files_temp_dir)
459
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800460
461def merge_target_files(
462 temp_dir,
463 system_target_files,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800464 system_item_list,
465 system_misc_info_keys,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800466 other_target_files,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800467 other_item_list,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800468 output_target_files):
469 """Merge two target files packages together.
470
471 This function takes system and other target files packages as input, performs
472 various file extractions, special case processing, and finally creates a
473 merged zip archive as output.
474
475 Args:
476 temp_dir: The name of a directory we use when we extract items from the
477 input target files packages, and also a scratch directory that we use for
478 temporary files.
479
480 system_target_files: The name of the zip archive containing the system
481 partial target files package.
482
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800483 system_item_list: The list of items to extract from the partial system
484 target files package as is, meaning these items will land in the output
485 target files package exactly as they appear in the input partial system
486 target files package.
487
488 system_misc_info_keys: The list of keys to obtain from the system instance
489 of META/misc_info.txt. The remaining keys from the other instance.
490
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800491 other_target_files: The name of the zip archive containing the other
492 partial target files package.
493
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800494 other_item_list: The list of items to extract from the partial other
495 target files package as is, meaning these items will land in the output
496 target files package exactly as they appear in the input partial other
497 target files package.
498
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800499 output_target_files: The name of the output zip archive target files
500 package created by merging system and other.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800501 """
502
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800503 logger.info(
504 'starting: merge system %s and other %s into output %s',
505 system_target_files,
506 other_target_files,
507 output_target_files)
508
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800509 # Create directory names that we'll use when we extract files from system,
510 # and other, and for zipping the final output.
511
512 system_target_files_temp_dir = os.path.join(temp_dir, 'system')
513 other_target_files_temp_dir = os.path.join(temp_dir, 'other')
514 output_target_files_temp_dir = os.path.join(temp_dir, 'output')
515
516 # Extract "as is" items from the input system partial target files package.
517 # We extract them directly into the output temporary directory since the
518 # items do not need special case processing.
519
Bill Peckham889b0c62019-02-21 18:53:37 -0800520 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800521 target_files=system_target_files,
522 target_files_temp_dir=output_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800523 extract_item_list=system_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800524
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800525 # Extract "as is" items from the input other partial target files package. We
526 # extract them directly into the output temporary directory since the items
527 # do not need special case processing.
528
Bill Peckham889b0c62019-02-21 18:53:37 -0800529 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800530 target_files=other_target_files,
531 target_files_temp_dir=output_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800532 extract_item_list=other_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800533
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800534 # Extract "special" items from the input system partial target files package.
535 # We extract these items to different directory since they require special
536 # processing before they will end up in the output directory.
537
Bill Peckham889b0c62019-02-21 18:53:37 -0800538 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800539 target_files=system_target_files,
540 target_files_temp_dir=system_target_files_temp_dir,
541 extract_item_list=system_extract_special_item_list)
542
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800543 # Extract "special" items from the input other partial target files package.
544 # We extract these items to different directory since they require special
545 # processing before they will end up in the output directory.
546
Bill Peckham889b0c62019-02-21 18:53:37 -0800547 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800548 target_files=other_target_files,
549 target_files_temp_dir=other_target_files_temp_dir,
550 extract_item_list=other_extract_special_item_list)
551
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800552 # Now that the temporary directories contain all the extracted files, perform
553 # special case processing on any items that need it. After this function
554 # completes successfully, all the files we need to create the output target
555 # files package are in place.
556
Bill Peckham889b0c62019-02-21 18:53:37 -0800557 process_special_cases(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800558 temp_dir=temp_dir,
559 system_target_files_temp_dir=system_target_files_temp_dir,
560 other_target_files_temp_dir=other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800561 output_target_files_temp_dir=output_target_files_temp_dir,
562 system_misc_info_keys=system_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800563
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800564 # Regenerate IMAGES in the temporary directory.
565
566 add_img_args = [
567 '--verbose',
568 output_target_files_temp_dir,
569 ]
570
571 add_img_to_target_files.main(add_img_args)
572
573 # Finally, create the output target files zip archive.
574
575 output_zip = os.path.abspath(output_target_files)
576 output_target_files_list = os.path.join(temp_dir, 'output.list')
577 output_target_files_meta_dir = os.path.join(
578 output_target_files_temp_dir, 'META')
579
580 command = [
581 'find',
582 output_target_files_meta_dir,
583 ]
584 # TODO(bpeckham): sort this to be more like build.
585 meta_content = common.RunAndCheckOutput(command, verbose=False)
586 command = [
587 'find',
588 output_target_files_temp_dir,
589 '-path',
590 output_target_files_meta_dir,
591 '-prune',
592 '-o',
593 '-print'
594 ]
595 # TODO(bpeckham): sort this to be more like build.
596 other_content = common.RunAndCheckOutput(command, verbose=False)
597
598 with open(output_target_files_list, 'wb') as f:
599 f.write(meta_content)
600 f.write(other_content)
601
602 command = [
Bill Peckhamf753e152019-02-19 18:02:46 -0800603 'soong_zip',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800604 '-d',
605 '-o', output_zip,
606 '-C', output_target_files_temp_dir,
607 '-l', output_target_files_list,
608 ]
609 logger.info('creating %s', output_target_files)
Bill Peckham889b0c62019-02-21 18:53:37 -0800610 common.RunAndWait(command, verbose=True)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800611
612
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800613def call_func_with_temp_dir(func, keep_tmp):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800614 """Manage the creation and cleanup of the temporary directory.
615
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800616 This function calls the given function after first creating a temporary
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800617 directory. It also cleans up the temporary directory.
618
619 Args:
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800620 func: The function to call. Should accept one parameter, the path to
621 the temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800622
623 keep_tmp: Keep the temporary directory after processing is complete.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800624 """
625
626 # Create a temporary directory. This will serve as the parent of directories
627 # we use when we extract items from the input target files packages, and also
628 # a scratch directory that we use for temporary files.
629
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800630 temp_dir = common.MakeTempDir(prefix='merge_target_files_')
631
632 try:
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800633 func(temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800634 except:
635 raise
636 finally:
637 if keep_tmp:
638 logger.info('keeping %s', temp_dir)
639 else:
640 common.Cleanup()
641
642
643def main():
644 """The main function.
645
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800646 Process command line arguments, then call merge_target_files to
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800647 perform the heavy lifting.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800648 """
649
650 common.InitLogging()
651
Bill Peckhamf753e152019-02-19 18:02:46 -0800652 def option_handler(o, a):
653 if o == '--system-target-files':
654 OPTIONS.system_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800655 elif o == '--system-item-list':
656 OPTIONS.system_item_list = a
657 elif o == '--system-misc-info-keys':
658 OPTIONS.system_misc_info_keys = a
Bill Peckhamf753e152019-02-19 18:02:46 -0800659 elif o == '--other-target-files':
660 OPTIONS.other_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800661 elif o == '--other-item-list':
662 OPTIONS.other_item_list = a
Bill Peckhamf753e152019-02-19 18:02:46 -0800663 elif o == '--output-target-files':
664 OPTIONS.output_target_files = a
665 elif o == '--keep_tmp':
666 OPTIONS.keep_tmp = True
667 else:
668 return False
669 return True
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800670
Bill Peckhamf753e152019-02-19 18:02:46 -0800671 args = common.ParseOptions(
672 sys.argv[1:], __doc__,
673 extra_long_opts=[
674 'system-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800675 'system-item-list=',
676 'system-misc-info-keys=',
Bill Peckhamf753e152019-02-19 18:02:46 -0800677 'other-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800678 'other-item-list=',
Bill Peckhamf753e152019-02-19 18:02:46 -0800679 'output-target-files=',
680 "keep_tmp",
681 ],
682 extra_option_handler=option_handler)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800683
Bill Peckham889b0c62019-02-21 18:53:37 -0800684 if (len(args) != 0 or
Bill Peckhamf753e152019-02-19 18:02:46 -0800685 OPTIONS.system_target_files is None or
686 OPTIONS.other_target_files is None or
687 OPTIONS.output_target_files is None):
688 common.Usage(__doc__)
Bill Peckham889b0c62019-02-21 18:53:37 -0800689 sys.exit(1)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800690
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800691 if OPTIONS.system_item_list:
692 system_item_list = read_config_list(OPTIONS.system_item_list)
693 else:
694 system_item_list = default_system_item_list
695
696 if OPTIONS.system_misc_info_keys:
697 system_misc_info_keys = read_config_list(OPTIONS.system_misc_info_keys)
698 else:
699 system_misc_info_keys = default_system_misc_info_keys
700
701 if OPTIONS.other_item_list:
702 other_item_list = read_config_list(OPTIONS.other_item_list)
703 else:
704 other_item_list = default_other_item_list
705
Daniel Normane5964522019-03-19 10:32:03 -0700706 if not validate_config_lists(
707 system_item_list=system_item_list,
708 other_item_list=other_item_list):
709 sys.exit(1)
710
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800711 call_func_with_temp_dir(
712 lambda temp_dir: merge_target_files(
713 temp_dir=temp_dir,
714 system_target_files=OPTIONS.system_target_files,
715 system_item_list=system_item_list,
716 system_misc_info_keys=system_misc_info_keys,
717 other_target_files=OPTIONS.other_target_files,
718 other_item_list=other_item_list,
719 output_target_files=OPTIONS.output_target_files),
720 OPTIONS.keep_tmp)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800721
722
723if __name__ == '__main__':
Bill Peckham889b0c62019-02-21 18:53:37 -0800724 main()