Ben Segall | eb2866e | 2023-01-20 20:14:44 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # Copyright 2023 The Chromium Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | """This script is a wrapper around the ninja.py script that also |
| 6 | handles the client lifecycle safely. It will automatically start |
| 7 | reproxy before running ninja and stop reproxy when ninja stops |
| 8 | for any reason eg. build completes, keyboard interupt etc.""" |
| 9 | |
| 10 | import os |
| 11 | import subprocess |
| 12 | import sys |
| 13 | |
| 14 | import ninja |
| 15 | import gclient_paths |
| 16 | |
| 17 | |
| 18 | def find_reclient_bin_dir(): |
| 19 | tools_path = gclient_paths.GetBuildtoolsPath() |
| 20 | if not tools_path: |
| 21 | return None |
| 22 | |
| 23 | reclient_bin_dir = os.path.join(tools_path, 'reclient') |
| 24 | if os.path.isdir(reclient_bin_dir): |
| 25 | return reclient_bin_dir |
| 26 | return None |
| 27 | |
| 28 | |
| 29 | def find_reclient_cfg(): |
| 30 | tools_path = gclient_paths.GetBuildtoolsPath() |
| 31 | if not tools_path: |
| 32 | return None |
| 33 | |
| 34 | reclient_cfg = os.path.join(tools_path, 'reclient_cfgs', 'reproxy.cfg') |
| 35 | if os.path.isfile(reclient_cfg): |
| 36 | return reclient_cfg |
| 37 | return None |
| 38 | |
| 39 | |
| 40 | def run(cmd_args): |
| 41 | if os.environ.get('NINJA_SUMMARIZE_BUILD') == '1': |
| 42 | print(' '.join(cmd_args)) |
| 43 | return subprocess.call(cmd_args) |
| 44 | |
| 45 | |
| 46 | def start_reproxy(reclient_cfg, reclient_bin_dir): |
| 47 | return run([ |
| 48 | os.path.join(reclient_bin_dir, 'bootstrap'), |
| 49 | '--re_proxy=' + os.path.join(reclient_bin_dir, 'reproxy'), |
| 50 | '--cfg=' + reclient_cfg |
| 51 | ]) |
| 52 | |
| 53 | |
| 54 | def stop_reproxy(reclient_cfg, reclient_bin_dir): |
| 55 | return run([ |
| 56 | os.path.join(reclient_bin_dir, 'bootstrap'), '--shutdown', |
| 57 | '--cfg=' + reclient_cfg |
| 58 | ]) |
| 59 | |
| 60 | |
Ben Segall | c4efd8a | 2023-02-13 17:17:33 +0000 | [diff] [blame] | 61 | def find_rel_ninja_out_dir(args): |
| 62 | # Ninja uses getopt_long, which allow to intermix non-option arguments. |
| 63 | # To leave non supported parameters untouched, we do not use getopt. |
| 64 | for index, arg in enumerate(args[1:]): |
| 65 | if arg == '-C': |
| 66 | # + 1 to get the next argument and +1 because we trimmed off args[0] |
| 67 | return args[index + 2] |
| 68 | if arg.startswith('-C'): |
| 69 | # Support -Cout/Default |
| 70 | return arg[2:] |
| 71 | return '.' |
| 72 | |
| 73 | |
| 74 | def set_reproxy_path_flags(out_dir): |
| 75 | """Helper to setup the logs and cache directories for reclient |
| 76 | |
| 77 | Creates the following directory structure: |
| 78 | out_dir/ |
| 79 | .reproxy_tmp/ |
| 80 | logs/ |
| 81 | cache/ |
| 82 | |
| 83 | The following env vars are set if not already set: |
| 84 | RBE_output_dir=out_dir/.reproxy_tmp/logs |
| 85 | RBE_proxy_log_dir=out_dir/.reproxy_tmp/logs |
| 86 | RBE_log_dir=out_dir/.reproxy_tmp/logs |
| 87 | RBE_cache_dir=out_dir/.reproxy_tmp/cache |
| 88 | *Nix Only: |
| 89 | RBE_server_address=unix://out_dir/.reproxy_tmp/reproxy.sock |
| 90 | Windows Only: |
| 91 | RBE_server_address=pipe://out_dir/.reproxy_tmp/reproxy.pipe |
| 92 | """ |
| 93 | tmp_dir = os.path.abspath(os.path.join(out_dir, '.reproxy_tmp')) |
| 94 | os.makedirs(tmp_dir, exist_ok=True) |
| 95 | log_dir = os.path.join(tmp_dir, 'logs') |
| 96 | os.makedirs(log_dir, exist_ok=True) |
| 97 | os.environ.setdefault("RBE_output_dir", log_dir) |
| 98 | os.environ.setdefault("RBE_proxy_log_dir", log_dir) |
| 99 | os.environ.setdefault("RBE_log_dir", log_dir) |
| 100 | cache_dir = os.path.join(tmp_dir, 'cache') |
| 101 | os.makedirs(cache_dir, exist_ok=True) |
| 102 | os.environ.setdefault("RBE_cache_dir", cache_dir) |
| 103 | if sys.platform.startswith('win'): |
| 104 | os.environ.setdefault("RBE_server_address", |
| 105 | "pipe://%s/reproxy.pipe" % tmp_dir) |
| 106 | else: |
| 107 | os.environ.setdefault("RBE_server_address", |
| 108 | "unix://%s/reproxy.sock" % tmp_dir) |
| 109 | |
| 110 | |
Ben Segall | eb2866e | 2023-01-20 20:14:44 +0000 | [diff] [blame] | 111 | def main(argv): |
| 112 | # If use_remoteexec is set, but the reclient binaries or configs don't |
| 113 | # exist, display an error message and stop. Otherwise, the build will |
| 114 | # attempt to run with rewrapper wrapping actions, but will fail with |
| 115 | # possible non-obvious problems. |
| 116 | # As of January 2023, dev builds with reclient are not supported, so |
| 117 | # indicate that use_goma should be swapped for use_remoteexec. This |
| 118 | # message will be changed when dev builds are fully supported. |
| 119 | reclient_bin_dir = find_reclient_bin_dir() |
| 120 | reclient_cfg = find_reclient_cfg() |
| 121 | if reclient_bin_dir is None or reclient_cfg is None: |
| 122 | print(("Build is configured to use reclient but necessary binaries " |
| 123 | "or config files can't be found. Developer builds with " |
| 124 | "reclient are not yet supported. Try regenerating your " |
| 125 | "build with use_goma in place of use_remoteexec for now."), |
| 126 | file=sys.stderr) |
| 127 | return 1 |
Ben Segall | c4efd8a | 2023-02-13 17:17:33 +0000 | [diff] [blame] | 128 | try: |
| 129 | set_reproxy_path_flags(find_rel_ninja_out_dir(argv)) |
| 130 | except OSError: |
| 131 | print("Error creating reproxy_tmp in output dir", file=sys.stderr) |
| 132 | return 1 |
Ben Segall | eb2866e | 2023-01-20 20:14:44 +0000 | [diff] [blame] | 133 | reproxy_ret_code = start_reproxy(reclient_cfg, reclient_bin_dir) |
| 134 | if reproxy_ret_code != 0: |
| 135 | return reproxy_ret_code |
| 136 | try: |
| 137 | return ninja.main(argv) |
| 138 | except KeyboardInterrupt: |
Ben Segall | 6a71052 | 2023-02-24 04:52:05 +0000 | [diff] [blame^] | 139 | print("Caught User Interrupt", file=sys.stderr) |
Ben Segall | eb2866e | 2023-01-20 20:14:44 +0000 | [diff] [blame] | 140 | # Suppress python stack trace if ninja is interrupted |
| 141 | return 1 |
| 142 | finally: |
Ben Segall | 6a71052 | 2023-02-24 04:52:05 +0000 | [diff] [blame^] | 143 | print("Shutting down reproxy...", file=sys.stderr) |
Ben Segall | eb2866e | 2023-01-20 20:14:44 +0000 | [diff] [blame] | 144 | stop_reproxy(reclient_cfg, reclient_bin_dir) |
| 145 | |
| 146 | |
| 147 | if __name__ == '__main__': |
| 148 | sys.exit(main(sys.argv)) |