Skip to content

Commit cd73f34

Browse files
authored
Support CARGO_BIN_EXE env vars (#322)
* Export CARGO_BIN_EXE env vars as Cargo does These env vars point at the binaries of data dependencies. See https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates * Output binary names without - _ replacement This emulate's Cargo's behavior. Unfortunately just setting -o instead of --out-dir warns with the following (even if only one output is being built): ``` warning: due to multiple output types requested, the explicitly specified output file name will be adapted for each output type ```
1 parent 6d00e25 commit cd73f34

File tree

5 files changed

+54
-3
lines changed

5 files changed

+54
-3
lines changed

rust/private/rust.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ def _rust_binary_impl(ctx):
144144
crate_name = ctx.label.name.replace("-", "_")
145145

146146
if (toolchain.target_arch == "wasm32"):
147-
output = ctx.actions.declare_file(crate_name + ".wasm")
147+
output = ctx.actions.declare_file(ctx.label.name + ".wasm")
148148
else:
149-
output = ctx.actions.declare_file(crate_name)
149+
output = ctx.actions.declare_file(ctx.label.name)
150150

151151
return rustc_compile_action(
152152
ctx = ctx,

rust/private/rustc.bzl

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,17 +320,41 @@ def rustc_compile_action(
320320
# and use `$(pwd)` which resolves the `exec_root` at action execution time.
321321
package_dir = ctx.build_file_path[:ctx.build_file_path.rfind("/")]
322322
manifest_dir_env = "CARGO_MANIFEST_DIR=$(pwd)/{} ".format(package_dir)
323-
command = '{}{}{} "$@" --remap-path-prefix="$(pwd)"=__bazel_redacted_pwd'.format(
323+
324+
# Handle that the binary name and crate name may be different.
325+
# If a target name contains a - then cargo (and rules_rust) will generate a crate name with _ instead.
326+
# Accordingly, rustc will generate a output file (executable, or rlib, or whatever) with _ not -.
327+
# But when cargo puts a binary in the target/${config} directory, and sets environment variables like
328+
# `CARGO_BIN_EXE_${binary_name}` it will use the - version not the _ version.
329+
# So we rename the rustc-generated file (with _s) to have -s if needed.
330+
maybe_rename = ""
331+
if crate_info.type == "bin":
332+
generated_file = crate_info.name
333+
if toolchain.target_arch == "wasm32":
334+
generated_file = generated_file + ".wasm"
335+
src = "/".join([output_dir, generated_file])
336+
dst = crate_info.output.path
337+
if src != dst:
338+
maybe_rename = " && /bin/mv {src} {dst}".format(src=src, dst=dst)
339+
command = '{}{}{} "$@" --remap-path-prefix="$(pwd)"=__bazel_redacted_pwd{}'.format(
324340
manifest_dir_env,
325341
out_dir_env,
326342
toolchain.rustc.path,
343+
maybe_rename,
327344
)
328345

329346
if hasattr(ctx.attr, "version") and ctx.attr.version != "0.0.0":
330347
formatted_version = " v{}".format(ctx.attr.version)
331348
else:
332349
formatted_version = ""
333350

351+
# Make bin crate data deps available to tests.
352+
for data in getattr(ctx.attr, "data", []):
353+
if CrateInfo in data:
354+
dep_crate_info = data[CrateInfo]
355+
if dep_crate_info.type == "bin":
356+
env["CARGO_BIN_EXE_" + dep_crate_info.output.basename] = dep_crate_info.output.short_path
357+
334358
# Update environment with user provided variables.
335359
env.update(crate_info.rustc_env)
336360

test/test_env/BUILD

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
load(
2+
"//rust:rust.bzl",
3+
"rust_binary",
4+
"rust_test",
5+
)
6+
7+
rust_binary(
8+
name = "hello-world",
9+
srcs = ["src/main.rs"],
10+
edition = "2018",
11+
)
12+
13+
rust_test(
14+
name = "test",
15+
srcs = ["tests/run.rs"],
16+
data = [":hello-world"],
17+
edition = "2018",
18+
)

test/test_env/src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("Hello world");
3+
}

test/test_env/tests/run.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#[test]
2+
fn run() {
3+
let path = env!("CARGO_BIN_EXE_hello-world");
4+
let output = std::process::Command::new(path).output().expect("Failed to run process");
5+
assert_eq!(&b"Hello world\n"[..], output.stdout.as_slice());
6+
}

0 commit comments

Comments
 (0)