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