build.rs

 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 build_successful = std::process::Command::new("cargo")
14        .args([
15            "build",
16            "--release",
17            "--target",
18            "wasm32-wasi",
19            "--manifest-path",
20            base.join("Cargo.toml").to_str().unwrap(),
21        ])
22        .status()
23        .expect("Could not build plugins")
24        .success();
25    assert!(build_successful);
26
27    let binaries = std::fs::read_dir(base.join("target/wasm32-wasi/release"))
28        .expect("Could not find compiled plugins in target");
29
30    let engine = create_default_engine();
31
32    for file in binaries {
33        let is_wasm = || {
34            let path = file.ok()?.path();
35            if path.extension()? == "wasm" {
36                Some(path)
37            } else {
38                None
39            }
40        };
41
42        if let Some(path) = is_wasm() {
43            let out_path = base.join("bin").join(path.file_name().unwrap());
44            std::fs::copy(&path, &out_path).expect("Could not copy compiled plugin to bin");
45            precompile(&out_path, &engine);
46        }
47    }
48}
49
50/// Creates a default engine for compiling Wasm.
51/// N.B.: this must create the same `Engine` as
52/// the `create_default_engine` function
53/// in `plugin_runtime/src/plugin.rs`.
54fn create_default_engine() -> Engine {
55    let mut config = Config::default();
56    config.async_support(true);
57    // config.epoch_interruption(true);
58    Engine::new(&config).expect("Could not create engine")
59}
60
61fn precompile(path: &Path, engine: &Engine) {
62    let bytes = std::fs::read(path).expect("Could not read wasm module");
63    let compiled = engine
64        .precompile_module(&bytes)
65        .expect("Could not precompile module");
66    let out_path = path.parent().unwrap().join(&format!(
67        "{}.pre",
68        path.file_name().unwrap().to_string_lossy()
69    ));
70    let mut out_file = std::fs::File::create(out_path)
71        .expect("Could not create output file for precompiled module");
72    out_file.write_all(&compiled).unwrap();
73}