Skip to content

Commit 10129d5

Browse files
authored
Replace uses of eprintln! with log (#1017)
Fixes #1010
1 parent 2a38e63 commit 10129d5

File tree

10 files changed

+117
-35
lines changed

10 files changed

+117
-35
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vello/src/debug/validate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub(crate) fn validate_line_soup(lines: &[LineSoup]) -> Vec<LineEndpoint> {
5858
}
5959
}
6060
if !points.is_empty() {
61-
eprintln!("Unpaired points are present: {:#?}", points);
61+
log::warn!("Unpaired points are present: {:#?}", points);
6262
}
6363
points.into_iter().collect()
6464
}

vello/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@
9898
clippy::cast_possible_truncation,
9999
clippy::missing_assert_message,
100100
clippy::shadow_unrelated,
101-
clippy::print_stderr,
102101
reason = "Deferred"
103102
)]
104103
#![allow(
@@ -581,7 +580,7 @@ impl Renderer {
581580
static HAS_WARNED: AtomicBool = AtomicBool::new(false);
582581
if !HAS_WARNED.swap(true, std::sync::atomic::Ordering::Release) {
583582
log::warn!(
584-
"Requested debug layers {debug:?} but `debug_layers` feature is not enabled.",
583+
"Requested debug layers {debug:?} but `debug_layers` feature is not enabled",
585584
debug = debug_layers
586585
);
587586
}

vello/src/scene.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,8 @@ impl ColorPainter for DrawColorGlyphs<'_> {
805805

806806
fn push_clip_glyph(&mut self, glyph_id: GlyphId) {
807807
let Some(outline) = self.outlines.get(glyph_id) else {
808-
eprintln!("Didn't get expected outline");
808+
log::warn!("Color Glyph (emoji) rendering: Color Glyph references missing outline");
809+
// TODO: In theory, we should record the name of the emoji font used, etc. here
809810
return;
810811
};
811812

@@ -887,7 +888,7 @@ impl ColorPainter for DrawColorGlyphs<'_> {
887888
brush: skrifa::color::Brush<'_>,
888889
) {
889890
let Some(outline) = self.outlines.get(glyph_id) else {
890-
eprintln!("Didn't get expected outline");
891+
log::warn!("Color Glyph (emoji) rendering: Color Glyph references missing outline");
891892
return;
892893
};
893894

vello/src/wgpu_engine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl WgpuEngine {
179179
std::thread::available_parallelism().map_or(2, |it| it.get().max(4) - 2)
180180
})
181181
.min(new_shaders.len());
182-
eprintln!("Initialising in parallel using {num_threads} threads");
182+
log::info!("Initialising shader modules in parallel using {num_threads} threads");
183183
let remainder = new_shaders.split_off(num_threads);
184184
let (tx, rx) = std::sync::mpsc::channel::<(ShaderId, WgpuShader)>();
185185

vello_shaders/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ targets = []
1717

1818
[features]
1919
default = ["wgsl", "cpu"]
20-
compile = ["dep:naga", "dep:thiserror"]
20+
compile = ["dep:naga", "dep:thiserror", "dep:log"]
2121

2222
# Target shading language variants of the vello shaders to link into the library.
2323
wgsl = []
@@ -34,7 +34,9 @@ bytemuck = { workspace = true, optional = true }
3434
naga = { version = "24.0.0", features = ["wgsl-in"], optional = true }
3535
thiserror = { workspace = true, optional = true }
3636
vello_encoding = { workspace = true, optional = true }
37+
log = { workspace = true, optional = true }
3738

3839
[build-dependencies]
3940
naga = { version = "24.0.0", features = ["wgsl-in"] }
4041
thiserror = { workspace = true }
42+
log = { workspace = true }

vello_shaders/build.rs

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ mod compile;
1212
mod types;
1313

1414
use std::env;
15-
use std::fmt::Write;
15+
use std::fmt::{self, Write as _};
1616
use std::path::Path;
1717

1818
use compile::ShaderInfo;
1919

2020
fn main() {
21+
log::set_logger(&BUILD_SCRIPT_LOGGER).unwrap();
22+
log::set_max_level(log::LevelFilter::Info);
2123
let out_dir = env::var_os("OUT_DIR").unwrap();
2224
let dest_path = Path::new(&out_dir).join("shaders.rs");
2325

@@ -26,10 +28,11 @@ fn main() {
2628
let mut shaders = match ShaderInfo::from_default() {
2729
Ok(s) => s,
2830
Err(err) => {
29-
let formatted = err.to_string();
30-
for line in formatted.lines() {
31-
println!("cargo:warning={line}");
32-
}
31+
let mut target = String::new();
32+
// Ideally, we'd write into stdout directly here, but the duck-typing of `write!`
33+
// makes that a bit annoying - we'd have to implement `CargoWarningAdapter` for both `io::Write` and `fmt::Write`
34+
writeln!(CargoWarningAdapter::new(&mut target), "{err}").unwrap();
35+
print!("{target}");
3336
return;
3437
}
3538
};
@@ -43,7 +46,7 @@ fn main() {
4346
std::fs::write(dest_path, &buf).unwrap();
4447
}
4548

46-
fn write_types(buf: &mut String, shaders: &[(String, ShaderInfo)]) -> Result<(), std::fmt::Error> {
49+
fn write_types(buf: &mut String, shaders: &[(String, ShaderInfo)]) -> Result<(), fmt::Error> {
4750
writeln!(buf, "pub struct Shaders<'a> {{")?;
4851
for (name, _) in shaders {
4952
writeln!(buf, " pub {name}: ComputeShader<'a>,")?;
@@ -52,10 +55,7 @@ fn write_types(buf: &mut String, shaders: &[(String, ShaderInfo)]) -> Result<(),
5255
Ok(())
5356
}
5457

55-
fn write_shaders(
56-
buf: &mut String,
57-
shaders: &[(String, ShaderInfo)],
58-
) -> Result<(), std::fmt::Error> {
58+
fn write_shaders(buf: &mut String, shaders: &[(String, ShaderInfo)]) -> Result<(), fmt::Error> {
5959
writeln!(buf, "mod generated {{")?;
6060
writeln!(buf, " use super::*;")?;
6161
writeln!(buf, " use BindType::*;")?;
@@ -110,12 +110,12 @@ fn write_shaders(
110110
}
111111

112112
#[cfg(not(feature = "msl"))]
113-
fn write_msl(_: &mut String, _: &ShaderInfo) -> Result<(), std::fmt::Error> {
113+
fn write_msl(_: &mut String, _: &ShaderInfo) -> Result<(), fmt::Error> {
114114
Ok(())
115115
}
116116

117117
#[cfg(feature = "msl")]
118-
fn write_msl(buf: &mut String, info: &ShaderInfo) -> Result<(), std::fmt::Error> {
118+
fn write_msl(buf: &mut String, info: &ShaderInfo) -> Result<(), fmt::Error> {
119119
let mut index_iter = compile::msl::BindingIndexIterator::default();
120120
let indices = info
121121
.bindings
@@ -136,3 +136,74 @@ fn write_msl(buf: &mut String, info: &ShaderInfo) -> Result<(), std::fmt::Error>
136136
writeln!(buf, " }},")?;
137137
Ok(())
138138
}
139+
140+
/// A very simple logger for build scripts, which ensures that warnings and above
141+
/// are visible to the user.
142+
///
143+
/// We don't use an external crate here to keep build times down.
144+
struct BuildScriptLog;
145+
146+
static BUILD_SCRIPT_LOGGER: BuildScriptLog = BuildScriptLog;
147+
148+
impl log::Log for BuildScriptLog {
149+
fn enabled(&self, _: &log::Metadata<'_>) -> bool {
150+
true
151+
}
152+
153+
fn log(&self, record: &log::Record<'_>) {
154+
// "more serious" levels are lower
155+
if record.level() <= log::Level::Warn {
156+
let mut target = String::new();
157+
write!(
158+
CargoWarningAdapter::new(&mut target),
159+
"{}: {}",
160+
record.level(),
161+
record.args()
162+
)
163+
.unwrap();
164+
println!("{target}");
165+
} else {
166+
// If the user wants more verbose output from the build script, they would pass
167+
// `-vv` to `cargo build`. In that case, we should provide all of the logs that
168+
// people chose to provide.
169+
// TODO: Maybe this should fall back to `env_logger`?
170+
eprintln!("{}: {}", record.level(), record.args());
171+
}
172+
}
173+
174+
fn flush(&self) {
175+
// Nothing to do; we use `println` which is "self-flushing"
176+
}
177+
}
178+
179+
/// An adapter for `fmt::Write` which prepends `cargo:warning=` to each line, ensuring that every
180+
/// output line is shown to build script users.
181+
struct CargoWarningAdapter<W: fmt::Write> {
182+
writer: W,
183+
needs_warning: bool,
184+
}
185+
186+
impl<W: fmt::Write> CargoWarningAdapter<W> {
187+
fn new(writer: W) -> Self {
188+
Self {
189+
writer,
190+
needs_warning: true,
191+
}
192+
}
193+
}
194+
195+
impl<W: fmt::Write> fmt::Write for CargoWarningAdapter<W> {
196+
fn write_str(&mut self, s: &str) -> fmt::Result {
197+
for line in s.split_inclusive('\n') {
198+
if self.needs_warning {
199+
write!(&mut self.writer, "cargo:warning=")?;
200+
self.needs_warning = false;
201+
}
202+
write!(&mut self.writer, "{line}")?;
203+
if line.ends_with('\n') {
204+
self.needs_warning = true;
205+
}
206+
}
207+
Ok(())
208+
}
209+
}

vello_shaders/src/compile/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ impl ShaderInfo {
213213
for permutation in permutations {
214214
let mut defines = defines.clone();
215215
defines.extend(permutation.defines.iter().cloned());
216-
let source = preprocess::preprocess(&contents, &defines, &imports);
216+
let source =
217+
preprocess::preprocess(&contents, shader_name, &defines, &imports);
217218
match Self::new(&permutation.name, source, "main") {
218219
Ok(shader_info) => {
219220
info.insert(permutation.name.clone(), shader_info);
@@ -224,7 +225,8 @@ impl ShaderInfo {
224225
}
225226
}
226227
} else {
227-
let source = preprocess::preprocess(&contents, &defines, &imports);
228+
let source =
229+
preprocess::preprocess(&contents, shader_name, &defines, &imports);
228230
match Self::new(shader_name, source, "main") {
229231
Ok(shader_info) => {
230232
info.insert(shader_name.to_string(), shader_info);

vello_shaders/src/compile/preprocess.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub struct StackItem {
3636

3737
pub fn preprocess(
3838
input: &str,
39+
shader_name: &str,
3940
defines: &HashSet<String>,
4041
imports: &HashMap<String, String>,
4142
) -> String {
@@ -68,9 +69,9 @@ pub fn preprocess(
6869
item @ ("ifdef" | "ifndef" | "else" | "endif" | "enable")
6970
if !directive_is_at_start =>
7071
{
71-
eprintln!(
72+
log::warn!(
7273
"#{item} directives must be the first non_whitespace items on \
73-
their line, ignoring (line {line_number})"
74+
their line, ignoring (line {line_number} of {shader_name}.wgsl)"
7475
);
7576
break;
7677
}
@@ -89,8 +90,8 @@ pub fn preprocess(
8990
let item = stack.last_mut();
9091
if let Some(item) = item {
9192
if item.else_passed {
92-
eprintln!(
93-
"Second else for same ifdef/ifndef (line {line_number}); \
93+
log::warn!(
94+
"Second else for same ifdef/ifndef (line {line_number} of {shader_name}.wgsl); \
9495
ignoring second else"
9596
);
9697
} else {
@@ -100,23 +101,23 @@ pub fn preprocess(
100101
}
101102
let remainder = directive_start[directive_len..].trim();
102103
if !remainder.is_empty() {
103-
eprintln!(
104+
log::warn!(
104105
"#else directives don't take an argument. `{remainder}` will not \
105-
be in output (line {line_number})"
106+
be in output (line {line_number} of {shader_name}.wgsl)"
106107
);
107108
}
108109
// Don't add this line to the output; it should be empty (see warning above)
109110
continue 'all_lines;
110111
}
111112
"endif" => {
112113
if stack.pop().is_none() {
113-
eprintln!("Mismatched endif (line {line_number})");
114+
log::warn!("Mismatched endif (line {line_number} of {shader_name}.wgsl)");
114115
}
115116
let remainder = directive_start[directive_len..].trim();
116117
if !remainder.is_empty() && !remainder.starts_with("//") {
117-
eprintln!(
118+
log::warn!(
118119
"#endif directives don't take an argument. `{remainder}` will \
119-
not be in output (line {line_number})"
120+
not be in output (line {line_number} of {shader_name}.wgsl)"
120121
);
121122
}
122123
// Don't add this line to the output; it should be empty (see warning above)
@@ -130,7 +131,9 @@ pub fn preprocess(
130131
{
131132
import_name_start
132133
} else {
133-
eprintln!("#import needs a non_whitespace argument (line {line_number})");
134+
log::warn!(
135+
"#import needs a non_whitespace argument (line {line_number} of {shader_name}.wgsl)"
136+
);
134137
continue 'all_lines;
135138
};
136139
let import_name_start = &directive_end[import_name_start..];
@@ -146,10 +149,12 @@ pub fn preprocess(
146149
// However, in practise there will only ever be at most 2 stack items, so
147150
// it's reasonable to just recompute it every time
148151
if stack.iter().all(|item| item.active) {
149-
output.push_str(&preprocess(import, defines, imports));
152+
output.push_str(&preprocess(import, shader_name, defines, imports));
150153
}
151154
} else {
152-
eprintln!("Unknown import `{import_name}` (line {line_number})");
155+
log::warn!(
156+
"Unknown import `{import_name}` (line {line_number} of {shader_name}.wgsl)"
157+
);
153158
}
154159
continue;
155160
}
@@ -164,7 +169,9 @@ pub fn preprocess(
164169
continue 'all_lines;
165170
}
166171
val => {
167-
eprintln!("Unknown preprocessor directive `{val}` (line {line_number})");
172+
log::warn!(
173+
"Unknown preprocessor directive `{val}` (line {line_number} of {shader_name}.wgsl)"
174+
);
168175
}
169176
}
170177
}

vello_shaders/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
unnameable_types,
3838
clippy::cast_possible_truncation,
3939
clippy::missing_assert_message,
40-
clippy::print_stderr,
4140
clippy::print_stdout,
4241
clippy::shadow_unrelated,
4342
clippy::todo,

0 commit comments

Comments
 (0)