Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support expanding locations in rustc_env and build_script_env #461

Closed
wants to merge 9 commits into from
39 changes: 33 additions & 6 deletions cargo/cargo_build_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ load("@io_bazel_rules_rust//rust:private/rustc.bzl", "BuildInfo", "DepInfo", "ge
load("@io_bazel_rules_rust//rust:private/utils.bzl", "find_toolchain")
load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary")

def _expand_location(ctx, env, data):
if env.startswith("$(execpath ") or env.startswith("$(location "):
# build script runner will replace with execroot
return "${pwd}/" + ctx.expand_location(env, data)
else:
return env

def _expand_locations(ctx):
"Expand $(execroot ...) references in user-provided env vars."
env = ctx.attr.build_script_env
data = getattr(ctx.attr, "data", [])
return dict([(k, _expand_location(ctx, v, data)) for (k, v) in env.items()])

def _build_script_impl(ctx):
"""The implementation for the `_build_script_run` rule.

Expand Down Expand Up @@ -88,14 +101,14 @@ def _build_script_impl(ctx):
for f in ctx.attr.crate_features:
env["CARGO_FEATURE_" + f.upper().replace("-", "_")] = "1"

env.update(ctx.attr.build_script_env)
env.update(_expand_locations(ctx))

tools = depset(
direct = [
script,
ctx.executable._cargo_build_script_runner,
toolchain.rustc,
],
] + ctx.files.data,
transitive = toolchain_tools,
)

Expand Down Expand Up @@ -164,6 +177,10 @@ _build_script_run = rule(
"build_script_env": attr.string_dict(
doc = "Environment variables for build scripts.",
),
"data": attr.label_list(
doc = "Data or tools required by the build script.",
allow_files = True,
),
"_cc_toolchain": attr.label(
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
),
Expand All @@ -188,6 +205,7 @@ def cargo_build_script(
version = None,
deps = [],
build_script_env = {},
data = [],
**kwargs):
"""Compile and execute a rust build script to generate build attributes

Expand Down Expand Up @@ -220,10 +238,16 @@ def cargo_build_script(
cargo_build_script(
name = "build_script",
srcs = ["build.rs"],
# Data are shipped during execution.
data = ["src/lib.rs"],
# Environment variables passed during build.rs execution
build_script_env = {"CARGO_PKG_VERSION": "0.1.2"},
# Optional environment variables passed during build.rs compilation
rustc_env = {
"CARGO_PKG_VERSION": "0.1.2",
},
# Optional environment variables passed during build.rs execution.
build_script_env = {
"SOME_TOOL_OR_FILE": "$(execroot @tool//:binary)"
}
# Optional data/tool dependencies
data = ["@tool//:binary"],
)

rust_library(
Expand All @@ -245,13 +269,15 @@ def cargo_build_script(
version (str, optional): The semantic version (semver) of the crate.
deps (list, optional): The dependencies of the crate defined by `crate_name`.
build_script_env (dict, optional): Environment variables for build scripts.
data (list, optional): Files or tools needed by the build script.
**kwargs: Forwards to the underlying `rust_binary` rule.
"""
rust_binary(
name = name + "_script_",
crate_features = crate_features,
version = version,
deps = deps,
data = data,
**kwargs
)
_build_script_run(
Expand All @@ -262,4 +288,5 @@ def cargo_build_script(
version = version,
build_script_env = build_script_env,
deps = deps,
data = data,
dae marked this conversation as resolved.
Show resolved Hide resolved
)
11 changes: 10 additions & 1 deletion cargo/cargo_build_script_runner/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn main() -> Result<(), String> {

let mut command = Command::new(exec_root.join(&progname));
command
.current_dir(manifest_dir.clone())
.current_dir(&manifest_dir)
.envs(target_env_vars)
.env("OUT_DIR", out_dir_abs)
.env("CARGO_MANIFEST_DIR", manifest_dir)
Expand Down Expand Up @@ -92,6 +92,15 @@ fn main() -> Result<(), String> {
}
}

// replace env vars with a ${pwd} prefix with the exec_root
for (key, value) in env::vars() {
let exec_root_str = exec_root.to_str().expect("exec_root not in utf8");
if value.starts_with("${pwd}") {
env::set_var(key, value.replacen("${pwd}", exec_root_str, 1));
}
}


let output = BuildScriptOutput::from_command(&mut command).map_err(|exit_code| {
format!(
"Build script process failed{}",
Expand Down
17 changes: 12 additions & 5 deletions docs/cargo_build_script.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
## cargo_build_script

<pre>
cargo_build_script(<a href="#cargo_build_script-name">name</a>, <a href="#cargo_build_script-crate_name">crate_name</a>, <a href="#cargo_build_script-crate_features">crate_features</a>, <a href="#cargo_build_script-version">version</a>, <a href="#cargo_build_script-deps">deps</a>, <a href="#cargo_build_script-build_script_env">build_script_env</a>, <a href="#cargo_build_script-kwargs">kwargs</a>)
cargo_build_script(<a href="#cargo_build_script-name">name</a>, <a href="#cargo_build_script-crate_name">crate_name</a>, <a href="#cargo_build_script-crate_features">crate_features</a>, <a href="#cargo_build_script-version">version</a>, <a href="#cargo_build_script-deps">deps</a>, <a href="#cargo_build_script-build_script_env">build_script_env</a>, <a href="#cargo_build_script-data">data</a>, <a href="#cargo_build_script-kwargs">kwargs</a>)
</pre>

Compile and execute a rust build script to generate build attributes
Expand Down Expand Up @@ -40,10 +40,16 @@ load("@io_bazel_rules_rust//cargo:cargo_build_script.bzl", "cargo_build_script")
cargo_build_script(
name = "build_script",
srcs = ["build.rs"],
# Data are shipped during execution.
data = ["src/lib.rs"],
# Environment variables passed during build.rs execution
build_script_env = {"CARGO_PKG_VERSION": "0.1.2"},
# Optional environment variables passed during build.rs compilation
rustc_env = {
"CARGO_PKG_VERSION": "0.1.2",
},
# Optional environment variables passed during build.rs execution.
build_script_env = {
"SOME_TOOL_OR_FILE": "$(execroot @tool//:binary)"
}
# Optional data/tool dependencies
data = ["@tool//:binary"],
)

rust_library(
Expand All @@ -69,6 +75,7 @@ The `hello_lib` target will be build with the flags and the environment variable
| <a id="cargo_build_script-version"></a>version | The semantic version (semver) of the crate. | <code>None</code> |
| <a id="cargo_build_script-deps"></a>deps | The dependencies of the crate defined by <code>crate_name</code>. | <code>[]</code> |
| <a id="cargo_build_script-build_script_env"></a>build_script_env | Environment variables for build scripts. | <code>{}</code> |
| <a id="cargo_build_script-data"></a>data | Files or tools needed by the build script. | <code>[]</code> |
| <a id="cargo_build_script-kwargs"></a>kwargs | Forwards to the underlying <code>rust_binary</code> rule. | none |


27 changes: 17 additions & 10 deletions docs/flatten.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ Run the benchmark test using: `bazel run //fibonacci:fibonacci_bench`.
| <a id="rust_benchmark-edition"></a>edition | The rust edition to use for this crate. Defaults to the edition specified in the rust_toolchain. | String | optional | "" |
| <a id="rust_benchmark-out_dir_tar"></a>out_dir_tar | __Deprecated__, do not use, see [#cargo_build_script] instead. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_benchmark-proc_macro_deps"></a>proc_macro_deps | List of <code>rust_library</code> targets with kind <code>proc-macro</code> used to help build this library target. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_benchmark-rustc_env"></a>rustc_env | Dictionary of additional <code>"key": "value"</code> environment variables to set for rustc. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_benchmark-rustc_env"></a>rustc_env | Dictionary of additional <code>"key": "value"</code> environment variables to set for rustc.<br><br>rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_benchmark-rustc_flags"></a>rustc_flags | List of compiler flags passed to <code>rustc</code>. | List of strings | optional | [] |
| <a id="rust_benchmark-srcs"></a>srcs | List of Rust <code>.rs</code> source files used to build the library.<br><br>If <code>srcs</code> contains more than one file, then there must be a file either named <code>lib.rs</code>. Otherwise, <code>crate_root</code> must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_benchmark-version"></a>version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" |
Expand Down Expand Up @@ -239,7 +239,7 @@ Hello world
| <a id="rust_binary-out_binary"></a>out_binary | - | Boolean | optional | False |
| <a id="rust_binary-out_dir_tar"></a>out_dir_tar | __Deprecated__, do not use, see [#cargo_build_script] instead. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_binary-proc_macro_deps"></a>proc_macro_deps | List of <code>rust_library</code> targets with kind <code>proc-macro</code> used to help build this library target. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_binary-rustc_env"></a>rustc_env | Dictionary of additional <code>"key": "value"</code> environment variables to set for rustc. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_binary-rustc_env"></a>rustc_env | Dictionary of additional <code>"key": "value"</code> environment variables to set for rustc.<br><br>rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_binary-rustc_flags"></a>rustc_flags | List of compiler flags passed to <code>rustc</code>. | List of strings | optional | [] |
| <a id="rust_binary-srcs"></a>srcs | List of Rust <code>.rs</code> source files used to build the library.<br><br>If <code>srcs</code> contains more than one file, then there must be a file either named <code>lib.rs</code>. Otherwise, <code>crate_root</code> must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_binary-version"></a>version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" |
Expand Down Expand Up @@ -535,7 +535,7 @@ INFO: Elapsed time: 1.245s, Critical Path: 1.01s
| <a id="rust_library-edition"></a>edition | The rust edition to use for this crate. Defaults to the edition specified in the rust_toolchain. | String | optional | "" |
| <a id="rust_library-out_dir_tar"></a>out_dir_tar | __Deprecated__, do not use, see [#cargo_build_script] instead. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_library-proc_macro_deps"></a>proc_macro_deps | List of <code>rust_library</code> targets with kind <code>proc-macro</code> used to help build this library target. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_library-rustc_env"></a>rustc_env | Dictionary of additional <code>"key": "value"</code> environment variables to set for rustc. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_library-rustc_env"></a>rustc_env | Dictionary of additional <code>"key": "value"</code> environment variables to set for rustc.<br><br>rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_library-rustc_flags"></a>rustc_flags | List of compiler flags passed to <code>rustc</code>. | List of strings | optional | [] |
| <a id="rust_library-srcs"></a>srcs | List of Rust <code>.rs</code> source files used to build the library.<br><br>If <code>srcs</code> contains more than one file, then there must be a file either named <code>lib.rs</code>. Otherwise, <code>crate_root</code> must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_library-version"></a>version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" |
Expand Down Expand Up @@ -792,7 +792,7 @@ Run the test with `bazel build //hello_lib:hello_lib_test`.
| <a id="rust_test-edition"></a>edition | The rust edition to use for this crate. Defaults to the edition specified in the rust_toolchain. | String | optional | "" |
| <a id="rust_test-out_dir_tar"></a>out_dir_tar | __Deprecated__, do not use, see [#cargo_build_script] instead. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_test-proc_macro_deps"></a>proc_macro_deps | List of <code>rust_library</code> targets with kind <code>proc-macro</code> used to help build this library target. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_test-rustc_env"></a>rustc_env | Dictionary of additional <code>"key": "value"</code> environment variables to set for rustc. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_test-rustc_env"></a>rustc_env | Dictionary of additional <code>"key": "value"</code> environment variables to set for rustc.<br><br>rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_test-rustc_flags"></a>rustc_flags | List of compiler flags passed to <code>rustc</code>. | List of strings | optional | [] |
| <a id="rust_test-srcs"></a>srcs | List of Rust <code>.rs</code> source files used to build the library.<br><br>If <code>srcs</code> contains more than one file, then there must be a file either named <code>lib.rs</code>. Otherwise, <code>crate_root</code> must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_test-version"></a>version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" |
Expand Down Expand Up @@ -963,15 +963,15 @@ The tools required for the `rust_wasm_bindgen` rule.
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="rust_wasm_bindgen_toolchain-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="rust_wasm_bindgen_toolchain-bindgen"></a>bindgen | The label of a <code>bindgen</code> executable. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_wasm_bindgen_toolchain-bindgen"></a>bindgen | The label of a <code>wasm-bindgen</code> executable. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |


<a id="#cargo_build_script"></a>

## cargo_build_script

<pre>
cargo_build_script(<a href="#cargo_build_script-name">name</a>, <a href="#cargo_build_script-crate_name">crate_name</a>, <a href="#cargo_build_script-crate_features">crate_features</a>, <a href="#cargo_build_script-version">version</a>, <a href="#cargo_build_script-deps">deps</a>, <a href="#cargo_build_script-build_script_env">build_script_env</a>, <a href="#cargo_build_script-kwargs">kwargs</a>)
cargo_build_script(<a href="#cargo_build_script-name">name</a>, <a href="#cargo_build_script-crate_name">crate_name</a>, <a href="#cargo_build_script-crate_features">crate_features</a>, <a href="#cargo_build_script-version">version</a>, <a href="#cargo_build_script-deps">deps</a>, <a href="#cargo_build_script-build_script_env">build_script_env</a>, <a href="#cargo_build_script-data">data</a>, <a href="#cargo_build_script-kwargs">kwargs</a>)
</pre>

Compile and execute a rust build script to generate build attributes
Expand Down Expand Up @@ -1005,10 +1005,16 @@ load("@io_bazel_rules_rust//cargo:cargo_build_script.bzl", "cargo_build_script")
cargo_build_script(
name = "build_script",
srcs = ["build.rs"],
# Data are shipped during execution.
data = ["src/lib.rs"],
# Environment variables passed during build.rs execution
build_script_env = {"CARGO_PKG_VERSION": "0.1.2"},
# Optional environment variables passed during build.rs compilation
rustc_env = {
"CARGO_PKG_VERSION": "0.1.2",
},
# Optional environment variables passed during build.rs execution.
build_script_env = {
"SOME_TOOL_OR_FILE": "$(execroot @tool//:binary)"
}
# Optional data/tool dependencies
data = ["@tool//:binary"],
)

rust_library(
Expand All @@ -1034,6 +1040,7 @@ The `hello_lib` target will be build with the flags and the environment variable
| <a id="cargo_build_script-version"></a>version | The semantic version (semver) of the crate. | <code>None</code> |
| <a id="cargo_build_script-deps"></a>deps | The dependencies of the crate defined by <code>crate_name</code>. | <code>[]</code> |
| <a id="cargo_build_script-build_script_env"></a>build_script_env | Environment variables for build scripts. | <code>{}</code> |
| <a id="cargo_build_script-data"></a>data | Files or tools needed by the build script. | <code>[]</code> |
| <a id="cargo_build_script-kwargs"></a>kwargs | Forwards to the underlying <code>rust_binary</code> rule. | none |


Expand Down
Loading