1#![deny(warnings, missing_docs)]
2use cargo_web::{CargoWebOpts, DeployOpts};
10use ignore::Walk;
11use std::env;
12use std::fs;
13use std::io::{BufWriter, Write};
14use std::path::{Path, PathBuf};
15use structopt::StructOpt;
16
17pub fn compile_wasm<X: AsRef<Path>>(cargo_web_dir: X) {
21 let profile = std::env::var("PROFILE").expect("expected env var PROFILE for build.rs");
22
23 let out_dir = env::var("OUT_DIR").unwrap();
24 let dest_path = Path::new(&out_dir).join("wasm_blobs_output_dir");
25 let _ = fs::remove_dir_all(&dest_path); fs::create_dir(&dest_path).unwrap();
28
29 println!("dest path: {:?}", &dest_path);
30
31 let current_dir = std::env::current_dir().unwrap();
32 env::set_current_dir(current_dir.join(cargo_web_dir)).unwrap();
33
34 let opts = if profile == "release" {
36 DeployOpts::from_iter_safe(&[
37 "--release",
38 "--target=wasm32-unknown-unknown",
39 "--output",
40 dest_path.to_str().unwrap(),
41 ])
42 } else {
43 DeployOpts::from_iter_safe(&[
44 "--target=wasm32-unknown-unknown",
45 "--output",
46 dest_path.to_str().unwrap(),
47 ])
48 }
49 .expect("expected hardcoded cargo-web args to be valid");
50
51 cargo_web::run(CargoWebOpts::Deploy(opts)).unwrap();
52
53 env::set_current_dir(current_dir).unwrap();
54
55 let f_dest_path = Path::new(&out_dir).join("wasm_blobs.rs");
56 let f = fs::File::create(&f_dest_path).unwrap();
57 let mut file = BufWriter::new(f);
58
59 let blobs: Vec<(String, PathBuf)> = (0..)
60 .zip(Walk::new(dest_path.clone()))
61 .filter_map(|(idx, result)| {
62 match result {
65 Ok(entry) => {
66 if entry.metadata().unwrap().is_file() {
67 Some((format!("ENTRY_{}", idx), entry.into_path()))
68 } else {
69 None
70 }
71 }
72 Err(err) => {
73 eprintln!("error traversing wasm directory: {}", err);
74 None
75 }
76 }
77 })
78 .collect();
79
80 for (identifier, path) in &blobs {
81 writeln!(
82 &mut file,
83 "static {}: &'static [u8] = include_bytes!(\"{}\");",
84 identifier,
85 path.to_str().unwrap()
86 )
87 .unwrap();
88 }
89
90 let mut codegen = phf_codegen::Map::new();
91
92 let dest_path = dest_path.to_str().unwrap();
93 for (identifier, path) in &blobs {
94 let key = &path.to_str().unwrap()[dest_path.len() + 1..];
95 codegen.entry(key, identifier);
96 }
97
98 writeln!(
99 &mut file,
100 "static WASM: ::phf::Map<&'static str, &'static [u8]> =\n{};\n",
101 codegen.build()
102 )
103 .unwrap();
104
105 for result in Walk::new("wasm") {
107 match result {
110 Ok(entry) => {
111 println!("cargo:rerun-if-changed={}", entry.path().display());
112 }
113 Err(err) => panic!("error traversing wasm directory: {}", err),
114 }
115 }
116
117 }