xref: /aosp_15_r20/external/angle/build/config/siso/reproxy.star (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker# -*- bazel-starlark -*-
2*8975f5c5SAndroid Build Coastguard Worker# Copyright 2023 The Chromium Authors
3*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker"""Siso configuration for rewriting remote calls into reproxy config."""
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Workerload("@builtin//encoding.star", "json")
8*8975f5c5SAndroid Build Coastguard Workerload("@builtin//path.star", "path")
9*8975f5c5SAndroid Build Coastguard Workerload("@builtin//runtime.star", "runtime")
10*8975f5c5SAndroid Build Coastguard Workerload("@builtin//struct.star", "module")
11*8975f5c5SAndroid Build Coastguard Workerload("./clang_code_coverage_wrapper.star", "clang_code_coverage_wrapper")
12*8975f5c5SAndroid Build Coastguard Workerload("./config.star", "config")
13*8975f5c5SAndroid Build Coastguard Workerload("./gn_logs.star", "gn_logs")
14*8975f5c5SAndroid Build Coastguard Workerload("./platform.star", "platform")
15*8975f5c5SAndroid Build Coastguard Workerload("./rewrapper_cfg.star", "rewrapper_cfg")
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Workerdef __filegroups(ctx):
18*8975f5c5SAndroid Build Coastguard Worker    return {}
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard Workerdef __parse_rewrapper_cmdline(ctx, cmd):
21*8975f5c5SAndroid Build Coastguard Worker    if not "rewrapper" in cmd.args[0]:
22*8975f5c5SAndroid Build Coastguard Worker        return [], "", False
23*8975f5c5SAndroid Build Coastguard Worker
24*8975f5c5SAndroid Build Coastguard Worker    # Example command:
25*8975f5c5SAndroid Build Coastguard Worker    #   ../../buildtools/reclient/rewrapper
26*8975f5c5SAndroid Build Coastguard Worker    #     -cfg=../../buildtools/reclient_cfgs/chromium-browser-clang/rewrapper_linux.cfg
27*8975f5c5SAndroid Build Coastguard Worker    #     -inputs=build/config/unsafe_buffers_paths.txt
28*8975f5c5SAndroid Build Coastguard Worker    #     -exec_root=/path/to/your/chromium/src/
29*8975f5c5SAndroid Build Coastguard Worker    #     ../../third_party/llvm-build/Release+Asserts/bin/clang++
30*8975f5c5SAndroid Build Coastguard Worker    #     [rest of clang args]
31*8975f5c5SAndroid Build Coastguard Worker    # We don't need to care about:
32*8975f5c5SAndroid Build Coastguard Worker    #   -exec_root: Siso already knows this.
33*8975f5c5SAndroid Build Coastguard Worker    wrapped_command_pos = -1
34*8975f5c5SAndroid Build Coastguard Worker    cfg_file = None
35*8975f5c5SAndroid Build Coastguard Worker    skip = ""
36*8975f5c5SAndroid Build Coastguard Worker    rw_cmd_opts = {}
37*8975f5c5SAndroid Build Coastguard Worker    for i, arg in enumerate(cmd.args):
38*8975f5c5SAndroid Build Coastguard Worker        if i == 0:
39*8975f5c5SAndroid Build Coastguard Worker            continue
40*8975f5c5SAndroid Build Coastguard Worker        if arg.startswith("-cfg="):
41*8975f5c5SAndroid Build Coastguard Worker            cfg_file = ctx.fs.canonpath(arg.removeprefix("-cfg="))
42*8975f5c5SAndroid Build Coastguard Worker            continue
43*8975f5c5SAndroid Build Coastguard Worker        if arg.startswith("-inputs=") or skip == "-inputs":
44*8975f5c5SAndroid Build Coastguard Worker            rw_cmd_opts["inputs"] = arg.removeprefix("-inputs=").split(",")
45*8975f5c5SAndroid Build Coastguard Worker            skip = ""
46*8975f5c5SAndroid Build Coastguard Worker            continue
47*8975f5c5SAndroid Build Coastguard Worker        if arg == "-inputs":
48*8975f5c5SAndroid Build Coastguard Worker            skip = arg
49*8975f5c5SAndroid Build Coastguard Worker            continue
50*8975f5c5SAndroid Build Coastguard Worker        if not arg.startswith("-"):
51*8975f5c5SAndroid Build Coastguard Worker            wrapped_command_pos = i
52*8975f5c5SAndroid Build Coastguard Worker            break
53*8975f5c5SAndroid Build Coastguard Worker    if wrapped_command_pos < 1:
54*8975f5c5SAndroid Build Coastguard Worker        fail("couldn't find first non-arg passed to rewrapper from %s" % str(cmd.args))
55*8975f5c5SAndroid Build Coastguard Worker    if not cfg_file:
56*8975f5c5SAndroid Build Coastguard Worker        fail("couldn't find rewrapper cfg file from %s" % str(cmd.args))
57*8975f5c5SAndroid Build Coastguard Worker
58*8975f5c5SAndroid Build Coastguard Worker    # Config options are the lowest prioity.
59*8975f5c5SAndroid Build Coastguard Worker    rw_opts = rewrapper_cfg.parse(ctx, cfg_file)
60*8975f5c5SAndroid Build Coastguard Worker
61*8975f5c5SAndroid Build Coastguard Worker    # TODO: Read RBE_* envvars.
62*8975f5c5SAndroid Build Coastguard Worker    if runtime.os == "windows":
63*8975f5c5SAndroid Build Coastguard Worker        # Experimenting if longer timeouts resolve slow Windows developer builds. b/335525655
64*8975f5c5SAndroid Build Coastguard Worker        rw_opts.update({
65*8975f5c5SAndroid Build Coastguard Worker            "exec_timeout": "4m",
66*8975f5c5SAndroid Build Coastguard Worker            "reclient_timeout": "8m",
67*8975f5c5SAndroid Build Coastguard Worker        })
68*8975f5c5SAndroid Build Coastguard Worker    if runtime.os == "darwin":
69*8975f5c5SAndroid Build Coastguard Worker        # Mac gets timeouts occasionally on large input uploads (likely due to large invalidations)
70*8975f5c5SAndroid Build Coastguard Worker        # b/356981080
71*8975f5c5SAndroid Build Coastguard Worker        rw_opts.update({
72*8975f5c5SAndroid Build Coastguard Worker            "exec_timeout": "3m",
73*8975f5c5SAndroid Build Coastguard Worker            "reclient_timeout": "6m",
74*8975f5c5SAndroid Build Coastguard Worker        })
75*8975f5c5SAndroid Build Coastguard Worker
76*8975f5c5SAndroid Build Coastguard Worker    # Command line options are the highest priority.
77*8975f5c5SAndroid Build Coastguard Worker    rw_opts.update(rw_cmd_opts)
78*8975f5c5SAndroid Build Coastguard Worker    return cmd.args[wrapped_command_pos:], rw_opts, True
79*8975f5c5SAndroid Build Coastguard Worker
80*8975f5c5SAndroid Build Coastguard Workerdef __parse_cros_rewrapper_cmdline(ctx, cmd):
81*8975f5c5SAndroid Build Coastguard Worker    # fix cros sdk clang command line and extract rewrapper cfg.
82*8975f5c5SAndroid Build Coastguard Worker    # Example command:
83*8975f5c5SAndroid Build Coastguard Worker    #   ../../build/cros_cache/chrome-sdk/symlinks/amd64-generic+15629.0.0+target_toolchain/bin/x86_64-cros-linux-gnu-clang++
84*8975f5c5SAndroid Build Coastguard Worker    #  -MMD -MF obj/third_party/abseil-cpp/absl/base/base/spinlock.o.d
85*8975f5c5SAndroid Build Coastguard Worker    #  ...
86*8975f5c5SAndroid Build Coastguard Worker    #  --rewrapper-path /usr/local/google/home/ukai/src/chromium/src/build/args/chromeos/rewrapper_amd64-generic
87*8975f5c5SAndroid Build Coastguard Worker    #  --rewrapper-cfg ../../buildtools/reclient_cfgs/chromium-browser-clang/rewrapper_linux.cfg
88*8975f5c5SAndroid Build Coastguard Worker    #  -pipe -march=x86-64 -msse3 ...
89*8975f5c5SAndroid Build Coastguard Worker    cfg_file = None
90*8975f5c5SAndroid Build Coastguard Worker    skip = ""
91*8975f5c5SAndroid Build Coastguard Worker    args = []
92*8975f5c5SAndroid Build Coastguard Worker    toolchainpath = None
93*8975f5c5SAndroid Build Coastguard Worker    for i, arg in enumerate(cmd.args):
94*8975f5c5SAndroid Build Coastguard Worker        if i == 0:
95*8975f5c5SAndroid Build Coastguard Worker            toolchainpath = path.dir(path.dir(ctx.fs.canonpath(arg)))
96*8975f5c5SAndroid Build Coastguard Worker            args.append(arg)
97*8975f5c5SAndroid Build Coastguard Worker            continue
98*8975f5c5SAndroid Build Coastguard Worker        if skip:
99*8975f5c5SAndroid Build Coastguard Worker            if skip == "--rewrapper-cfg":
100*8975f5c5SAndroid Build Coastguard Worker                cfg_file = ctx.fs.canonpath(arg)
101*8975f5c5SAndroid Build Coastguard Worker            skip = ""
102*8975f5c5SAndroid Build Coastguard Worker            continue
103*8975f5c5SAndroid Build Coastguard Worker        if arg in ("--rewrapper-path", "--rewrapper-cfg"):
104*8975f5c5SAndroid Build Coastguard Worker            skip = arg
105*8975f5c5SAndroid Build Coastguard Worker            continue
106*8975f5c5SAndroid Build Coastguard Worker        args.append(arg)
107*8975f5c5SAndroid Build Coastguard Worker    if not cfg_file:
108*8975f5c5SAndroid Build Coastguard Worker        fail("couldn't find rewrapper cfg file in %s" % str(cmd.args))
109*8975f5c5SAndroid Build Coastguard Worker    rwcfg = rewrapper_cfg.parse(ctx, cfg_file)
110*8975f5c5SAndroid Build Coastguard Worker    inputs = rwcfg.get("inputs", [])
111*8975f5c5SAndroid Build Coastguard Worker    inputs.extend([
112*8975f5c5SAndroid Build Coastguard Worker        path.join(toolchainpath, "bin"),
113*8975f5c5SAndroid Build Coastguard Worker        path.join(toolchainpath, "lib"),
114*8975f5c5SAndroid Build Coastguard Worker        path.join(toolchainpath, "usr/bin"),
115*8975f5c5SAndroid Build Coastguard Worker        path.join(toolchainpath, "usr/lib64/clang"),
116*8975f5c5SAndroid Build Coastguard Worker        # TODO: b/320189180 - Simple Chrome builds should use libraries under usr/lib64.
117*8975f5c5SAndroid Build Coastguard Worker        # But, Ninja/Reclient also don't use them unexpectedly.
118*8975f5c5SAndroid Build Coastguard Worker    ])
119*8975f5c5SAndroid Build Coastguard Worker    rwcfg["inputs"] = inputs
120*8975f5c5SAndroid Build Coastguard Worker    rwcfg["preserve_symlinks"] = True
121*8975f5c5SAndroid Build Coastguard Worker    return args, rwcfg
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard Worker# TODO(b/278225415): change gn so this wrapper (and by extension this handler) becomes unnecessary.
124*8975f5c5SAndroid Build Coastguard Workerdef __parse_clang_code_coverage_wrapper_cmdline(ctx, cmd):
125*8975f5c5SAndroid Build Coastguard Worker    # Example command:
126*8975f5c5SAndroid Build Coastguard Worker    #   python3
127*8975f5c5SAndroid Build Coastguard Worker    #     ../../build/toolchain/clang_code_coverage_wrapper.py
128*8975f5c5SAndroid Build Coastguard Worker    #     --target-os=...
129*8975f5c5SAndroid Build Coastguard Worker    #     --files_to_instrument=...
130*8975f5c5SAndroid Build Coastguard Worker    #     ../../buildtools/reclient/rewrapper
131*8975f5c5SAndroid Build Coastguard Worker    #     -cfg=../../buildtools/reclient_cfgs/chromium-browser-clang/rewrapper_linux.cfg
132*8975f5c5SAndroid Build Coastguard Worker    #     -inputs=build/config/unsafe_buffers_paths.txt
133*8975f5c5SAndroid Build Coastguard Worker    #     -exec_root=/path/to/your/chromium/src/
134*8975f5c5SAndroid Build Coastguard Worker    #     ../../third_party/llvm-build/Release+Asserts/bin/clang++
135*8975f5c5SAndroid Build Coastguard Worker    #     [rest of clang args]
136*8975f5c5SAndroid Build Coastguard Worker    # We don't need to care about:
137*8975f5c5SAndroid Build Coastguard Worker    #   most args to clang_code_coverage_wrapper (need --files_to_instrument as tool_input)
138*8975f5c5SAndroid Build Coastguard Worker    #   -exec_root: Siso already knows this.
139*8975f5c5SAndroid Build Coastguard Worker    rewrapper_pos = -1
140*8975f5c5SAndroid Build Coastguard Worker    wrapped_command_pos = -1
141*8975f5c5SAndroid Build Coastguard Worker    cfg_file = None
142*8975f5c5SAndroid Build Coastguard Worker    skip = None
143*8975f5c5SAndroid Build Coastguard Worker    rw_ops = {}
144*8975f5c5SAndroid Build Coastguard Worker    for i, arg in enumerate(cmd.args):
145*8975f5c5SAndroid Build Coastguard Worker        if i < 2:
146*8975f5c5SAndroid Build Coastguard Worker            continue
147*8975f5c5SAndroid Build Coastguard Worker        if rewrapper_pos == -1 and not arg.startswith("-"):
148*8975f5c5SAndroid Build Coastguard Worker            rewrapper_pos = i
149*8975f5c5SAndroid Build Coastguard Worker            continue
150*8975f5c5SAndroid Build Coastguard Worker        if rewrapper_pos > 0 and arg.startswith("-cfg="):
151*8975f5c5SAndroid Build Coastguard Worker            cfg_file = ctx.fs.canonpath(arg.removeprefix("-cfg="))
152*8975f5c5SAndroid Build Coastguard Worker            continue
153*8975f5c5SAndroid Build Coastguard Worker        if arg.startswith("-inputs=") or skip == "-inputs":
154*8975f5c5SAndroid Build Coastguard Worker            rw_ops["inputs"] = arg.removeprefix("-inputs=").split(",")
155*8975f5c5SAndroid Build Coastguard Worker            skip = ""
156*8975f5c5SAndroid Build Coastguard Worker            continue
157*8975f5c5SAndroid Build Coastguard Worker        if arg == "-inputs":
158*8975f5c5SAndroid Build Coastguard Worker            skip = arg
159*8975f5c5SAndroid Build Coastguard Worker            continue
160*8975f5c5SAndroid Build Coastguard Worker        if rewrapper_pos > 0 and not arg.startswith("-"):
161*8975f5c5SAndroid Build Coastguard Worker            wrapped_command_pos = i
162*8975f5c5SAndroid Build Coastguard Worker            break
163*8975f5c5SAndroid Build Coastguard Worker    if rewrapper_pos < 1:
164*8975f5c5SAndroid Build Coastguard Worker        fail("couldn't find rewrapper in %s" % str(cmd.args))
165*8975f5c5SAndroid Build Coastguard Worker    if wrapped_command_pos < 1:
166*8975f5c5SAndroid Build Coastguard Worker        fail("couldn't find first non-arg passed to rewrapper for %s" % str(cmd.args))
167*8975f5c5SAndroid Build Coastguard Worker    if not cfg_file:
168*8975f5c5SAndroid Build Coastguard Worker        fail("couldn't find rewrapper cfg file in %s" % str(cmd.args))
169*8975f5c5SAndroid Build Coastguard Worker    coverage_wrapper_command = cmd.args[:rewrapper_pos] + cmd.args[wrapped_command_pos:]
170*8975f5c5SAndroid Build Coastguard Worker    clang_command = clang_code_coverage_wrapper.run(ctx, list(coverage_wrapper_command))
171*8975f5c5SAndroid Build Coastguard Worker    if len(clang_command) > 1 and "/chrome-sdk/" in clang_command[0]:
172*8975f5c5SAndroid Build Coastguard Worker        # TODO: implement cros sdk support under code coverage wrapper
173*8975f5c5SAndroid Build Coastguard Worker        fail("need to fix handler for cros sdk under code coverage wrapper")
174*8975f5c5SAndroid Build Coastguard Worker    rw_cfg_opts = rewrapper_cfg.parse(ctx, cfg_file)
175*8975f5c5SAndroid Build Coastguard Worker
176*8975f5c5SAndroid Build Coastguard Worker    # Command line options have higher priority than the ones in the cfg file.
177*8975f5c5SAndroid Build Coastguard Worker    rw_cfg_opts.update(rw_ops)
178*8975f5c5SAndroid Build Coastguard Worker    return clang_command, rw_cfg_opts
179*8975f5c5SAndroid Build Coastguard Worker
180*8975f5c5SAndroid Build Coastguard Workerdef __rewrite_rewrapper(ctx, cmd, use_large = False):
181*8975f5c5SAndroid Build Coastguard Worker    # If clang-coverage, needs different handling.
182*8975f5c5SAndroid Build Coastguard Worker    if len(cmd.args) > 2 and "clang_code_coverage_wrapper.py" in cmd.args[1]:
183*8975f5c5SAndroid Build Coastguard Worker        args, rwcfg = __parse_clang_code_coverage_wrapper_cmdline(ctx, cmd)
184*8975f5c5SAndroid Build Coastguard Worker    elif len(cmd.args) > 1 and "/chrome-sdk/" in cmd.args[0]:
185*8975f5c5SAndroid Build Coastguard Worker        args, rwcfg = __parse_cros_rewrapper_cmdline(ctx, cmd)
186*8975f5c5SAndroid Build Coastguard Worker    else:
187*8975f5c5SAndroid Build Coastguard Worker        # handling for generic rewrapper.
188*8975f5c5SAndroid Build Coastguard Worker        args, rwcfg, wrapped = __parse_rewrapper_cmdline(ctx, cmd)
189*8975f5c5SAndroid Build Coastguard Worker        if not wrapped:
190*8975f5c5SAndroid Build Coastguard Worker            print("command doesn't have rewrapper. %s" % str(cmd.args))
191*8975f5c5SAndroid Build Coastguard Worker            return
192*8975f5c5SAndroid Build Coastguard Worker    if not rwcfg:
193*8975f5c5SAndroid Build Coastguard Worker        fail("couldn't find rewrapper cfg file in %s" % str(cmd.args))
194*8975f5c5SAndroid Build Coastguard Worker    if use_large:
195*8975f5c5SAndroid Build Coastguard Worker        platform = rwcfg.get("platform", {})
196*8975f5c5SAndroid Build Coastguard Worker        if platform.get("OSFamily") == "Windows":
197*8975f5c5SAndroid Build Coastguard Worker            # Since there is no large Windows workers, it needs to run locally.
198*8975f5c5SAndroid Build Coastguard Worker            ctx.actions.fix(args = args)
199*8975f5c5SAndroid Build Coastguard Worker            return
200*8975f5c5SAndroid Build Coastguard Worker        if platform:
201*8975f5c5SAndroid Build Coastguard Worker            action_key = None
202*8975f5c5SAndroid Build Coastguard Worker            for key in rwcfg["platform"]:
203*8975f5c5SAndroid Build Coastguard Worker                if key.startswith("label:action_"):
204*8975f5c5SAndroid Build Coastguard Worker                    action_key = key
205*8975f5c5SAndroid Build Coastguard Worker                    break
206*8975f5c5SAndroid Build Coastguard Worker            if action_key:
207*8975f5c5SAndroid Build Coastguard Worker                rwcfg["platform"].pop(action_key)
208*8975f5c5SAndroid Build Coastguard Worker        else:
209*8975f5c5SAndroid Build Coastguard Worker            rwcfg["platform"] = {}
210*8975f5c5SAndroid Build Coastguard Worker        rwcfg["platform"].update({
211*8975f5c5SAndroid Build Coastguard Worker            "label:action_large": "1",
212*8975f5c5SAndroid Build Coastguard Worker        })
213*8975f5c5SAndroid Build Coastguard Worker
214*8975f5c5SAndroid Build Coastguard Worker        # Some large compiles take longer than the default timeout 2m.
215*8975f5c5SAndroid Build Coastguard Worker        # same as clang_exception.star.
216*8975f5c5SAndroid Build Coastguard Worker        rwcfg["exec_timeout"] = "10m"
217*8975f5c5SAndroid Build Coastguard Worker        rwcfg["reclient_timeout"] = "10m"
218*8975f5c5SAndroid Build Coastguard Worker    ctx.actions.fix(
219*8975f5c5SAndroid Build Coastguard Worker        args = args,
220*8975f5c5SAndroid Build Coastguard Worker        reproxy_config = json.encode(rwcfg),
221*8975f5c5SAndroid Build Coastguard Worker    )
222*8975f5c5SAndroid Build Coastguard Worker
223*8975f5c5SAndroid Build Coastguard Workerdef __rewrite_rewrapper_large(ctx, cmd):
224*8975f5c5SAndroid Build Coastguard Worker    return __rewrite_rewrapper(ctx, cmd, use_large = True)
225*8975f5c5SAndroid Build Coastguard Worker
226*8975f5c5SAndroid Build Coastguard Workerdef __strip_rewrapper(ctx, cmd):
227*8975f5c5SAndroid Build Coastguard Worker    # If clang-coverage, needs different handling.
228*8975f5c5SAndroid Build Coastguard Worker    if len(cmd.args) > 2 and "clang_code_coverage_wrapper.py" in cmd.args[1]:
229*8975f5c5SAndroid Build Coastguard Worker        args, _ = __parse_clang_code_coverage_wrapper_cmdline(ctx, cmd)
230*8975f5c5SAndroid Build Coastguard Worker    else:
231*8975f5c5SAndroid Build Coastguard Worker        args, _, wrapped = __parse_rewrapper_cmdline(ctx, cmd)
232*8975f5c5SAndroid Build Coastguard Worker        if not wrapped:
233*8975f5c5SAndroid Build Coastguard Worker            print("command doesn't have rewrapper. %s" % str(cmd.args))
234*8975f5c5SAndroid Build Coastguard Worker            return
235*8975f5c5SAndroid Build Coastguard Worker    ctx.actions.fix(args = args)
236*8975f5c5SAndroid Build Coastguard Worker
237*8975f5c5SAndroid Build Coastguard Worker__handlers = {
238*8975f5c5SAndroid Build Coastguard Worker    "rewrite_rewrapper": __rewrite_rewrapper,
239*8975f5c5SAndroid Build Coastguard Worker    "rewrite_rewrapper_large": __rewrite_rewrapper_large,
240*8975f5c5SAndroid Build Coastguard Worker    "strip_rewrapper": __strip_rewrapper,
241*8975f5c5SAndroid Build Coastguard Worker}
242*8975f5c5SAndroid Build Coastguard Worker
243*8975f5c5SAndroid Build Coastguard Workerdef __use_reclient(ctx):
244*8975f5c5SAndroid Build Coastguard Worker    return gn_logs.read(ctx).get("use_reclient") == "true"
245*8975f5c5SAndroid Build Coastguard Worker
246*8975f5c5SAndroid Build Coastguard Workerdef __step_config(ctx, step_config):
247*8975f5c5SAndroid Build Coastguard Worker    # New rules to convert commands calling rewrapper to use reproxy instead.
248*8975f5c5SAndroid Build Coastguard Worker    new_rules = []
249*8975f5c5SAndroid Build Coastguard Worker
250*8975f5c5SAndroid Build Coastguard Worker    # Disable racing on builders since bots don't have many CPU cores.
251*8975f5c5SAndroid Build Coastguard Worker    # TODO: b/297807325 - Siso wants to handle local execution.
252*8975f5c5SAndroid Build Coastguard Worker    # However, Reclient's alerts require racing and local fallback to be
253*8975f5c5SAndroid Build Coastguard Worker    # done on Reproxy side.
254*8975f5c5SAndroid Build Coastguard Worker    exec_strategy = "racing"
255*8975f5c5SAndroid Build Coastguard Worker    if config.get(ctx, "builder"):
256*8975f5c5SAndroid Build Coastguard Worker        exec_strategy = "remote_local_fallback"
257*8975f5c5SAndroid Build Coastguard Worker
258*8975f5c5SAndroid Build Coastguard Worker    for rule in step_config["rules"]:
259*8975f5c5SAndroid Build Coastguard Worker        # Replace nacl-clang/clang++ rules without command_prefix, because they will incorrectly match rewrapper.
260*8975f5c5SAndroid Build Coastguard Worker        # Replace the original step rule with one that only rewrites rewrapper and convert its rewrapper config to reproxy config.
261*8975f5c5SAndroid Build Coastguard Worker        if rule["name"].find("nacl-clang") >= 0 and not rule.get("command_prefix"):
262*8975f5c5SAndroid Build Coastguard Worker            new_rule = {
263*8975f5c5SAndroid Build Coastguard Worker                "name": rule["name"],
264*8975f5c5SAndroid Build Coastguard Worker                "action": rule["action"],
265*8975f5c5SAndroid Build Coastguard Worker                "handler": "rewrite_rewrapper",
266*8975f5c5SAndroid Build Coastguard Worker            }
267*8975f5c5SAndroid Build Coastguard Worker            new_rules.append(new_rule)
268*8975f5c5SAndroid Build Coastguard Worker            continue
269*8975f5c5SAndroid Build Coastguard Worker
270*8975f5c5SAndroid Build Coastguard Worker        # clang cxx/cc/objcxx/objc will always have rewrapper config when use_remoteexec=true.
271*8975f5c5SAndroid Build Coastguard Worker        # Remove the native siso handling and replace with custom rewrapper-specific handling.
272*8975f5c5SAndroid Build Coastguard Worker        # All other rule values are not reused, instead use rewrapper config via handler.
273*8975f5c5SAndroid Build Coastguard Worker        # (In particular, command_prefix should be avoided because it will be rewrapper.)
274*8975f5c5SAndroid Build Coastguard Worker        if (rule["name"].startswith("clang/cxx") or rule["name"].startswith("clang/cc") or
275*8975f5c5SAndroid Build Coastguard Worker            rule["name"].startswith("clang-cl/cxx") or rule["name"].startswith("clang-cl/cc") or
276*8975f5c5SAndroid Build Coastguard Worker            rule["name"].startswith("clang/objc")):
277*8975f5c5SAndroid Build Coastguard Worker            if not rule.get("action"):
278*8975f5c5SAndroid Build Coastguard Worker                fail("clang rule %s found without action" % rule["name"])
279*8975f5c5SAndroid Build Coastguard Worker
280*8975f5c5SAndroid Build Coastguard Worker            new_rule = {
281*8975f5c5SAndroid Build Coastguard Worker                "name": rule["name"],
282*8975f5c5SAndroid Build Coastguard Worker                "action": rule["action"],
283*8975f5c5SAndroid Build Coastguard Worker                "exclude_input_patterns": rule.get("exclude_input_patterns"),
284*8975f5c5SAndroid Build Coastguard Worker                "handler": "rewrite_rewrapper",
285*8975f5c5SAndroid Build Coastguard Worker                "input_root_absolute_path": rule.get("input_root_absolute_path"),
286*8975f5c5SAndroid Build Coastguard Worker            }
287*8975f5c5SAndroid Build Coastguard Worker            new_rules.append(new_rule)
288*8975f5c5SAndroid Build Coastguard Worker            continue
289*8975f5c5SAndroid Build Coastguard Worker
290*8975f5c5SAndroid Build Coastguard Worker        # clang-coverage/ is handled by the rewrite_rewrapper handler of clang/{cxx, cc} action rules above, so ignore these rules.
291*8975f5c5SAndroid Build Coastguard Worker        if rule["name"].startswith("clang-coverage/"):
292*8975f5c5SAndroid Build Coastguard Worker            continue
293*8975f5c5SAndroid Build Coastguard Worker
294*8975f5c5SAndroid Build Coastguard Worker        # Add non-remote rules as-is.
295*8975f5c5SAndroid Build Coastguard Worker        if not rule.get("remote"):
296*8975f5c5SAndroid Build Coastguard Worker            new_rules.append(rule)
297*8975f5c5SAndroid Build Coastguard Worker            continue
298*8975f5c5SAndroid Build Coastguard Worker
299*8975f5c5SAndroid Build Coastguard Worker        # Finally handle remaining remote rules. It's assumed it is enough to only convert native remote config to reproxy config.
300*8975f5c5SAndroid Build Coastguard Worker        platform_ref = rule.get("platform_ref")
301*8975f5c5SAndroid Build Coastguard Worker        if platform_ref:
302*8975f5c5SAndroid Build Coastguard Worker            p = step_config["platforms"].get(platform_ref)
303*8975f5c5SAndroid Build Coastguard Worker            if not p:
304*8975f5c5SAndroid Build Coastguard Worker                fail("Rule %s uses undefined platform '%s'" % (rule["name"], platform_ref))
305*8975f5c5SAndroid Build Coastguard Worker        else:
306*8975f5c5SAndroid Build Coastguard Worker            p = step_config.get("platforms", {}).get("default")
307*8975f5c5SAndroid Build Coastguard Worker            if not p:
308*8975f5c5SAndroid Build Coastguard Worker                fail("Rule %s did not set platform_ref but no default platform exists" % rule["name"])
309*8975f5c5SAndroid Build Coastguard Worker        rule["reproxy_config"] = {
310*8975f5c5SAndroid Build Coastguard Worker            "platform": p,
311*8975f5c5SAndroid Build Coastguard Worker            "labels": {
312*8975f5c5SAndroid Build Coastguard Worker                "type": "tool",
313*8975f5c5SAndroid Build Coastguard Worker                "siso_rule": rule["name"],
314*8975f5c5SAndroid Build Coastguard Worker            },
315*8975f5c5SAndroid Build Coastguard Worker            "canonicalize_working_dir": rule.get("canonicalize_dir", False),
316*8975f5c5SAndroid Build Coastguard Worker            "exec_strategy": exec_strategy,
317*8975f5c5SAndroid Build Coastguard Worker            # TODO: crbug.com/380755128 - Make each compile unit smaller.
318*8975f5c5SAndroid Build Coastguard Worker            "exec_timeout": rule.get("timeout", "30m"),
319*8975f5c5SAndroid Build Coastguard Worker            "reclient_timeout": rule.get("timeout", "15m"),
320*8975f5c5SAndroid Build Coastguard Worker            "download_outputs": True,
321*8975f5c5SAndroid Build Coastguard Worker        }
322*8975f5c5SAndroid Build Coastguard Worker        new_rules.append(rule)
323*8975f5c5SAndroid Build Coastguard Worker
324*8975f5c5SAndroid Build Coastguard Worker    step_config["rules"] = new_rules
325*8975f5c5SAndroid Build Coastguard Worker    return step_config
326*8975f5c5SAndroid Build Coastguard Worker
327*8975f5c5SAndroid Build Coastguard Workerreproxy = module(
328*8975f5c5SAndroid Build Coastguard Worker    "reproxy",
329*8975f5c5SAndroid Build Coastguard Worker    enabled = __use_reclient,
330*8975f5c5SAndroid Build Coastguard Worker    step_config = __step_config,
331*8975f5c5SAndroid Build Coastguard Worker    filegroups = __filegroups,
332*8975f5c5SAndroid Build Coastguard Worker    handlers = __handlers,
333*8975f5c5SAndroid Build Coastguard Worker)
334