rustc: add arbitrary environment variables (#314)
Rules that call `rustc` setup environment variables in line with `cargo`'s behaviour (see the [documentation here](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates)). However they don't allow passing in additional environment variables that may be required at compile time, such as the [`PROTOC` variable in `prost-build`](https://github.com/danburkert/prost/blob/2de785aca480779ab0d4442d4bc91a696e3e6c89/prost-build/src/lib.rs#L689).
This PR adds the `rustc_env` attribute to the common attribute set, allowing it to be set in the following rules:
- `rust_benchmark`
- `rust_binary`
- `rust_library`
- `rust_test`
Variables are provided in a string dictionary, and will be merged into the generated environment overriding existing values.
diff --git a/proto/proto.bzl b/proto/proto.bzl
index f4174e2..680d9af 100644
--- a/proto/proto.bzl
+++ b/proto/proto.bzl
@@ -171,6 +171,7 @@
aliases = {},
output = rust_lib,
edition = proto_toolchain.edition,
+ rustc_env = {},
),
output_hash = output_hash,
)
diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl
index bf871f6..7d01d1a 100644
--- a/rust/private/rust.bzl
+++ b/rust/private/rust.bzl
@@ -134,6 +134,7 @@
aliases = ctx.attr.aliases,
output = rust_lib,
edition = _get_edition(ctx, toolchain),
+ rustc_env = ctx.attr.rustc_env,
),
output_hash = output_hash,
)
@@ -159,6 +160,7 @@
aliases = ctx.attr.aliases,
output = output,
edition = _get_edition(ctx, toolchain),
+ rustc_env = ctx.attr.rustc_env,
),
)
@@ -185,6 +187,7 @@
aliases = ctx.attr.aliases,
output = test_binary,
edition = crate.edition,
+ rustc_env = ctx.attr.rustc_env,
)
elif len(ctx.attr.deps) == 1 and len(ctx.files.srcs) == 0:
dep = ctx.attr.deps[0].label
@@ -204,6 +207,7 @@
aliases = ctx.attr.aliases,
output = test_binary,
edition = _get_edition(ctx, toolchain),
+ rustc_env = ctx.attr.rustc_env,
)
return rustc_compile_action(
@@ -298,6 +302,11 @@
These are other `rust_library` targets and will be presented as the new name given.
"""),
),
+ "rustc_env": attr.string_dict(
+ doc = _tidy("""
+ Dictionary of additional `"key": "value"` environment variables to set for rustc.
+ """),
+ ),
"crate_features": attr.string_list(
doc = _tidy("""
List of features to enable for this crate.
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl
index 3c3a1e4..543a92a 100644
--- a/rust/private/rustc.bzl
+++ b/rust/private/rustc.bzl
@@ -35,6 +35,7 @@
"aliases": "Dict[Label, String]: Renamed and aliased crates",
"output": "File: The output File that will be produced, depends on crate type.",
"edition": "str: The edition of this crate.",
+ "rustc_env": """Dict[String, String]: Additional `"key": "value"` environment variables to set for rustc.""",
},
)
@@ -330,6 +331,9 @@
else:
formatted_version = ""
+ # Update environment with user provided variables.
+ env.update(crate_info.rustc_env)
+
ctx.actions.run_shell(
command = command,
inputs = compile_inputs,
diff --git a/test/build_env/BUILD b/test/build_env/BUILD
index 803787e..55496c9 100644
--- a/test/build_env/BUILD
+++ b/test/build_env/BUILD
@@ -10,3 +10,11 @@
srcs = ["tests/manifest_dir.rs"],
data = ["src/manifest_dir_file.txt"],
)
+
+rust_test(
+ name = "arbitrary_env_test",
+ srcs = ["tests/arbitrary_env.rs"],
+ rustc_env = {
+ "USER_DEFINED_KEY": "USER_DEFINED_VALUE",
+ },
+)
diff --git a/test/build_env/tests/arbitrary_env.rs b/test/build_env/tests/arbitrary_env.rs
new file mode 100644
index 0000000..1b9ab23
--- /dev/null
+++ b/test/build_env/tests/arbitrary_env.rs
@@ -0,0 +1,6 @@
+#[test]
+pub fn test_arbitrary_env() {
+ let actual = env!("USER_DEFINED_KEY");
+ let expected = "USER_DEFINED_VALUE".to_owned();
+ assert_eq!(actual, expected);
+}