1*d4726bddSHONG Yifan"""Macros used for representing crates or annotations for existing crates""" 2*d4726bddSHONG Yifan 3*d4726bddSHONG Yifanload(":common_utils.bzl", "parse_alias_rule") 4*d4726bddSHONG Yifan 5*d4726bddSHONG Yifandef _workspace_member(version, sha256 = None): 6*d4726bddSHONG Yifan """Define information for extra workspace members 7*d4726bddSHONG Yifan 8*d4726bddSHONG Yifan Args: 9*d4726bddSHONG Yifan version (str): The semver of the crate to download. Must be an exact version. 10*d4726bddSHONG Yifan sha256 (str, optional): The sha256 checksum of the `.crate` file. 11*d4726bddSHONG Yifan 12*d4726bddSHONG Yifan Returns: 13*d4726bddSHONG Yifan string: A json encoded string of all inputs 14*d4726bddSHONG Yifan """ 15*d4726bddSHONG Yifan return json.encode(struct( 16*d4726bddSHONG Yifan version = version, 17*d4726bddSHONG Yifan sha256 = sha256, 18*d4726bddSHONG Yifan )) 19*d4726bddSHONG Yifan 20*d4726bddSHONG Yifandef _spec( 21*d4726bddSHONG Yifan package = None, 22*d4726bddSHONG Yifan version = None, 23*d4726bddSHONG Yifan artifact = None, 24*d4726bddSHONG Yifan lib = None, 25*d4726bddSHONG Yifan default_features = True, 26*d4726bddSHONG Yifan features = [], 27*d4726bddSHONG Yifan git = None, 28*d4726bddSHONG Yifan branch = None, 29*d4726bddSHONG Yifan tag = None, 30*d4726bddSHONG Yifan rev = None): 31*d4726bddSHONG Yifan """A constructor for a crate dependency. 32*d4726bddSHONG Yifan 33*d4726bddSHONG Yifan See [specifying dependencies][sd] in the Cargo book for more details. 34*d4726bddSHONG Yifan 35*d4726bddSHONG Yifan [sd]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html 36*d4726bddSHONG Yifan 37*d4726bddSHONG Yifan Args: 38*d4726bddSHONG Yifan package (str, optional): The explicit name of the package (used when attempting to alias a crate). 39*d4726bddSHONG Yifan version (str, optional): The exact version of the crate. Cannot be used with `git`. 40*d4726bddSHONG Yifan artifact (str, optional): Set to "bin" to pull in a binary crate as an artifact dependency. Requires a nightly Cargo. 41*d4726bddSHONG Yifan lib (bool, optional): If using `artifact = "bin"`, additionally setting `lib = True` declares a dependency on both the package's library and binary, as opposed to just the binary. 42*d4726bddSHONG Yifan default_features (bool, optional): Maps to the `default-features` flag. 43*d4726bddSHONG Yifan features (list, optional): A list of features to use for the crate 44*d4726bddSHONG Yifan git (str, optional): The Git url to use for the crate. Cannot be used with `version`. 45*d4726bddSHONG Yifan branch (str, optional): The git branch of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified. Specifying `rev` is recommended for fully-reproducible builds. 46*d4726bddSHONG Yifan tag (str, optional): The git tag of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified. Specifying `rev` is recommended for fully-reproducible builds. 47*d4726bddSHONG Yifan rev (str, optional): The git revision of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified. 48*d4726bddSHONG Yifan 49*d4726bddSHONG Yifan Returns: 50*d4726bddSHONG Yifan string: A json encoded string of all inputs 51*d4726bddSHONG Yifan """ 52*d4726bddSHONG Yifan return json.encode({ 53*d4726bddSHONG Yifan k: v 54*d4726bddSHONG Yifan for k, v in { 55*d4726bddSHONG Yifan "artifact": artifact, 56*d4726bddSHONG Yifan "branch": branch, 57*d4726bddSHONG Yifan "default_features": default_features, 58*d4726bddSHONG Yifan "features": features, 59*d4726bddSHONG Yifan "git": git, 60*d4726bddSHONG Yifan "lib": lib, 61*d4726bddSHONG Yifan "package": package, 62*d4726bddSHONG Yifan "rev": rev, 63*d4726bddSHONG Yifan "tag": tag, 64*d4726bddSHONG Yifan "version": version, 65*d4726bddSHONG Yifan }.items() 66*d4726bddSHONG Yifan # The `cargo_toml` crate parses unstable fields to a flattened 67*d4726bddSHONG Yifan # BTreeMap<String, toml::Value> and toml::Value does not support null, 68*d4726bddSHONG Yifan # so we must omit null values. 69*d4726bddSHONG Yifan if v != None 70*d4726bddSHONG Yifan }) 71*d4726bddSHONG Yifan 72*d4726bddSHONG Yifandef _assert_absolute(label): 73*d4726bddSHONG Yifan """Ensure a given label is an absolute label 74*d4726bddSHONG Yifan 75*d4726bddSHONG Yifan Args: 76*d4726bddSHONG Yifan label (Label): The label to check 77*d4726bddSHONG Yifan """ 78*d4726bddSHONG Yifan label_str = str(label) 79*d4726bddSHONG Yifan if not label_str.startswith("@"): 80*d4726bddSHONG Yifan fail("The labels must be absolute. Please update '{}'".format( 81*d4726bddSHONG Yifan label_str, 82*d4726bddSHONG Yifan )) 83*d4726bddSHONG Yifan 84*d4726bddSHONG Yifan# This should be kept in sync crate_universe/extension.bzl. 85*d4726bddSHONG Yifandef _annotation( 86*d4726bddSHONG Yifan version = "*", 87*d4726bddSHONG Yifan additive_build_file = None, 88*d4726bddSHONG Yifan additive_build_file_content = None, 89*d4726bddSHONG Yifan alias_rule = None, 90*d4726bddSHONG Yifan build_script_data = None, 91*d4726bddSHONG Yifan build_script_tools = None, 92*d4726bddSHONG Yifan build_script_data_glob = None, 93*d4726bddSHONG Yifan build_script_deps = None, 94*d4726bddSHONG Yifan build_script_env = None, 95*d4726bddSHONG Yifan build_script_proc_macro_deps = None, 96*d4726bddSHONG Yifan build_script_rundir = None, 97*d4726bddSHONG Yifan build_script_rustc_env = None, 98*d4726bddSHONG Yifan build_script_toolchains = None, 99*d4726bddSHONG Yifan compile_data = None, 100*d4726bddSHONG Yifan compile_data_glob = None, 101*d4726bddSHONG Yifan crate_features = None, 102*d4726bddSHONG Yifan data = None, 103*d4726bddSHONG Yifan data_glob = None, 104*d4726bddSHONG Yifan deps = None, 105*d4726bddSHONG Yifan extra_aliased_targets = None, 106*d4726bddSHONG Yifan gen_binaries = None, 107*d4726bddSHONG Yifan disable_pipelining = False, 108*d4726bddSHONG Yifan gen_build_script = None, 109*d4726bddSHONG Yifan patch_args = None, 110*d4726bddSHONG Yifan patch_tool = None, 111*d4726bddSHONG Yifan patches = None, 112*d4726bddSHONG Yifan proc_macro_deps = None, 113*d4726bddSHONG Yifan rustc_env = None, 114*d4726bddSHONG Yifan rustc_env_files = None, 115*d4726bddSHONG Yifan rustc_flags = None, 116*d4726bddSHONG Yifan shallow_since = None, 117*d4726bddSHONG Yifan override_targets = None): 118*d4726bddSHONG Yifan """A collection of extra attributes and settings for a particular crate 119*d4726bddSHONG Yifan 120*d4726bddSHONG Yifan Args: 121*d4726bddSHONG Yifan version (str, optional): The version or semver-conditions to match with a crate. The wildcard `*` 122*d4726bddSHONG Yifan matches any version, including prerelease versions. 123*d4726bddSHONG Yifan additive_build_file_content (str, optional): Extra contents to write to the bottom of generated BUILD files. 124*d4726bddSHONG Yifan additive_build_file (str, optional): A file containing extra contents to write to the bottom of 125*d4726bddSHONG Yifan generated BUILD files. 126*d4726bddSHONG Yifan alias_rule (str, optional): Alias rule to use instead of `native.alias()`. Overrides [render_config](#render_config)'s 127*d4726bddSHONG Yifan 'default_alias_rule'. 128*d4726bddSHONG Yifan build_script_data (list, optional): A list of labels to add to a crate's `cargo_build_script::data` attribute. 129*d4726bddSHONG Yifan build_script_tools (list, optional): A list of labels to add to a crate's `cargo_build_script::tools` attribute. 130*d4726bddSHONG Yifan build_script_data_glob (list, optional): A list of glob patterns to add to a crate's `cargo_build_script::data` 131*d4726bddSHONG Yifan attribute. 132*d4726bddSHONG Yifan build_script_deps (list, optional): A list of labels to add to a crate's `cargo_build_script::deps` attribute. 133*d4726bddSHONG Yifan build_script_env (dict, optional): Additional environment variables to set on a crate's 134*d4726bddSHONG Yifan `cargo_build_script::env` attribute. 135*d4726bddSHONG Yifan build_script_proc_macro_deps (list, optional): A list of labels to add to a crate's 136*d4726bddSHONG Yifan `cargo_build_script::proc_macro_deps` attribute. 137*d4726bddSHONG Yifan build_script_rundir (str, optional): An override for the build script's rundir attribute. 138*d4726bddSHONG Yifan build_script_rustc_env (dict, optional): Additional environment variables to set on a crate's 139*d4726bddSHONG Yifan `cargo_build_script::env` attribute. 140*d4726bddSHONG Yifan build_script_toolchains (list, optional): A list of labels to set on a crates's `cargo_build_script::toolchains` attribute. 141*d4726bddSHONG Yifan compile_data (list, optional): A list of labels to add to a crate's `rust_library::compile_data` attribute. 142*d4726bddSHONG Yifan compile_data_glob (list, optional): A list of glob patterns to add to a crate's `rust_library::compile_data` 143*d4726bddSHONG Yifan attribute. 144*d4726bddSHONG Yifan crate_features (optional): A list of strings to add to a crate's `rust_library::crate_features` 145*d4726bddSHONG Yifan attribute. 146*d4726bddSHONG Yifan data (list, optional): A list of labels to add to a crate's `rust_library::data` attribute. 147*d4726bddSHONG Yifan data_glob (list, optional): A list of glob patterns to add to a crate's `rust_library::data` attribute. 148*d4726bddSHONG Yifan deps (list, optional): A list of labels to add to a crate's `rust_library::deps` attribute. 149*d4726bddSHONG Yifan extra_aliased_targets (dict, optional): A list of targets to add to the generated aliases in the root 150*d4726bddSHONG Yifan crate_universe repository. 151*d4726bddSHONG Yifan gen_binaries (list or bool, optional): As a list, the subset of the crate's bins that should get `rust_binary` 152*d4726bddSHONG Yifan targets produced. Or `True` to generate all, `False` to generate none. 153*d4726bddSHONG Yifan disable_pipelining (bool, optional): If True, disables pipelining for library targets for this crate. 154*d4726bddSHONG Yifan gen_build_script (bool, optional): An authorative flag to determine whether or not to produce 155*d4726bddSHONG Yifan `cargo_build_script` targets for the current crate. 156*d4726bddSHONG Yifan patch_args (list, optional): The `patch_args` attribute of a Bazel repository rule. See 157*d4726bddSHONG Yifan [http_archive.patch_args](https://docs.bazel.build/versions/main/repo/http.html#http_archive-patch_args) 158*d4726bddSHONG Yifan patch_tool (string, optional): The `patch_tool` attribute of a Bazel repository rule. See 159*d4726bddSHONG Yifan [http_archive.patch_tool](https://docs.bazel.build/versions/main/repo/http.html#http_archive-patch_tool) 160*d4726bddSHONG Yifan patches (list, optional): The `patches` attribute of a Bazel repository rule. See 161*d4726bddSHONG Yifan [http_archive.patches](https://docs.bazel.build/versions/main/repo/http.html#http_archive-patches) 162*d4726bddSHONG Yifan proc_macro_deps (list, optional): A list of labels to add to a crate's `rust_library::proc_macro_deps` 163*d4726bddSHONG Yifan attribute. 164*d4726bddSHONG Yifan rustc_env (dict, optional): Additional variables to set on a crate's `rust_library::rustc_env` attribute. 165*d4726bddSHONG Yifan rustc_env_files (list, optional): A list of labels to set on a crate's `rust_library::rustc_env_files` 166*d4726bddSHONG Yifan attribute. 167*d4726bddSHONG Yifan rustc_flags (list, optional): A list of strings to set on a crate's `rust_library::rustc_flags` attribute. 168*d4726bddSHONG Yifan shallow_since (str, optional): An optional timestamp used for crates originating from a git repository 169*d4726bddSHONG Yifan instead of a crate registry. This flag optimizes fetching the source code. 170*d4726bddSHONG Yifan override_targets (dict, optional): A dictionary of alternate tagets to use when something depends on this crate to allow 171*d4726bddSHONG Yifan the parent repo to provide its own version of this dependency. Keys can be `proc_marco`, `build_script`, `lib`, `bin`. 172*d4726bddSHONG Yifan 173*d4726bddSHONG Yifan Returns: 174*d4726bddSHONG Yifan string: A json encoded string containing the specified version and separately all other inputs. 175*d4726bddSHONG Yifan """ 176*d4726bddSHONG Yifan if additive_build_file: 177*d4726bddSHONG Yifan _assert_absolute(additive_build_file) 178*d4726bddSHONG Yifan if patches: 179*d4726bddSHONG Yifan for patch in patches: 180*d4726bddSHONG Yifan _assert_absolute(patch) 181*d4726bddSHONG Yifan 182*d4726bddSHONG Yifan return json.encode(( 183*d4726bddSHONG Yifan version, 184*d4726bddSHONG Yifan struct( 185*d4726bddSHONG Yifan additive_build_file = _stringify_label(additive_build_file), 186*d4726bddSHONG Yifan additive_build_file_content = additive_build_file_content, 187*d4726bddSHONG Yifan alias_rule = parse_alias_rule(alias_rule), 188*d4726bddSHONG Yifan build_script_data = _stringify_list(build_script_data), 189*d4726bddSHONG Yifan build_script_tools = _stringify_list(build_script_tools), 190*d4726bddSHONG Yifan build_script_data_glob = build_script_data_glob, 191*d4726bddSHONG Yifan build_script_deps = _stringify_list(build_script_deps), 192*d4726bddSHONG Yifan build_script_env = build_script_env, 193*d4726bddSHONG Yifan build_script_proc_macro_deps = _stringify_list(build_script_proc_macro_deps), 194*d4726bddSHONG Yifan build_script_rundir = build_script_rundir, 195*d4726bddSHONG Yifan build_script_rustc_env = build_script_rustc_env, 196*d4726bddSHONG Yifan build_script_toolchains = _stringify_list(build_script_toolchains), 197*d4726bddSHONG Yifan compile_data = _stringify_list(compile_data), 198*d4726bddSHONG Yifan compile_data_glob = compile_data_glob, 199*d4726bddSHONG Yifan crate_features = crate_features, 200*d4726bddSHONG Yifan data = _stringify_list(data), 201*d4726bddSHONG Yifan data_glob = data_glob, 202*d4726bddSHONG Yifan deps = _stringify_list(deps), 203*d4726bddSHONG Yifan extra_aliased_targets = extra_aliased_targets, 204*d4726bddSHONG Yifan gen_binaries = gen_binaries, 205*d4726bddSHONG Yifan disable_pipelining = disable_pipelining, 206*d4726bddSHONG Yifan gen_build_script = gen_build_script, 207*d4726bddSHONG Yifan patch_args = patch_args, 208*d4726bddSHONG Yifan patch_tool = patch_tool, 209*d4726bddSHONG Yifan patches = _stringify_list(patches), 210*d4726bddSHONG Yifan proc_macro_deps = _stringify_list(proc_macro_deps), 211*d4726bddSHONG Yifan rustc_env = rustc_env, 212*d4726bddSHONG Yifan rustc_env_files = _stringify_list(rustc_env_files), 213*d4726bddSHONG Yifan rustc_flags = rustc_flags, 214*d4726bddSHONG Yifan shallow_since = shallow_since, 215*d4726bddSHONG Yifan override_targets = override_targets, 216*d4726bddSHONG Yifan ), 217*d4726bddSHONG Yifan )) 218*d4726bddSHONG Yifan 219*d4726bddSHONG Yifandef _stringify_label(value): 220*d4726bddSHONG Yifan if not value: 221*d4726bddSHONG Yifan return value 222*d4726bddSHONG Yifan return str(value) 223*d4726bddSHONG Yifan 224*d4726bddSHONG Yifan# In bzlmod, attributes of type `attr.label_list` end up as `Label`s not `str`, 225*d4726bddSHONG Yifan# and the `json` module doesn't know how to serialize `Label`s, 226*d4726bddSHONG Yifan# so we proactively convert them to strings before serializing. 227*d4726bddSHONG Yifandef _stringify_list(values): 228*d4726bddSHONG Yifan if not values: 229*d4726bddSHONG Yifan return values 230*d4726bddSHONG Yifan return [str(x) for x in values] 231*d4726bddSHONG Yifan 232*d4726bddSHONG Yifandef _select(common, selects): 233*d4726bddSHONG Yifan """A Starlark Select for `crate.annotation()`. 234*d4726bddSHONG Yifan 235*d4726bddSHONG Yifan Args: 236*d4726bddSHONG Yifan common: A value that applies to all configurations. 237*d4726bddSHONG Yifan selects (dict): A dict of `target_triple` to values. 238*d4726bddSHONG Yifan 239*d4726bddSHONG Yifan Returns: 240*d4726bddSHONG Yifan struct: A struct representing the Starlark Select. 241*d4726bddSHONG Yifan """ 242*d4726bddSHONG Yifan return struct( 243*d4726bddSHONG Yifan common = common, 244*d4726bddSHONG Yifan selects = selects, 245*d4726bddSHONG Yifan ) 246*d4726bddSHONG Yifan 247*d4726bddSHONG Yifancrate = struct( 248*d4726bddSHONG Yifan spec = _spec, 249*d4726bddSHONG Yifan annotation = _annotation, 250*d4726bddSHONG Yifan workspace_member = _workspace_member, 251*d4726bddSHONG Yifan select = _select, 252*d4726bddSHONG Yifan) 253