Skip to content

Commit

Permalink
$(location ...) expansion and runtime data support for build scripts
Browse files Browse the repository at this point in the history
- rustc_env now expands $(rootpath //package:target), for passing
the location of files or tools that are needed at compile time
- build_script_env now expands $(execpath //package:target), for
passing the location of files or tools that are needed at build
script runtime
- cargo_script_build() now passes the data argument to the build
script runner, so the data is available at runtime

Ideally both build and run would work with execpath/location, but
the approach of walking back to the root folder that cargo_build_script()
is using doesn't seem to be possible at compile time, as ${pwd} is being
substituted after the starlark code is executed. So at compile time,
we use the relative rootpath instead.
  • Loading branch information
dae committed Oct 25, 2020
1 parent 9c889b0 commit f3d1552
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 29 deletions.
41 changes: 34 additions & 7 deletions cargo/cargo_build_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ 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, data, subfolder_level, env_string):
expanded = ctx.expand_location(env_string, data)

# if a variable was expanded, make path relative to working directory
if env_string != expanded:
expanded = "/".join([".."] * subfolder_level) + "/" + expanded
return expanded

def _expand_locations(ctx, subfolder_level):
"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, data, subfolder_level, v)) 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 +102,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, manifest_dir.count("/") + 1))

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

Expand Down Expand Up @@ -164,6 +178,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 +206,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 +239,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 +270,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 @@ -261,5 +288,5 @@ def cargo_build_script(
crate_features = crate_features,
version = version,
build_script_env = build_script_env,
deps = deps,
data = data,
)
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>Supports $(rootpath ...) expansion, so you can use this to pass in the path to a generated file or an external tool. | <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>Supports $(rootpath ...) expansion, so you can use this to pass in the path to a generated file or an external tool. | <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>Supports $(rootpath ...) expansion, so you can use this to pass in the path to a generated file or an external tool. | <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>Supports $(rootpath ...) expansion, so you can use this to pass in the path to a generated file or an external tool. | <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

0 comments on commit f3d1552

Please sign in to comment.