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