xref: /aosp_15_r20/external/angle/build/android/gyp/unused_resources.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*8975f5c5SAndroid Build Coastguard Worker# encoding: utf-8
3*8975f5c5SAndroid Build Coastguard Worker# Copyright 2021 The Chromium Authors
4*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
5*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Workerimport argparse
8*8975f5c5SAndroid Build Coastguard Workerimport os
9*8975f5c5SAndroid Build Coastguard Workerimport pathlib
10*8975f5c5SAndroid Build Coastguard Workerimport sys
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Workerfrom util import build_utils
13*8975f5c5SAndroid Build Coastguard Workerfrom util import resource_utils
14*8975f5c5SAndroid Build Coastguard Workerimport action_helpers  # build_utils adds //build to sys.path.
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Workerdef _FilterUnusedResources(r_text_in, r_text_out, unused_resources_config):
18*8975f5c5SAndroid Build Coastguard Worker  removed_resources = set()
19*8975f5c5SAndroid Build Coastguard Worker  with open(unused_resources_config, encoding='utf-8') as output_config:
20*8975f5c5SAndroid Build Coastguard Worker    for line in output_config:
21*8975f5c5SAndroid Build Coastguard Worker      # example line: attr/line_height#remove
22*8975f5c5SAndroid Build Coastguard Worker      resource = line.split('#')[0]
23*8975f5c5SAndroid Build Coastguard Worker      resource_type, resource_name = resource.split('/')
24*8975f5c5SAndroid Build Coastguard Worker      removed_resources.add((resource_type, resource_name))
25*8975f5c5SAndroid Build Coastguard Worker  kept_lines = []
26*8975f5c5SAndroid Build Coastguard Worker  with open(r_text_in, encoding='utf-8') as infile:
27*8975f5c5SAndroid Build Coastguard Worker    for line in infile:
28*8975f5c5SAndroid Build Coastguard Worker      # example line: int attr line_height 0x7f0014ee
29*8975f5c5SAndroid Build Coastguard Worker      resource_type, resource_name = line.split(' ')[1:3]
30*8975f5c5SAndroid Build Coastguard Worker      if (resource_type, resource_name) not in removed_resources:
31*8975f5c5SAndroid Build Coastguard Worker        kept_lines.append(line)
32*8975f5c5SAndroid Build Coastguard Worker
33*8975f5c5SAndroid Build Coastguard Worker  with open(r_text_out, 'w', encoding='utf-8') as out_file:
34*8975f5c5SAndroid Build Coastguard Worker    out_file.writelines(kept_lines)
35*8975f5c5SAndroid Build Coastguard Worker
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Workerdef _WritePaths(dest_path, lines):
38*8975f5c5SAndroid Build Coastguard Worker  pathlib.Path(dest_path).write_text('\n'.join(lines) + '\n')
39*8975f5c5SAndroid Build Coastguard Worker
40*8975f5c5SAndroid Build Coastguard Worker
41*8975f5c5SAndroid Build Coastguard Workerdef main(args):
42*8975f5c5SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser()
43*8975f5c5SAndroid Build Coastguard Worker
44*8975f5c5SAndroid Build Coastguard Worker  action_helpers.add_depfile_arg(parser)
45*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--script',
46*8975f5c5SAndroid Build Coastguard Worker                      required=True,
47*8975f5c5SAndroid Build Coastguard Worker                      help='Path to the unused resources detector script.')
48*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
49*8975f5c5SAndroid Build Coastguard Worker      '--dependencies-res-zips',
50*8975f5c5SAndroid Build Coastguard Worker      required=True,
51*8975f5c5SAndroid Build Coastguard Worker      action='append',
52*8975f5c5SAndroid Build Coastguard Worker      help='Resources zip archives to investigate for unused resources.')
53*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--dexes',
54*8975f5c5SAndroid Build Coastguard Worker                      action='append',
55*8975f5c5SAndroid Build Coastguard Worker                      required=True,
56*8975f5c5SAndroid Build Coastguard Worker                      help='Path to dex file, or zip with dex files.')
57*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
58*8975f5c5SAndroid Build Coastguard Worker      '--proguard-mapping',
59*8975f5c5SAndroid Build Coastguard Worker      help='Path to proguard mapping file for the optimized dex.')
60*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--r-text-in', required=True, help='Path to input R.txt')
61*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
62*8975f5c5SAndroid Build Coastguard Worker      '--r-text-out',
63*8975f5c5SAndroid Build Coastguard Worker      help='Path to output R.txt with unused resources removed.')
64*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--android-manifests',
65*8975f5c5SAndroid Build Coastguard Worker                      action='append',
66*8975f5c5SAndroid Build Coastguard Worker                      required=True,
67*8975f5c5SAndroid Build Coastguard Worker                      help='Path to AndroidManifest')
68*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--output-config',
69*8975f5c5SAndroid Build Coastguard Worker                      required=True,
70*8975f5c5SAndroid Build Coastguard Worker                      help='Path to output the aapt2 config to.')
71*8975f5c5SAndroid Build Coastguard Worker  args = build_utils.ExpandFileArgs(args)
72*8975f5c5SAndroid Build Coastguard Worker  options = parser.parse_args(args)
73*8975f5c5SAndroid Build Coastguard Worker  options.dependencies_res_zips = (action_helpers.parse_gn_list(
74*8975f5c5SAndroid Build Coastguard Worker      options.dependencies_res_zips))
75*8975f5c5SAndroid Build Coastguard Worker
76*8975f5c5SAndroid Build Coastguard Worker  # in case of no resources, short circuit early.
77*8975f5c5SAndroid Build Coastguard Worker  if not options.dependencies_res_zips:
78*8975f5c5SAndroid Build Coastguard Worker    build_utils.Touch(options.output_config)
79*8975f5c5SAndroid Build Coastguard Worker    return
80*8975f5c5SAndroid Build Coastguard Worker
81*8975f5c5SAndroid Build Coastguard Worker  with build_utils.TempDir() as temp_dir:
82*8975f5c5SAndroid Build Coastguard Worker    dep_subdirs = []
83*8975f5c5SAndroid Build Coastguard Worker    for dependency_res_zip in options.dependencies_res_zips:
84*8975f5c5SAndroid Build Coastguard Worker      dep_subdirs += resource_utils.ExtractDeps([dependency_res_zip], temp_dir)
85*8975f5c5SAndroid Build Coastguard Worker
86*8975f5c5SAndroid Build Coastguard Worker    # Use files for paths to avoid command line getting too long.
87*8975f5c5SAndroid Build Coastguard Worker    # https://crbug.com/362019371
88*8975f5c5SAndroid Build Coastguard Worker    manifests_file = os.path.join(temp_dir, 'manifests-inputs.txt')
89*8975f5c5SAndroid Build Coastguard Worker    resources_file = os.path.join(temp_dir, 'resources-inputs.txt')
90*8975f5c5SAndroid Build Coastguard Worker    dexes_file = os.path.join(temp_dir, 'dexes-inputs.txt')
91*8975f5c5SAndroid Build Coastguard Worker
92*8975f5c5SAndroid Build Coastguard Worker    _WritePaths(manifests_file, options.android_manifests)
93*8975f5c5SAndroid Build Coastguard Worker    _WritePaths(resources_file, dep_subdirs)
94*8975f5c5SAndroid Build Coastguard Worker    _WritePaths(dexes_file, options.dexes)
95*8975f5c5SAndroid Build Coastguard Worker
96*8975f5c5SAndroid Build Coastguard Worker    cmd = [
97*8975f5c5SAndroid Build Coastguard Worker        options.script,
98*8975f5c5SAndroid Build Coastguard Worker        '--rtxts',
99*8975f5c5SAndroid Build Coastguard Worker        options.r_text_in,
100*8975f5c5SAndroid Build Coastguard Worker        '--manifests',
101*8975f5c5SAndroid Build Coastguard Worker        manifests_file,
102*8975f5c5SAndroid Build Coastguard Worker        '--resourceDirs',
103*8975f5c5SAndroid Build Coastguard Worker        resources_file,
104*8975f5c5SAndroid Build Coastguard Worker        '--dexes',
105*8975f5c5SAndroid Build Coastguard Worker        dexes_file,
106*8975f5c5SAndroid Build Coastguard Worker        '--outputConfig',
107*8975f5c5SAndroid Build Coastguard Worker        options.output_config,
108*8975f5c5SAndroid Build Coastguard Worker    ]
109*8975f5c5SAndroid Build Coastguard Worker    if options.proguard_mapping:
110*8975f5c5SAndroid Build Coastguard Worker      cmd += [
111*8975f5c5SAndroid Build Coastguard Worker          '--mapping',
112*8975f5c5SAndroid Build Coastguard Worker          options.proguard_mapping,
113*8975f5c5SAndroid Build Coastguard Worker      ]
114*8975f5c5SAndroid Build Coastguard Worker    build_utils.CheckOutput(cmd)
115*8975f5c5SAndroid Build Coastguard Worker
116*8975f5c5SAndroid Build Coastguard Worker  if options.r_text_out:
117*8975f5c5SAndroid Build Coastguard Worker    _FilterUnusedResources(options.r_text_in, options.r_text_out,
118*8975f5c5SAndroid Build Coastguard Worker                           options.output_config)
119*8975f5c5SAndroid Build Coastguard Worker
120*8975f5c5SAndroid Build Coastguard Worker  if options.depfile:
121*8975f5c5SAndroid Build Coastguard Worker    depfile_deps = (options.dependencies_res_zips + options.android_manifests +
122*8975f5c5SAndroid Build Coastguard Worker                    options.dexes) + [options.r_text_in]
123*8975f5c5SAndroid Build Coastguard Worker    if options.proguard_mapping:
124*8975f5c5SAndroid Build Coastguard Worker      depfile_deps.append(options.proguard_mapping)
125*8975f5c5SAndroid Build Coastguard Worker    action_helpers.write_depfile(options.depfile, options.output_config,
126*8975f5c5SAndroid Build Coastguard Worker                                 depfile_deps)
127*8975f5c5SAndroid Build Coastguard Worker
128*8975f5c5SAndroid Build Coastguard Worker
129*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__':
130*8975f5c5SAndroid Build Coastguard Worker  main(sys.argv[1:])
131