xref: /aosp_15_r20/external/cronet/build/util/action_remote.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*6777b538SAndroid Build Coastguard Worker# Copyright 2022 The Chromium Authors
3*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file.
5*6777b538SAndroid Build Coastguard Worker"""Wrapper script to run action remotely through rewrapper with gn.
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard WorkerAlso includes Chromium-specific input processors which don't make sense to
8*6777b538SAndroid Build Coastguard Workerbe reclient inbuilt input processors."""
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Workerimport argparse
11*6777b538SAndroid Build Coastguard Workerimport json
12*6777b538SAndroid Build Coastguard Workerimport os
13*6777b538SAndroid Build Coastguard Workerimport subprocess
14*6777b538SAndroid Build Coastguard Workerimport sys
15*6777b538SAndroid Build Coastguard Workerfrom enum import Enum
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker_THIS_DIR = os.path.realpath(os.path.dirname(__file__))
18*6777b538SAndroid Build Coastguard Worker_SRC_DIR = os.path.dirname(os.path.dirname(_THIS_DIR))
19*6777b538SAndroid Build Coastguard Worker_MOJOM_DIR = os.path.join(_SRC_DIR, 'mojo', 'public', 'tools', 'mojom')
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker
22*6777b538SAndroid Build Coastguard Workerclass CustomProcessor(Enum):
23*6777b538SAndroid Build Coastguard Worker  mojom_parser = 'mojom_parser'
24*6777b538SAndroid Build Coastguard Worker
25*6777b538SAndroid Build Coastguard Worker  def __str__(self):
26*6777b538SAndroid Build Coastguard Worker    return self.value
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Workerdef _normalize_path(path):
30*6777b538SAndroid Build Coastguard Worker  # Always use posix-style directory separators as GN does it.
31*6777b538SAndroid Build Coastguard Worker  return os.path.normpath(path).replace("\\", "/")
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard Worker
34*6777b538SAndroid Build Coastguard Workerdef _process_build_metadata_json(bm_file, input_roots, output_root,
35*6777b538SAndroid Build Coastguard Worker                                 output_files, processed_inputs):
36*6777b538SAndroid Build Coastguard Worker  """Recursively find mojom_parser inputs from a build_metadata file."""
37*6777b538SAndroid Build Coastguard Worker  # Import Mojo-specific dep here so non-Mojo remote actions don't need it.
38*6777b538SAndroid Build Coastguard Worker  if _MOJOM_DIR not in sys.path:
39*6777b538SAndroid Build Coastguard Worker    sys.path.insert(0, _MOJOM_DIR)
40*6777b538SAndroid Build Coastguard Worker  from mojom_parser import RebaseAbsolutePath
41*6777b538SAndroid Build Coastguard Worker
42*6777b538SAndroid Build Coastguard Worker  if bm_file in processed_inputs:
43*6777b538SAndroid Build Coastguard Worker    return
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker  processed_inputs.add(bm_file)
46*6777b538SAndroid Build Coastguard Worker
47*6777b538SAndroid Build Coastguard Worker  bm_dir = os.path.dirname(bm_file)
48*6777b538SAndroid Build Coastguard Worker
49*6777b538SAndroid Build Coastguard Worker  with open(bm_file) as f:
50*6777b538SAndroid Build Coastguard Worker    bm = json.load(f)
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker  # All sources and corresponding module files are inputs.
53*6777b538SAndroid Build Coastguard Worker  for s in bm["sources"]:
54*6777b538SAndroid Build Coastguard Worker    src = _normalize_path(os.path.join(bm_dir, s))
55*6777b538SAndroid Build Coastguard Worker    if src not in processed_inputs and os.path.exists(src):
56*6777b538SAndroid Build Coastguard Worker      processed_inputs.add(src)
57*6777b538SAndroid Build Coastguard Worker    src_module = _normalize_path(
58*6777b538SAndroid Build Coastguard Worker        os.path.join(
59*6777b538SAndroid Build Coastguard Worker            output_root,
60*6777b538SAndroid Build Coastguard Worker            RebaseAbsolutePath(os.path.abspath(src), input_roots) + "-module"))
61*6777b538SAndroid Build Coastguard Worker    if src_module in output_files:
62*6777b538SAndroid Build Coastguard Worker      continue
63*6777b538SAndroid Build Coastguard Worker    if src_module not in processed_inputs and os.path.exists(src_module):
64*6777b538SAndroid Build Coastguard Worker      processed_inputs.add(src_module)
65*6777b538SAndroid Build Coastguard Worker
66*6777b538SAndroid Build Coastguard Worker  # Recurse into build_metadata deps.
67*6777b538SAndroid Build Coastguard Worker  for d in bm["deps"]:
68*6777b538SAndroid Build Coastguard Worker    dep = _normalize_path(os.path.join(bm_dir, d))
69*6777b538SAndroid Build Coastguard Worker    _process_build_metadata_json(dep, input_roots, output_root, output_files,
70*6777b538SAndroid Build Coastguard Worker                                 processed_inputs)
71*6777b538SAndroid Build Coastguard Worker
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Workerdef _get_mojom_parser_inputs(exec_root, output_files, extra_args):
74*6777b538SAndroid Build Coastguard Worker  """Get mojom inputs by walking generated build_metadata files.
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Worker  This is less complexity and disk I/O compared to parsing mojom files for
77*6777b538SAndroid Build Coastguard Worker  imports and finding all imports.
78*6777b538SAndroid Build Coastguard Worker
79*6777b538SAndroid Build Coastguard Worker  Start from the root build_metadata file passed to mojom_parser's
80*6777b538SAndroid Build Coastguard Worker  --check-imports flag.
81*6777b538SAndroid Build Coastguard Worker  """
82*6777b538SAndroid Build Coastguard Worker  argparser = argparse.ArgumentParser()
83*6777b538SAndroid Build Coastguard Worker  argparser.add_argument('--check-imports', dest='check_imports', required=True)
84*6777b538SAndroid Build Coastguard Worker  argparser.add_argument('--output-root', dest='output_root', required=True)
85*6777b538SAndroid Build Coastguard Worker  argparser.add_argument('--input-root',
86*6777b538SAndroid Build Coastguard Worker                         default=[],
87*6777b538SAndroid Build Coastguard Worker                         action='append',
88*6777b538SAndroid Build Coastguard Worker                         dest='input_root_paths')
89*6777b538SAndroid Build Coastguard Worker  mojom_parser_args, _ = argparser.parse_known_args(args=extra_args)
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker  input_roots = list(map(os.path.abspath, mojom_parser_args.input_root_paths))
92*6777b538SAndroid Build Coastguard Worker  output_root = os.path.abspath(mojom_parser_args.output_root)
93*6777b538SAndroid Build Coastguard Worker  processed_inputs = set()
94*6777b538SAndroid Build Coastguard Worker  _process_build_metadata_json(mojom_parser_args.check_imports, input_roots,
95*6777b538SAndroid Build Coastguard Worker                               output_root, output_files, processed_inputs)
96*6777b538SAndroid Build Coastguard Worker
97*6777b538SAndroid Build Coastguard Worker  # Rebase paths onto rewrapper exec root.
98*6777b538SAndroid Build Coastguard Worker  return map(lambda dep: _normalize_path(os.path.relpath(dep, exec_root)),
99*6777b538SAndroid Build Coastguard Worker             processed_inputs)
100*6777b538SAndroid Build Coastguard Worker
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Workerdef main():
103*6777b538SAndroid Build Coastguard Worker  # Set up argparser with some rewrapper flags.
104*6777b538SAndroid Build Coastguard Worker  argparser = argparse.ArgumentParser(description='rewrapper executor for gn',
105*6777b538SAndroid Build Coastguard Worker                                      allow_abbrev=False)
106*6777b538SAndroid Build Coastguard Worker  argparser.add_argument('--custom_processor',
107*6777b538SAndroid Build Coastguard Worker                         type=CustomProcessor,
108*6777b538SAndroid Build Coastguard Worker                         choices=list(CustomProcessor))
109*6777b538SAndroid Build Coastguard Worker  argparser.add_argument('rewrapper_path')
110*6777b538SAndroid Build Coastguard Worker  argparser.add_argument('--input_list_paths')
111*6777b538SAndroid Build Coastguard Worker  argparser.add_argument('--output_list_paths')
112*6777b538SAndroid Build Coastguard Worker  argparser.add_argument('--exec_root')
113*6777b538SAndroid Build Coastguard Worker  parsed_args, extra_args = argparser.parse_known_args()
114*6777b538SAndroid Build Coastguard Worker
115*6777b538SAndroid Build Coastguard Worker  # This script expects to be calling rewrapper.
116*6777b538SAndroid Build Coastguard Worker  args = [parsed_args.rewrapper_path]
117*6777b538SAndroid Build Coastguard Worker
118*6777b538SAndroid Build Coastguard Worker  # Get the output files list.
119*6777b538SAndroid Build Coastguard Worker  output_files = set()
120*6777b538SAndroid Build Coastguard Worker  with open(parsed_args.output_list_paths, 'r') as file:
121*6777b538SAndroid Build Coastguard Worker    for line in file:
122*6777b538SAndroid Build Coastguard Worker      # Output files are relative to exec_root.
123*6777b538SAndroid Build Coastguard Worker      output_file = _normalize_path(
124*6777b538SAndroid Build Coastguard Worker          os.path.join(parsed_args.exec_root, line.rstrip('\n')))
125*6777b538SAndroid Build Coastguard Worker      output_files.add(output_file)
126*6777b538SAndroid Build Coastguard Worker
127*6777b538SAndroid Build Coastguard Worker  # Scan for and add explicit inputs for rewrapper if necessary.
128*6777b538SAndroid Build Coastguard Worker  # These should be in a new input list paths file, as using --inputs can fail
129*6777b538SAndroid Build Coastguard Worker  # if the list is extremely large.
130*6777b538SAndroid Build Coastguard Worker  if parsed_args.custom_processor == CustomProcessor.mojom_parser:
131*6777b538SAndroid Build Coastguard Worker    root, ext = os.path.splitext(parsed_args.input_list_paths)
132*6777b538SAndroid Build Coastguard Worker    extra_inputs = _get_mojom_parser_inputs(parsed_args.exec_root, output_files,
133*6777b538SAndroid Build Coastguard Worker                                            extra_args)
134*6777b538SAndroid Build Coastguard Worker    extra_input_list_path = '%s__extra%s' % (root, ext)
135*6777b538SAndroid Build Coastguard Worker    with open(extra_input_list_path, 'w') as file:
136*6777b538SAndroid Build Coastguard Worker      with open(parsed_args.input_list_paths, 'r') as inputs:
137*6777b538SAndroid Build Coastguard Worker        file.write(inputs.read())
138*6777b538SAndroid Build Coastguard Worker      file.write("\n".join(extra_inputs))
139*6777b538SAndroid Build Coastguard Worker    args += ["--input_list_paths=%s" % extra_input_list_path]
140*6777b538SAndroid Build Coastguard Worker  else:
141*6777b538SAndroid Build Coastguard Worker    args += ["--input_list_paths=%s" % parsed_args.input_list_paths]
142*6777b538SAndroid Build Coastguard Worker
143*6777b538SAndroid Build Coastguard Worker  # Filter out --custom_processor= which is a flag for this script,
144*6777b538SAndroid Build Coastguard Worker  # and filter out --input_list_paths= because we replace it above.
145*6777b538SAndroid Build Coastguard Worker  # Pass on the rest of the args to rewrapper.
146*6777b538SAndroid Build Coastguard Worker  args_rest = filter(lambda arg: '--custom_processor=' not in arg, sys.argv[2:])
147*6777b538SAndroid Build Coastguard Worker  args += filter(lambda arg: '--input_list_paths=' not in arg, args_rest)
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker  # Run rewrapper.
150*6777b538SAndroid Build Coastguard Worker  proc = subprocess.run(args)
151*6777b538SAndroid Build Coastguard Worker  return proc.returncode
152*6777b538SAndroid Build Coastguard Worker
153*6777b538SAndroid Build Coastguard Worker
154*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__':
155*6777b538SAndroid Build Coastguard Worker  sys.exit(main())
156