1"""Rules for Cargo build scripts (`build.rs` files)""" 2 3load( 4 "//cargo/private:cargo_build_script.bzl", 5 "name_to_crate_name", 6 "name_to_pkg_name", 7 _build_script_run = "cargo_build_script", 8) 9load("//rust:defs.bzl", "rust_binary") 10 11def cargo_build_script( 12 name, 13 edition = None, 14 crate_name = None, 15 crate_root = None, 16 srcs = [], 17 crate_features = [], 18 version = None, 19 deps = [], 20 link_deps = [], 21 proc_macro_deps = [], 22 build_script_env = {}, 23 data = [], 24 compile_data = [], 25 tools = [], 26 links = None, 27 rundir = None, 28 rustc_env = {}, 29 rustc_env_files = [], 30 rustc_flags = [], 31 visibility = None, 32 tags = None, 33 aliases = None, 34 **kwargs): 35 """Compile and execute a rust build script to generate build attributes 36 37 This rules take the same arguments as rust_binary. 38 39 Example: 40 41 Suppose you have a crate with a cargo build script `build.rs`: 42 43 ```output 44 [workspace]/ 45 hello_lib/ 46 BUILD 47 build.rs 48 src/ 49 lib.rs 50 ``` 51 52 Then you want to use the build script in the following: 53 54 `hello_lib/BUILD`: 55 ```python 56 package(default_visibility = ["//visibility:public"]) 57 58 load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library") 59 load("@rules_rust//cargo:defs.bzl", "cargo_build_script") 60 61 # This will run the build script from the root of the workspace, and 62 # collect the outputs. 63 cargo_build_script( 64 name = "build_script", 65 srcs = ["build.rs"], 66 # Optional environment variables passed during build.rs compilation 67 rustc_env = { 68 "CARGO_PKG_VERSION": "0.1.2", 69 }, 70 # Optional environment variables passed during build.rs execution. 71 # Note that as the build script's working directory is not execroot, 72 # execpath/location will return an absolute path, instead of a relative 73 # one. 74 build_script_env = { 75 "SOME_TOOL_OR_FILE": "$(execpath @tool//:binary)" 76 }, 77 # Optional data/tool dependencies 78 data = ["@tool//:binary"], 79 ) 80 81 rust_library( 82 name = "hello_lib", 83 srcs = [ 84 "src/lib.rs", 85 ], 86 deps = [":build_script"], 87 ) 88 ``` 89 90 The `hello_lib` target will be build with the flags and the environment variables declared by the \ 91 build script in addition to the file generated by it. 92 93 Args: 94 name (str): The name for the underlying rule. This should be the name of the package 95 being compiled, optionally with a suffix of `_build_script`. 96 edition (str): The rust edition to use for the internal binary crate. 97 crate_name (str): Crate name to use for build script. 98 crate_root (label): The file that will be passed to rustc to be used for building this crate. 99 srcs (list of label): Souce files of the crate to build. Passing source files here can be used to trigger rebuilds when changes are made. 100 crate_features (list, optional): A list of features to enable for the build script. 101 version (str, optional): The semantic version (semver) of the crate. 102 deps (list, optional): The build-dependencies of the crate. 103 link_deps (list, optional): The subset of the (normal) dependencies of the crate that have the 104 links attribute and therefore provide environment variables to this build script. 105 proc_macro_deps (list of label, optional): List of rust_proc_macro targets used to build the script. 106 build_script_env (dict, optional): Environment variables for build scripts. 107 data (list, optional): Files needed by the build script. 108 compile_data (list, optional): Files needed for the compilation of the build script. 109 tools (list, optional): Tools (executables) needed by the build script. 110 links (str, optional): Name of the native library this crate links against. 111 rundir (str, optional): A directory to `cd` to before the cargo_build_script is run. This should be a path relative to the exec root. 112 113 The default behaviour (and the behaviour if rundir is set to the empty string) is to change to the relative path corresponding to the cargo manifest directory, which replicates the normal behaviour of cargo so it is easy to write compatible build scripts. 114 115 If set to `.`, the cargo build script will run in the exec root. 116 rustc_env (dict, optional): Environment variables to set in rustc when compiling the build script. 117 rustc_env_files (list of label, optional): Files containing additional environment variables to set for rustc 118 when building the build script. 119 rustc_flags (list, optional): List of compiler flags passed to `rustc`. 120 visibility (list of label, optional): Visibility to apply to the generated build script output. 121 tags: (list of str, optional): Tags to apply to the generated build script output. 122 aliases (dict, optional): Remap crates to a new name or moniker for linkage to this target. \ 123 These are other `rust_library` targets and will be presented as the new name given. 124 **kwargs: Forwards to the underlying `rust_binary` rule. An exception is the `compatible_with` 125 attribute, which shouldn't be forwarded to the `rust_binary`, as the `rust_binary` is only 126 built and used in `exec` mode. We propagate the `compatible_with` attribute to the `_build_scirpt_run` 127 target. 128 """ 129 130 # This duplicates the code in _cargo_build_script_impl because we need to make these 131 # available both when we invoke rustc (this code) and when we run the compiled build 132 # script (_cargo_build_script_impl). https://github.com/bazelbuild/rules_rust/issues/661 133 # will hopefully remove this duplication. 134 rustc_env = dict(rustc_env) 135 if "CARGO_PKG_NAME" not in rustc_env: 136 rustc_env["CARGO_PKG_NAME"] = name_to_pkg_name(name) 137 if "CARGO_CRATE_NAME" not in rustc_env: 138 rustc_env["CARGO_CRATE_NAME"] = name_to_crate_name(name_to_pkg_name(name)) 139 140 binary_tags = [tag for tag in tags or []] 141 if "manual" not in binary_tags: 142 binary_tags.append("manual") 143 144 rust_binary( 145 name = name + "_", 146 crate_name = crate_name, 147 srcs = srcs, 148 crate_root = crate_root, 149 crate_features = crate_features, 150 deps = deps, 151 proc_macro_deps = proc_macro_deps, 152 data = data, 153 compile_data = compile_data, 154 rustc_env = rustc_env, 155 rustc_env_files = rustc_env_files, 156 rustc_flags = rustc_flags, 157 edition = edition, 158 tags = binary_tags, 159 aliases = aliases, 160 ) 161 _build_script_run( 162 name = name, 163 script = ":{}_".format(name), 164 crate_features = crate_features, 165 version = version, 166 build_script_env = build_script_env, 167 links = links, 168 deps = deps, 169 link_deps = link_deps, 170 data = data, 171 tools = tools, 172 rundir = rundir, 173 rustc_flags = rustc_flags, 174 visibility = visibility, 175 tags = tags, 176 **kwargs 177 ) 178