-
Notifications
You must be signed in to change notification settings - Fork 435
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moved
cargo_dep_env
into it's own file. (#2823)
I've also added some additional tests for `cargo_build_script`.
- Loading branch information
1 parent
73b1594
commit 6450253
Showing
10 changed files
with
258 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
"""Rules for Cargo build scripts (`build.rs` files)""" | ||
|
||
load("//rust:rust_common.bzl", "BuildInfo", "DepInfo") | ||
|
||
# buildifier: disable=bzl-visibility | ||
load("//rust/private:utils.bzl", "dedent") | ||
|
||
def _cargo_dep_env_impl(ctx): | ||
empty_file = ctx.actions.declare_file(ctx.label.name + ".empty_file") | ||
empty_dir = ctx.actions.declare_directory(ctx.label.name + ".empty_dir") | ||
ctx.actions.write( | ||
output = empty_file, | ||
content = "", | ||
) | ||
ctx.actions.run( | ||
outputs = [empty_dir], | ||
executable = "true", | ||
) | ||
|
||
build_infos = [] | ||
out_dir = ctx.file.out_dir | ||
if out_dir: | ||
if not out_dir.is_directory: | ||
fail("out_dir must be a directory artifact") | ||
|
||
# BuildInfos in this list are collected up for all transitive cargo_build_script | ||
# dependencies. This is important for any flags set in `dep_env` which reference this | ||
# `out_dir`. | ||
# | ||
# TLDR: This BuildInfo propagates up build script dependencies. | ||
build_infos.append(BuildInfo( | ||
dep_env = empty_file, | ||
flags = empty_file, | ||
linker_flags = empty_file, | ||
link_search_paths = empty_file, | ||
out_dir = out_dir, | ||
rustc_env = empty_file, | ||
compile_data = depset([]), | ||
)) | ||
return [ | ||
DefaultInfo(files = depset(ctx.files.src)), | ||
# Parts of this BuildInfo is used when building all transitive dependencies | ||
# (cargo_build_script and otherwise), alongside the DepInfo. This is how other rules | ||
# identify this one as a valid dependency, but we don't otherwise have a use for it. | ||
# | ||
# TLDR: This BuildInfo propagates up normal (non build script) depenencies. | ||
# | ||
# In the future, we could consider setting rustc_env here, and also propagating dep_dir | ||
# so files in it can be referenced there. | ||
BuildInfo( | ||
dep_env = empty_file, | ||
flags = empty_file, | ||
linker_flags = empty_file, | ||
link_search_paths = empty_file, | ||
out_dir = None, | ||
rustc_env = empty_file, | ||
compile_data = depset([]), | ||
), | ||
# Information here is used directly by dependencies, and it is an error to have more than | ||
# one dependency which sets this. This is the main way to specify information from build | ||
# scripts, which is what we're looking to do. | ||
DepInfo( | ||
dep_env = ctx.file.src, | ||
direct_crates = depset(), | ||
link_search_path_files = depset(), | ||
transitive_build_infos = depset(direct = build_infos), | ||
transitive_crate_outputs = depset(), | ||
transitive_crates = depset(), | ||
transitive_noncrates = depset(), | ||
), | ||
] | ||
|
||
cargo_dep_env = rule( | ||
implementation = _cargo_dep_env_impl, | ||
doc = ( | ||
"A rule for generating variables for dependent `cargo_build_script`s " + | ||
"without a build script. This is useful for using Bazel rules instead " + | ||
"of a build script, while also generating configuration information " + | ||
"for build scripts which depend on this crate." | ||
), | ||
attrs = { | ||
"out_dir": attr.label( | ||
doc = dedent("""\ | ||
Folder containing additional inputs when building all direct dependencies. | ||
This has the same effect as a `cargo_build_script` which prints | ||
puts files into `$OUT_DIR`, but without requiring a build script. | ||
"""), | ||
allow_single_file = True, | ||
mandatory = False, | ||
), | ||
"src": attr.label( | ||
doc = dedent("""\ | ||
File containing additional environment variables to set for build scripts of direct dependencies. | ||
This has the same effect as a `cargo_build_script` which prints | ||
`cargo:VAR=VALUE` lines, but without requiring a build script. | ||
This files should contain a single variable per line, of format | ||
`NAME=value`, and newlines may be included in a value by ending a | ||
line with a trailing back-slash (`\\\\`). | ||
"""), | ||
allow_single_file = True, | ||
mandatory = True, | ||
), | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
load("@bazel_skylib//rules:write_file.bzl", "write_file") | ||
load("//cargo:defs.bzl", "cargo_build_script") | ||
load("//rust:defs.bzl", "rust_test") | ||
|
||
write_file( | ||
name = "target_data", | ||
out = "target_data.txt", | ||
content = ["la-li-lu-le-lo"], | ||
) | ||
|
||
write_file( | ||
name = "exec_data", | ||
out = "exec_data.txt", | ||
content = ["la-li-lu-le-lo"], | ||
) | ||
|
||
cargo_build_script( | ||
name = "build_rs", | ||
srcs = ["build.rs"], | ||
build_script_env = { | ||
"DATA_EXECPATH": "$(execpath target_data.txt)", | ||
"DATA_RLOCATIONPATH": "$(rlocationpath target_data.txt)", | ||
"DATA_ROOTPATH": "$(rootpath target_data.txt)", | ||
"TOOL_EXECPATH": "$(execpath exec_data.txt)", | ||
"TOOL_RLOCATIONPATH": "$(rlocationpath exec_data.txt)", | ||
"TOOL_ROOTPATH": "$(rootpath exec_data.txt)", | ||
}, | ||
data = ["target_data.txt"], | ||
edition = "2018", | ||
tools = ["exec_data.txt"], | ||
) | ||
|
||
rust_test( | ||
name = "test", | ||
srcs = ["test.rs"], | ||
edition = "2018", | ||
deps = [":build_rs"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
fn main() { | ||
println!( | ||
"cargo:rustc-env=DATA_ROOTPATH={}", | ||
std::env::var("DATA_ROOTPATH").expect("Environment variable not set") | ||
); | ||
println!( | ||
"cargo:rustc-env=DATA_EXECPATH={}", | ||
std::env::var("DATA_EXECPATH").expect("Environment variable not set") | ||
); | ||
println!( | ||
"cargo:rustc-env=DATA_RLOCATIONPATH={}", | ||
std::env::var("DATA_RLOCATIONPATH").expect("Environment variable not set") | ||
); | ||
println!( | ||
"cargo:rustc-env=TOOL_ROOTPATH={}", | ||
std::env::var("TOOL_ROOTPATH").expect("Environment variable not set") | ||
); | ||
println!( | ||
"cargo:rustc-env=TOOL_EXECPATH={}", | ||
std::env::var("TOOL_EXECPATH").expect("Environment variable not set") | ||
); | ||
println!( | ||
"cargo:rustc-env=TOOL_RLOCATIONPATH={}", | ||
std::env::var("TOOL_RLOCATIONPATH").expect("Environment variable not set") | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#[test] | ||
pub fn test_data_rootpath() { | ||
assert_eq!( | ||
"test/cargo_build_script/location_expansion/target_data.txt", | ||
env!("DATA_ROOTPATH") | ||
); | ||
} | ||
|
||
#[test] | ||
pub fn test_data_rlocation() { | ||
assert_eq!( | ||
"rules_rust/test/cargo_build_script/location_expansion/target_data.txt", | ||
env!("DATA_RLOCATIONPATH") | ||
); | ||
} | ||
|
||
#[test] | ||
pub fn test_tool_rootpath() { | ||
assert_eq!( | ||
"test/cargo_build_script/location_expansion/exec_data.txt", | ||
env!("TOOL_ROOTPATH") | ||
); | ||
} | ||
|
||
#[test] | ||
pub fn test_tool_rlocationpath() { | ||
assert_eq!( | ||
"rules_rust/test/cargo_build_script/location_expansion/exec_data.txt", | ||
env!("TOOL_RLOCATIONPATH") | ||
); | ||
} | ||
|
||
#[test] | ||
pub fn test_execpath() { | ||
// Replace `\` to ensure paths are consistent on Windows.` | ||
let data_execpath = env!("DATA_EXECPATH").replace('\\', "/"); | ||
let tool_execpath = env!("TOOL_EXECPATH").replace('\\', "/"); | ||
|
||
let data_path = data_execpath | ||
.split_at( | ||
data_execpath | ||
.find("/bazel-out/") | ||
.unwrap_or_else(|| panic!("Failed to parse execroot from: {}", data_execpath)), | ||
) | ||
.1; | ||
let tool_path = tool_execpath | ||
.split_at( | ||
tool_execpath | ||
.find("/bazel-out/") | ||
.unwrap_or_else(|| panic!("Failed to parse execroot from: {}", tool_execpath)), | ||
) | ||
.1; | ||
|
||
let (data_cfg, data_short_path) = data_path.split_at( | ||
data_path | ||
.find("/bin/") | ||
.unwrap_or_else(|| panic!("Failed to find bin in {}", data_path)) | ||
+ "/bin/".len(), | ||
); | ||
let (tool_cfg, tool_short_path) = tool_path.split_at( | ||
tool_path | ||
.find("/bin/") | ||
.unwrap_or_else(|| panic!("Failed to find bin in {}", tool_path)) | ||
+ "/bin/".len(), | ||
); | ||
|
||
assert_ne!( | ||
data_cfg, tool_cfg, | ||
"Data and tools should not be from the same configuration." | ||
); | ||
|
||
assert_eq!( | ||
data_short_path, | ||
"test/cargo_build_script/location_expansion/target_data.txt" | ||
); | ||
assert_eq!( | ||
tool_short_path, | ||
"test/cargo_build_script/location_expansion/exec_data.txt" | ||
); | ||
} |
Empty file.
Oops, something went wrong.