1use std::{io::Write, path::Path};
2use wasmtime::{Config, Engine};
3
4fn main() {
5 let base = Path::new("../../plugins");
6
7 println!("cargo:rerun-if-changed={}", base.display());
8
9 let _ = std::fs::remove_dir_all(base.join("bin"));
10 let _ =
11 std::fs::create_dir_all(base.join("bin")).expect("Could not make plugins bin directory");
12
13 let (profile_flags, profile_target) = match std::env::var("PROFILE").unwrap().as_str() {
14 "debug" => (&[][..], "debug"),
15 "release" => (&["--release"][..], "release"),
16 unknown => panic!("unknown profile `{}`", unknown),
17 };
18
19 let build_successful = std::process::Command::new("cargo")
20 .args([
21 "build",
22 "--target",
23 "wasm32-wasi",
24 "--manifest-path",
25 base.join("Cargo.toml").to_str().unwrap(),
26 ])
27 .args(profile_flags)
28 .status()
29 .expect("Could not build plugins")
30 .success();
31 assert!(build_successful);
32
33 let binaries = std::fs::read_dir(base.join("target/wasm32-wasi").join(profile_target))
34 .expect("Could not find compiled plugins in target");
35
36 let engine = create_default_engine();
37
38 for file in binaries {
39 let is_wasm = || {
40 let path = file.ok()?.path();
41 if path.extension()? == "wasm" {
42 Some(path)
43 } else {
44 None
45 }
46 };
47
48 if let Some(path) = is_wasm() {
49 let out_path = base.join("bin").join(path.file_name().unwrap());
50 std::fs::copy(&path, &out_path).expect("Could not copy compiled plugin to bin");
51 precompile(&out_path, &engine);
52 }
53 }
54}
55
56/// Creates a default engine for compiling Wasm.
57fn create_default_engine() -> Engine {
58 let mut config = Config::default();
59 config.async_support(true);
60 Engine::new(&config).expect("Could not create engine")
61}
62
63fn precompile(path: &Path, engine: &Engine) {
64 let bytes = std::fs::read(path).expect("Could not read wasm module");
65 let compiled = engine
66 .precompile_module(&bytes)
67 .expect("Could not precompile module");
68 let out_path = path.parent().unwrap().join(&format!(
69 "{}.pre",
70 path.file_name().unwrap().to_string_lossy()
71 ));
72 let mut out_file = std::fs::File::create(out_path)
73 .expect("Could not create output file for precompiled module");
74 out_file.write_all(&compiled).unwrap();
75}