1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
// Replaces the crate's own build script, which cannot work outside one
// machine.
//
// Upstream's writes a slice of `include_bytes!` calls naming *absolute* paths
// — it has to, because `include_bytes!` resolves relative to the file
// containing it and that file lives in OUT_DIR. The paths it writes point into
// the directory the build script ran in, which buck2 models as an output of
// the build-script action and does not expose as a subtarget. Nothing
// downstream can depend on it, so the compile that reads the generated file
// only finds those bytes when the earlier action happened to leave them on the
// same disk. Locally that is true and the build works. On a remote worker it
// is not, and rustc reports 36 missing files.
//
// So write the bytes themselves rather than a path to them. The generated file
// becomes self-contained, the compile needs nothing but OUT_DIR, and where the
// two actions ran stops mattering. 460K of XML becomes about 1.8M of escaped
// source, which costs a second of parsing and is the whole price.
use std::env;
use std::fs;
use std::io::{BufWriter, Write};
use std::path::Path;
fn main() {
let dest = env::var("OUT_DIR").unwrap();
let mut file = BufWriter::new(fs::File::create(Path::new(&dest).join("webgl_exts.rs")).unwrap());
let root = env::current_dir().unwrap().join("api_webgl/extensions");
// Sorted, so the slice is in the same order however the directory is read:
// upstream takes read_dir's order, which is the filesystem's, and that
// differs between the machine that populates a cache and the one that
// reads it.
let mut dirs: Vec<_> = root
.read_dir()
.unwrap()
.map(|entry| entry.unwrap().path())
.collect();
dirs.sort();
writeln!(file, "&[").unwrap();
for dir in dirs {
let name = dir.file_name().unwrap().to_str().unwrap().to_owned();
// A directory that is not the template and holds an extension.xml is
// an extension — the same rule upstream applies, and the same one
// api_webgl/extensions/find-exts applies.
if !dir.is_dir() || name == "template" {
continue;
}
let xml = dir.join("extension.xml");
if !xml.is_file() {
continue;
}
write!(file, " &*b\"").unwrap();
for byte in fs::read(&xml).unwrap() {
write!(file, "\\x{:02x}", byte).unwrap();
}
writeln!(file, "\",").unwrap();
}
writeln!(file, "]").unwrap();
// Nothing else is emitted, and nothing else was: upstream prints no cargo
// directives at all, so the crate's cfgs and link flags are unchanged.
}
|