1# -*- bazel-starlark -*- 2# Copyright 2023 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5"""Siso configuration for rust/linux.""" 6 7load("@builtin//lib/gn.star", "gn") 8load("@builtin//path.star", "path") 9load("@builtin//runtime.star", "runtime") 10load("@builtin//struct.star", "module") 11load("./ar.star", "ar") 12load("./config.star", "config") 13load("./fuchsia.star", "fuchsia") 14load("./win_sdk.star", "win_sdk") 15 16def __filegroups(ctx): 17 fg = { 18 "third_party/rust-toolchain:toolchain": { 19 "type": "glob", 20 "includes": [ 21 "bin/rustc", 22 "lib/*.so", 23 "lib/libclang.so.*", 24 "lib/rustlib/src/rust/library/std/src/lib.rs", 25 "lib/rustlib/x86_64-unknown-linux-gnu/lib/*", 26 ], 27 }, 28 "third_party/rust:rustlib": { 29 "type": "glob", 30 "includes": [ 31 "*.rs", 32 ], 33 }, 34 "build/linux/debian_bullseye_amd64-sysroot:rustlink": { 35 "type": "glob", 36 "includes": [ 37 "*.so", 38 "*.so.*", 39 "*.o", 40 "*.a", 41 ], 42 }, 43 "third_party/llvm-build/Release+Asserts:rustlink": { 44 "type": "glob", 45 "includes": [ 46 "bin/*lld*", 47 "bin/clang", 48 "bin/clang++", 49 "lib/clang/*/share/cfi_ignorelist.txt", 50 "libclang*.a", 51 ], 52 }, 53 } 54 if fuchsia.enabled(ctx): 55 fg.update(fuchsia.filegroups(ctx)) 56 return fg 57 58def __rust_link_handler(ctx, cmd): 59 inputs = [] 60 use_android_toolchain = None 61 target = None 62 args = cmd.args 63 64 # there is a case that command line sets environment variable 65 # like `TOOL_VERSION=xxxx "python3" ..` 66 if args[0] == "/bin/sh": 67 args = args[2].split(" ") 68 for i, arg in enumerate(args): 69 if arg.startswith("--sysroot=../../third_party/fuchsia-sdk/sdk"): 70 sysroot = ctx.fs.canonpath(arg.removeprefix("--sysroot=")) 71 libpath = path.join(path.dir(sysroot), "lib") 72 inputs.extend([ 73 sysroot + ":link", 74 libpath + ":link", 75 ]) 76 elif arg.startswith("--sysroot=../../third_party/android_toolchain/ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot"): 77 use_android_toolchain = True 78 inputs.append("third_party/android_toolchain/ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot:headers") 79 if arg == "-isysroot": 80 sysroot = ctx.fs.canonpath(args[i + 1]) 81 inputs.extend([ 82 sysroot + ":link", 83 ]) 84 if arg.startswith("--target="): 85 target = arg.removeprefix("--target=") 86 if arg.startswith("-Clinker="): 87 linker = arg.removeprefix("-Clinker=") 88 if linker.startswith("\""): 89 linker = linker[1:len(linker) - 1] 90 linker_base = path.dir(path.dir(linker)) 91 92 # TODO(crbug.com/380798907): expand input_deps, instead of using label? 93 inputs.append(ctx.fs.canonpath(linker_base) + ":link") 94 if use_android_toolchain and target: 95 # e.g. target=aarch64-linux-android26 96 android_ver = "" 97 i = target.find("android") 98 if i >= 0: 99 android_ver = target[i:].removeprefix("android").removeprefix("eabi") 100 if android_ver: 101 android_arch = target.removesuffix(android_ver) 102 filegroup = "third_party/android_toolchain/ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/%s/%s:link" % (android_arch, android_ver) 103 inputs.append(filegroup) 104 105 # Replace thin archives (.lib) with -start-lib ... -end-lib in rsp file for 106 # Windows builds. 107 new_rspfile_content = None 108 is_windows = None 109 if "args.gn" in ctx.metadata: 110 gn_args = gn.args(ctx) 111 if gn_args.get("target_os") == '"win"': 112 is_windows = True 113 if runtime.os == "windows": 114 is_windows = True 115 if is_windows: 116 new_lines = [] 117 for line in str(cmd.rspfile_content).split("\n"): 118 new_elems = [] 119 for elem in line.split(" "): 120 # Parse only .lib files. 121 if not elem.endswith(".lib"): 122 new_elems.append(elem) 123 continue 124 125 # Parse files under the out dir. 126 fname = ctx.fs.canonpath(elem.removeprefix("-Clink-arg=")) 127 if not ctx.fs.exists(fname): 128 new_elems.append(elem) 129 continue 130 131 # Check if the library is generated or not. 132 # The source libs are not under the build dir. 133 build_dir = ctx.fs.canonpath("./") 134 if path.rel(build_dir, fname).startswith("../../"): 135 new_elems.append(elem) 136 continue 137 138 ents = ar.entries(ctx, fname, build_dir) 139 if not ents: 140 new_elems.append(elem) 141 continue 142 143 new_elems.append("-Clink-arg=-start-lib") 144 new_elems.extend(["-Clink-arg=" + e for e in ents]) 145 new_elems.append("-Clink-arg=-end-lib") 146 new_lines.append(" ".join(new_elems)) 147 new_rspfile_content = "\n".join(new_lines) 148 149 ctx.actions.fix(inputs = cmd.inputs + inputs, rspfile_content = new_rspfile_content or cmd.rspfile_content) 150 151def __rust_build_handler(ctx, cmd): 152 inputs = [] 153 for i, arg in enumerate(cmd.args): 154 if arg == "--src-dir": 155 inputs.append(ctx.fs.canonpath(cmd.args[i + 1])) 156 ctx.actions.fix(inputs = cmd.inputs + inputs) 157 158__handlers = { 159 "rust_link_handler": __rust_link_handler, 160 "rust_build_handler": __rust_build_handler, 161} 162 163def __step_config(ctx, step_config): 164 platform_ref = "large" # Rust actions run faster on large workers. 165 166 remote = True 167 if runtime.os != "linux": 168 remote = False 169 clang_inputs = [ 170 "build/linux/debian_bullseye_amd64-sysroot:rustlink", 171 "third_party/llvm-build/Release+Asserts:rustlink", 172 ] 173 if win_sdk.enabled(ctx): 174 clang_inputs.append(win_sdk.toolchain_dir(ctx) + ":libs") 175 176 rust_toolchain = [ 177 # TODO(b/285225184): use precomputed subtree 178 "third_party/rust-toolchain:toolchain", 179 ] 180 rust_inputs = [ 181 "build/action_helpers.py", 182 "build/gn_helpers.py", 183 "build/rust/rustc_wrapper.py", 184 ] + rust_toolchain 185 rust_indirect_inputs = { 186 "includes": [ 187 "*.h", 188 "*.o", 189 "*.rlib", 190 "*.rs", 191 "*.so", 192 ], 193 } 194 step_config["rules"].extend([ 195 { 196 "name": "rust_bin", 197 "action": "(.*_)?rust_bin", 198 "inputs": rust_inputs + clang_inputs, 199 "indirect_inputs": rust_indirect_inputs, 200 "handler": "rust_link_handler", 201 "deps": "none", # disable gcc scandeps 202 "remote": remote, 203 # "canonicalize_dir": True, # TODO(b/300352286) 204 "timeout": "2m", 205 "platform_ref": platform_ref, 206 }, 207 { 208 "name": "rust_cdylib", 209 "action": "(.*_)?rust_cdylib", 210 "inputs": rust_inputs + clang_inputs, 211 "indirect_inputs": rust_indirect_inputs, 212 "handler": "rust_link_handler", 213 "deps": "none", # disable gcc scandeps 214 "remote": remote, 215 # "canonicalize_dir": True, # TODO(b/300352286) 216 "timeout": "2m", 217 "platform_ref": platform_ref, 218 }, 219 { 220 "name": "rust_macro", 221 "action": "(.*_)?rust_macro", 222 "inputs": rust_inputs + clang_inputs, 223 "indirect_inputs": rust_indirect_inputs, 224 "handler": "rust_link_handler", 225 "deps": "none", # disable gcc scandeps 226 # "canonicalize_dir": True, # TODO(b/300352286) 227 "remote": remote, 228 "timeout": "2m", 229 "platform_ref": platform_ref, 230 }, 231 { 232 "name": "rust_rlib", 233 "action": "(.*_)?rust_rlib", 234 "inputs": rust_inputs, 235 "indirect_inputs": rust_indirect_inputs, 236 "deps": "none", # disable gcc scandeps 237 "remote": remote, 238 # "canonicalize_dir": True, # TODO(b/300352286) 239 "timeout": "2m", 240 "platform_ref": platform_ref, 241 }, 242 { 243 "name": "rust_staticlib", 244 "action": "(.*_)?rust_staticlib", 245 "inputs": rust_inputs, 246 "indirect_inputs": rust_indirect_inputs, 247 "deps": "none", # disable gcc scandeps 248 "remote": remote, 249 # "canonicalize_dir": True, # TODO(b/300352286) 250 "timeout": "2m", 251 "platform_ref": platform_ref, 252 }, 253 { 254 "name": "rust/run_build_script", 255 "command_prefix": "python3 ../../build/rust/run_build_script.py", 256 "inputs": [ 257 "third_party/rust-toolchain:toolchain", 258 "third_party/rust:rustlib", 259 ], 260 "handler": "rust_build_handler", 261 "remote": remote and config.get(ctx, "cog"), 262 "input_root_absolute_path": True, 263 "timeout": "2m", 264 }, 265 { 266 "name": "rust/find_std_rlibs", 267 "command_prefix": "python3 ../../build/rust/std/find_std_rlibs.py", 268 "inputs": [ 269 "third_party/rust-toolchain:toolchain", 270 "third_party/rust-toolchain/lib/rustlib:rlib", 271 ], 272 "remote": remote and config.get(ctx, "cog"), 273 "input_root_absolute_path": True, 274 "timeout": "2m", 275 }, 276 { 277 # rust/bindgen fails remotely when *.d does not exist. 278 # TODO(b/356496947): need to run scandeps? 279 "name": "rust/bindgen", 280 "command_prefix": "python3 ../../build/rust/run_bindgen.py", 281 "inputs": rust_toolchain + clang_inputs, 282 "remote": False, 283 "timeout": "2m", 284 }, 285 ]) 286 return step_config 287 288rust = module( 289 "rust", 290 filegroups = __filegroups, 291 handlers = __handlers, 292 step_config = __step_config, 293) 294