Skip to content

Commit 72b5736

Browse files
committed
add run_in_execroot flag to cargo_build_script()
Re discussion on bazelbuild#461 (review)
1 parent cb8fd0e commit 72b5736

File tree

4 files changed

+24
-18
lines changed

4 files changed

+24
-18
lines changed

cargo/cargo_build_script.bzl

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ def _build_script_impl(ctx):
6060
# OUT_DIR is set by the runner itself, rather than on the action.
6161
})
6262

63+
if ctx.attr.run_in_execroot:
64+
env["RUN_IN_EXECROOT"] = "1"
65+
6366
if ctx.attr.version:
6467
version = ctx.attr.version.split("+")[0].split(".")
6568
patch = version[2].split("-") if len(version) > 2 else [""]
@@ -174,6 +177,9 @@ _build_script_run = rule(
174177
doc = "Data or tools required by the build script.",
175178
allow_files = True,
176179
),
180+
"run_in_execroot": attr.bool(
181+
doc = "Whether to start in execroot, or the manifest dir.",
182+
),
177183
"_cc_toolchain": attr.label(
178184
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
179185
),
@@ -199,6 +205,7 @@ def cargo_build_script(
199205
deps = [],
200206
build_script_env = {},
201207
data = [],
208+
run_in_execroot = False,
202209
**kwargs):
203210
"""Compile and execute a rust build script to generate build attributes
204211
@@ -236,12 +243,14 @@ def cargo_build_script(
236243
"CARGO_PKG_VERSION": "0.1.2",
237244
},
238245
# Optional environment variables passed during build.rs execution.
239-
# The path will be relative to the folder above bazel-out, so your
240-
# build script will need to walk up the tree first - see build.rs
241-
# in examples/env_locations for a demo.
242246
build_script_env = {
243247
"SOME_TOOL_OR_FILE": "$(execroot @tool//:binary)"
244248
}
249+
# When passsing locations in, this must be set so the build script
250+
# runs relative to execroot. When not set, the build script runs
251+
# in CARGO_MANIFEST_DIR, for compatibility with crates imported
252+
# via cargo raze.
253+
run_in_execroot = True,
245254
# Optional data/tool dependencies
246255
data = ["@tool//:binary"],
247256
)
@@ -266,6 +275,7 @@ def cargo_build_script(
266275
deps (list, optional): The dependencies of the crate defined by `crate_name`.
267276
build_script_env (dict, optional): Environment variables for build scripts.
268277
data (list, optional): Files or tools needed by the build script.
278+
run_in_execroot (bool, optional): Run in execroot instead of manifest folder, for location expansion.
269279
**kwargs: Forwards to the underlying `rust_binary` rule.
270280
"""
271281
rust_binary(
@@ -284,4 +294,5 @@ def cargo_build_script(
284294
version = version,
285295
build_script_env = build_script_env,
286296
data = data,
297+
run_in_execroot = run_in_execroot,
287298
)

cargo/cargo_build_script_runner/bin.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ fn main() -> Result<(), String> {
3737
let rustc_env = env::var("RUSTC").expect("RUSTC was not set");
3838
let manifest_dir = exec_root.join(&manifest_dir_env);
3939
let rustc = exec_root.join(&rustc_env);
40+
let working_dir = if env::var("RUN_IN_EXECROOT").is_ok() {
41+
&exec_root
42+
} else {
43+
&manifest_dir
44+
};
4045

4146
match (args.next(), args.next(), args.next(), args.next(), args.next(), args.next(), args.next()) {
4247
(Some(progname), Some(crate_name), Some(out_dir), Some(envfile), Some(flagfile), Some(linkflags), Some(depenvfile)) => {
@@ -48,7 +53,7 @@ fn main() -> Result<(), String> {
4853

4954
let mut command = Command::new(exec_root.join(&progname));
5055
command
51-
.current_dir(manifest_dir.clone())
56+
.current_dir(working_dir)
5257
.envs(target_env_vars)
5358
.env("OUT_DIR", out_dir_abs)
5459
.env("CARGO_MANIFEST_DIR", manifest_dir)

examples/env_locations/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ cargo_build_script(
3030
"SOME_TOOL": "$(execpath @com_google_protobuf//:protoc)",
3131
},
3232
data = _data,
33+
run_in_execroot = True,
3334
)
3435

3536
rust_test(

examples/env_locations/build.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,17 @@
11
use std::{fs,env};
22

33
fn main() {
4-
// walk up and locate bazel-out
5-
let mut execroot = env::current_dir().unwrap();
6-
let mut should_continue = true;
7-
loop {
8-
should_continue = !execroot.ends_with("bazel-out");
9-
execroot.pop();
10-
if !should_continue {
11-
break;
12-
}
13-
}
14-
154
// our source file should be readable
16-
let path = execroot.join(env::var("SOURCE_FILE").unwrap());
5+
let path = env::var("SOURCE_FILE").unwrap();
176
let generated_data = fs::read_to_string(&path).unwrap();
187
assert_eq!(generated_data, "source\n");
198

209
// our generated data file should be readable
21-
let path = execroot.join(env::var("GENERATED_DATA").unwrap());
10+
let path = env::var("GENERATED_DATA").unwrap();
2211
let generated_data = fs::read_to_string(&path).unwrap();
2312
assert_eq!(generated_data, "hello\n");
2413

2514
// and we should be able to read (and thus execute) our tool
26-
let path = execroot.join(env::var("SOME_TOOL").unwrap());
15+
let path = env::var("SOME_TOOL").unwrap();
2716
assert_eq!(fs::read(&path).unwrap().is_empty(), false);
2817
}

0 commit comments

Comments
 (0)