Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions cargo/private/cargo_build_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,16 @@ def _cargo_build_script_impl(ctx):
if out_dir_volatile_basenames:
env["RULES_RUST_OUT_DIR_VOLATILE_BASENAMES"] = ":".join(out_dir_volatile_basenames)

emit_warnings_setting = ctx.attr._emit_build_script_warnings[BuildSettingInfo].value
if emit_warnings_setting == "on":
emit_warnings = True
elif emit_warnings_setting == "off":
emit_warnings = False
else:
emit_warnings = ctx.attr.emit_warnings
if not emit_warnings:
env["RULES_RUST_SUPPRESS_BUILD_SCRIPT_WARNINGS"] = "1"

ctx.actions.run(
executable = ctx.executable._cargo_build_script_runner,
arguments = [args, runfiles_args],
Expand Down Expand Up @@ -704,6 +714,16 @@ cargo_build_script = rule(
providers = [[DepInfo], [CrateGroupInfo]],
cfg = "exec",
),
"emit_warnings": attr.bool(
doc = dedent("""\
Whether to forward `cargo::warning=` lines from the build script to stderr.

Honored only when `--@rules_rust//cargo/settings:emit_build_script_warnings`
is `auto` (the default). Setting the flag to `on` or `off` overrides
this attribute for every target.
"""),
default = True,
),
"link_deps": attr.label_list(
doc = dedent("""\
The subset of the Rust (normal) dependencies of the crate that
Expand Down Expand Up @@ -776,6 +796,9 @@ cargo_build_script = rule(
"_debug_std_streams_output_group": attr.label(
default = Label("//cargo/settings:debug_std_streams_output_group"),
),
"_emit_build_script_warnings": attr.label(
default = Label("//cargo/settings:emit_build_script_warnings"),
),
"_default_use_default_shell_env": attr.label(
default = Label("//cargo/settings:use_default_shell_env"),
),
Expand Down
9 changes: 7 additions & 2 deletions cargo/private/cargo_build_script_runner/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::path::{Path, PathBuf};
use std::process::Command;

use cargo_build_script_runner::cargo_manifest_dir::{remove_symlink, symlink, RunfilesMaker};
use cargo_build_script_runner::{BuildScriptOutput, CompileAndLinkFlags};
use cargo_build_script_runner::{BuildScriptOutput, CompileAndLinkFlags, SUPPRESS_WARNINGS_ENV};

fn run_buildrs() -> Result<(), String> {
// We use exec_root.join rather than std::fs::canonicalize, to avoid resolving symlinks, as
Expand Down Expand Up @@ -158,7 +158,12 @@ fn run_buildrs() -> Result<(), String> {
);
}

let (buildrs_outputs, process_output) = BuildScriptOutput::outputs_from_command(&mut command)
let emit_warnings = env::var_os(SUPPRESS_WARNINGS_ENV).is_none_or(|v| v != "1");

let (buildrs_outputs, process_output) = BuildScriptOutput::outputs_from_command(
&mut command,
emit_warnings,
)
.map_err(|process_output| {
format!(
"Build script process failed{}\n--stdout:\n{}\n--stderr:\n{}",
Expand Down
46 changes: 30 additions & 16 deletions cargo/private/cargo_build_script_runner/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use std::io::{BufRead, BufReader, Read};
use std::process::{Command, Output};

pub const SUPPRESS_WARNINGS_ENV: &str = "RULES_RUST_SUPPRESS_BUILD_SCRIPT_WARNINGS";

pub mod cargo_manifest_dir;

#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -46,13 +48,7 @@ pub enum BuildScriptOutput {
}

impl BuildScriptOutput {
/// Converts a line into a [BuildScriptOutput] enum.
///
/// Examples
/// ```rust
/// assert_eq!(BuildScriptOutput::new("cargo::rustc-link-lib=lib"), Some(BuildScriptOutput::LinkLib("lib".to_owned())));
/// ```
fn new(line: &str) -> Option<BuildScriptOutput> {
fn new(line: &str, emit_warnings: bool) -> Option<BuildScriptOutput> {
let split = line.splitn(2, '=').collect::<Vec<_>>();
if split.len() <= 1 {
// Not a cargo directive.
Expand Down Expand Up @@ -83,7 +79,9 @@ impl BuildScriptOutput {
None
}
"warning" => {
eprint!("Build Script Warning: {}", split[1]);
if emit_warnings {
eprint!("Build Script Warning: {}", split[1]);
}
None
}
"metadata" => {
Expand Down Expand Up @@ -122,7 +120,10 @@ impl BuildScriptOutput {
}

/// Converts a [BufReader] into a vector of [BuildScriptOutput] enums.
fn outputs_from_reader<T: Read>(mut reader: BufReader<T>) -> Vec<BuildScriptOutput> {
fn outputs_from_reader<T: Read>(
mut reader: BufReader<T>,
emit_warnings: bool,
) -> Vec<BuildScriptOutput> {
let mut result = Vec::<BuildScriptOutput>::new();
let mut buf = Vec::new();
while reader
Expand All @@ -132,7 +133,7 @@ impl BuildScriptOutput {
{
// like cargo, ignore any lines that are not valid utf8
if let Ok(line) = String::from_utf8(buf.clone()) {
if let Some(bso) = BuildScriptOutput::new(&line) {
if let Some(bso) = BuildScriptOutput::new(&line, emit_warnings) {
result.push(bso);
}
}
Expand All @@ -144,13 +145,14 @@ impl BuildScriptOutput {
/// Take a [Command], execute it and converts its input into a vector of [BuildScriptOutput]
pub fn outputs_from_command(
cmd: &mut Command,
emit_warnings: bool,
) -> Result<(Vec<BuildScriptOutput>, Output), Output> {
let child_output = cmd
.output()
.unwrap_or_else(|e| panic!("Unable to start command:\n{:#?}\n{:?}", cmd, e));
if child_output.status.success() {
let reader = BufReader::new(child_output.stdout.as_slice());
let output = Self::outputs_from_reader(reader);
let output = Self::outputs_from_reader(reader, emit_warnings);
Ok((output, child_output))
} else {
Err(child_output)
Expand Down Expand Up @@ -277,7 +279,7 @@ mod tests {

fn from_read_buffer_to_env_and_flags_test_impl(buff: Cursor<&str>) {
let reader = BufReader::new(buff);
let result = BuildScriptOutput::outputs_from_reader(reader);
let result = BuildScriptOutput::outputs_from_reader(reader, true);
assert_eq!(result.len(), 13);
assert_eq!(result[0], BuildScriptOutput::LinkLib("sdfsdf".to_owned()));
assert_eq!(result[1], BuildScriptOutput::Env("FOO=BAR".to_owned()));
Expand Down Expand Up @@ -393,7 +395,7 @@ cargo::rustc-env=valid2=2
",
);
let reader = BufReader::new(buff);
let result = BuildScriptOutput::outputs_from_reader(reader);
let result = BuildScriptOutput::outputs_from_reader(reader, true);
assert_eq!(result.len(), 2);
assert_eq!(
&BuildScriptOutput::outputs_to_env(&result, "/some/absolute/path", ""),
Expand All @@ -412,18 +414,30 @@ cargo:rustc-env=valid2=2
",
);
let reader = BufReader::new(buff);
let result = BuildScriptOutput::outputs_from_reader(reader);
let result = BuildScriptOutput::outputs_from_reader(reader, true);
assert_eq!(result.len(), 2);
assert_eq!(
&BuildScriptOutput::outputs_to_env(&result, "/some/absolute/path", ""),
"valid1=1\nvalid2=2"
);
}

#[test]
fn warning_lines_never_appear_in_outputs() {
let lines = "cargo::warning=hello\ncargo::rustc-env=A=1\n";
for emit_warnings in [true, false] {
let result = BuildScriptOutput::outputs_from_reader(
BufReader::new(Cursor::new(lines)),
emit_warnings,
);
assert_eq!(result, vec![BuildScriptOutput::Env("A=1".to_owned())]);
}
}

#[test]
fn metadata_directive_maps_to_dep_env_key_value() {
let reader = BufReader::new(Cursor::new("cargo::metadata=version_1_10_0=1\n"));
let result = BuildScriptOutput::outputs_from_reader(reader);
let result = BuildScriptOutput::outputs_from_reader(reader, true);
assert_eq!(
result,
vec![BuildScriptOutput::DepEnv("VERSION_1_10_0=1".to_owned())]
Expand All @@ -447,7 +461,7 @@ cargo::rustc-env=BAR=/abs/exec_root/elsewhere/file.rs
",
);
let reader = BufReader::new(buff);
let result = BuildScriptOutput::outputs_from_reader(reader);
let result = BuildScriptOutput::outputs_from_reader(reader, true);
assert_eq!(
BuildScriptOutput::outputs_to_env(
&result,
Expand Down
6 changes: 6 additions & 0 deletions cargo/private/cargo_build_script_wrapper.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def cargo_build_script(
proc_macro_deps = [],
build_script_env = {},
build_script_env_files = [],
emit_warnings = True,
use_default_shell_env = None,
data = [],
compile_data = [],
Expand Down Expand Up @@ -112,6 +113,10 @@ def cargo_build_script(
build_script_env (dict, optional): Environment variables for build scripts.
build_script_env_files (list of label, optional): Files containing additional environment variables to set
when running the build script.
emit_warnings (bool, optional): Whether to forward `cargo::warning=` lines from the build script
to stderr. Honored only when
`@rules_rust//cargo/settings:emit_build_script_warnings` is `auto` (the
default); set the flag to `on` or `off` to override every target.
use_default_shell_env (bool, optional): Whether or not to include the default shell environment for the build script action. If unset the global
setting `@rules_rust//cargo/settings:use_default_shell_env` will be used to determine this value.
data (list, optional): Files needed by the build script.
Expand Down Expand Up @@ -221,6 +226,7 @@ def cargo_build_script(
version = version,
build_script_env = build_script_env,
build_script_env_files = build_script_env_files,
emit_warnings = emit_warnings,
use_default_shell_env = sanitized_use_default_shell_env,
links = links,
deps = deps,
Expand Down
3 changes: 3 additions & 0 deletions cargo/settings/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ load(
":settings.bzl",
"cargo_manifest_dir_filename_suffixes_to_retain",
"debug_std_streams_output_group",
"emit_build_script_warnings",
"experimental_symlink_execroot",
"out_dir_volatile_file_basenames",
"use_default_shell_env",
Expand Down Expand Up @@ -30,3 +31,5 @@ experimental_symlink_execroot()
use_default_shell_env()

out_dir_volatile_file_basenames()

emit_build_script_warnings()
21 changes: 20 additions & 1 deletion cargo/settings/settings.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Definitions for all `@rules_rust//cargo` settings
"""

load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_list_flag")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag", "string_list_flag")

def experimental_symlink_execroot():
"""A flag for which causes `cargo_build_script` to symlink the execroot of the action to \
Expand Down Expand Up @@ -43,6 +43,25 @@ def use_default_shell_env():
build_setting_default = True,
)

def emit_build_script_warnings():
"""A flag which controls whether `cargo_build_script` warnings \
(`cargo::warning=`) are printed to stderr.

Supported values:

- `on`: emit warnings for every `cargo_build_script` target, overriding any
per-target `emit_warnings = False`.
- `auto` (default): respect the per-target `emit_warnings` attribute.
`crate_universe`-generated targets set it to `False`, so registry/git
crates stay quiet (matching Cargo); first-party targets emit by default.
- `off`: silence warnings build-wide.
"""
string_flag(
name = "emit_build_script_warnings",
build_setting_default = "auto",
values = ["on", "auto", "off"],
)

def out_dir_volatile_file_basenames():
"""A flag which determines what file basenames are removed from `OUT_DIR` by `cargo_build_script` actions to make the `_bs.out_dir` TreeArtifact deterministic.

Expand Down
21 changes: 21 additions & 0 deletions cargo/tests/cargo_build_script/emit_warnings/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
load("//cargo:defs.bzl", "cargo_build_script")
load("//rust:defs.bzl", "rust_library", "rust_test")

cargo_build_script(
name = "build_quiet",
srcs = ["build.rs"],
edition = "2018",
emit_warnings = False,
)

rust_library(
name = "quiet_lib",
srcs = ["test_lib.rs"],
edition = "2018",
deps = [":build_quiet"],
)

rust_test(
name = "quiet_test",
crate = ":quiet_lib",
)
4 changes: 4 additions & 0 deletions cargo/tests/cargo_build_script/emit_warnings/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
println!("cargo::warning=this should be suppressed when emit_warnings=False");
println!("cargo::rustc-env=FROM_BUILD_SCRIPT=ok");
}
7 changes: 7 additions & 0 deletions cargo/tests/cargo_build_script/emit_warnings/test_lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#[cfg(test)]
mod tests {
#[test]
fn build_script_ran() {
assert_eq!(env!("FROM_BUILD_SCRIPT"), "ok");
}
}
8 changes: 8 additions & 0 deletions crate_universe/src/rendering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,9 @@ impl Renderer {
),
platforms,
),
// Match Cargo's default: registry/git crates are quiet unless the
// build fails or the user passes `-vv`.
emit_warnings: false,
edition: krate.common_attrs.edition.clone(),
linker_script: krate.common_attrs.linker_script.clone(),
links: attrs.and_then(|attrs| attrs.links.clone()),
Expand Down Expand Up @@ -1244,6 +1247,11 @@ mod test {
"```\n{}```\n",
build_file_content
);
assert!(
build_file_content.contains("emit_warnings = False"),
"```\n{}```\n",
build_file_content
);

// Ensure `cargo_build_script` requirements are met
assert!(build_file_content.contains("name = \"_bs\""));
Expand Down
3 changes: 3 additions & 0 deletions crate_universe/src/utils/starlark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ pub(crate) struct CargoBuildScript {
pub(crate) data: Data,
#[serde(skip_serializing_if = "SelectSet::is_empty")]
pub(crate) deps: SelectSet<Label>,
// Skip emitting when value matches the rule default (`True`).
#[serde(skip_serializing_if = "Clone::clone")]
pub(crate) emit_warnings: bool,
#[serde(skip_serializing_if = "SelectSet::is_empty")]
pub(crate) link_deps: SelectSet<Label>,
pub(crate) edition: String,
Expand Down