nectar/build.rs

211 lines
6.6 KiB
Rust
Raw Normal View History

2023-10-03 06:58:20 +03:00
use std::process::Command;
2023-10-06 07:12:31 +03:00
use std::{
fs, io,
io::{Read, Write},
};
2023-10-03 06:58:20 +03:00
fn run_command(cmd: &mut Command) -> io::Result<()> {
let status = cmd.status()?;
if status.success() {
Ok(())
} else {
Err(io::Error::new(io::ErrorKind::Other, "Command failed"))
}
}
2023-10-09 03:55:19 +03:00
fn file_outdated<P1, P2>(input: P1, output: P2) -> io::Result<bool>
where
P1: AsRef<std::path::Path>,
P2: AsRef<std::path::Path>,
{
let out_meta = std::fs::metadata(output);
if let Ok(meta) = out_meta {
let output_mtime = meta.modified()?;
// if input file is more recent than our output, we are outdated
let input_meta = fs::metadata(input)?;
let input_mtime = input_meta.modified()?;
Ok(input_mtime > output_mtime)
} else {
// output file not found, we are outdated
Ok(true)
}
}
2023-10-03 06:58:20 +03:00
fn main() {
if std::env::var("SKIP_BUILD_SCRIPT").is_ok() {
println!("Skipping build script");
return;
}
let build_enabled = std::env::var("BUILD_APPS")
.map(|v| v == "true")
2023-10-09 04:26:32 +03:00
.unwrap_or(true); // run by default
if !build_enabled {
return;
}
2023-10-04 18:54:53 +03:00
// only execute if one of the modules has source code changes
const WASI_APPS: [&str; 9] = [
"app_tracker",
"chess",
2023-10-09 02:46:12 +03:00
"homepage",
2023-10-04 18:54:53 +03:00
"http_bindings",
"http_proxy",
"orgs",
"qns_indexer",
"rpc",
"terminal",
];
for name in WASI_APPS {
println!("cargo:rerun-if-changed=modules/{}/src", name);
2023-10-06 07:12:31 +03:00
println!("cargo:rerun-if-changed=modules/{}/pkg/manifest.json", name);
println!("cargo:rerun-if-changed=modules/{}/pkg/metadata.json", name);
2023-10-04 18:54:53 +03:00
}
2023-10-03 06:58:20 +03:00
let pwd = std::env::current_dir().unwrap();
// create target.wasm (compiled .wit) & world
run_command(Command::new("wasm-tools").args(&[
"component",
"wit",
&format!("{}/wit/", pwd.display()),
"-o",
"target.wasm",
"--wasm",
]))
.unwrap();
run_command(Command::new("touch").args(&[&format!("{}/world", pwd.display())])).unwrap();
// Build wasm32-wasi apps.
for name in WASI_APPS {
2023-10-09 03:55:19 +03:00
// copy in newly-made wit IF old one is outdated
if file_outdated(
format!("{}/wit/", pwd.display()),
format!("{}/modules/{}/wit/", pwd.display(), name),
2023-10-09 03:56:01 +03:00
)
.unwrap_or(true)
{
2023-10-09 03:55:19 +03:00
run_command(Command::new("cp").args(&[
"-r",
"wit",
&format!("{}/modules/{}", pwd.display(), name),
]))
.unwrap();
// create target/bindings directory
fs::create_dir_all(&format!(
"{}/modules/{}/target/bindings/{}",
2023-10-03 06:58:20 +03:00
pwd.display(),
name,
name
2023-10-09 03:55:19 +03:00
))
.unwrap();
// copy newly-made target.wasm into target/bindings
run_command(Command::new("cp").args(&[
"target.wasm",
&format!(
"{}/modules/{}/target/bindings/{}/",
pwd.display(),
name,
name
),
]))
.unwrap();
// copy newly-made world into target/bindings
run_command(Command::new("cp").args(&[
"world",
&format!(
"{}/modules/{}/target/bindings/{}/",
pwd.display(),
name,
name
),
]))
.unwrap();
}
2023-10-06 07:12:31 +03:00
// build the module targeting wasm32-wasi
2023-10-03 06:58:20 +03:00
run_command(Command::new("cargo").args(&[
"build",
"--release",
"--no-default-features",
&format!(
"--manifest-path={}/modules/{}/Cargo.toml",
pwd.display(),
name
),
"--target",
"wasm32-wasi",
]))
.unwrap();
2023-10-06 07:12:31 +03:00
// adapt module to component with adapter based on wasi_snapshot_preview1.wasm
2023-10-03 06:58:20 +03:00
run_command(Command::new("wasm-tools").args(&[
"component",
"new",
&format!(
"{}/modules/{}/target/wasm32-wasi/release/{}.wasm",
pwd.display(),
name,
name
),
"-o",
&format!(
"{}/modules/{}/target/wasm32-wasi/release/{}_adapted.wasm",
pwd.display(),
name,
name
),
"--adapt",
&format!("{}/wasi_snapshot_preview1.wasm", pwd.display()),
]))
.unwrap();
2023-10-06 07:12:31 +03:00
// put wit into component & place final .wasm in /pkg
let pkg_folder = format!("{}/modules/{}/pkg/", pwd.display(), name);
let _ = run_command(Command::new("mkdir").args(&["-p", &pkg_folder]));
2023-10-03 06:58:20 +03:00
run_command(Command::new("wasm-tools").args(&[
"component",
"embed",
"wit",
"--world",
"uq-process",
&format!(
"{}/modules/{}/target/wasm32-wasi/release/{}_adapted.wasm",
pwd.display(),
name,
name
),
"-o",
2023-10-06 07:12:31 +03:00
&format!("{}/{}.wasm", pkg_folder, name),
2023-10-03 06:58:20 +03:00
]))
.unwrap();
2023-10-06 07:12:31 +03:00
// from the pkg folder, create a zip archive and save in target directory
2023-10-06 07:13:03 +03:00
let writer =
std::fs::File::create(format!("{}/target/{}.zip", pwd.display(), name)).unwrap();
2023-10-06 07:12:31 +03:00
let options = zip::write::FileOptions::default()
.compression_method(zip::CompressionMethod::Stored) // or CompressionMethod::Deflated
.unix_permissions(0o755);
let mut zip = zip::ZipWriter::new(writer);
for entry in walkdir::WalkDir::new(&pkg_folder) {
let entry = entry.unwrap();
let path = entry.path();
let name = path
.strip_prefix(std::path::Path::new(&pkg_folder))
.unwrap();
// Write a directory or file to the ZIP archive
if path.is_file() {
zip.start_file(name.to_string_lossy().into_owned(), options)
.unwrap();
let mut file = std::fs::File::open(path).unwrap();
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).unwrap();
zip.write_all(&buffer).unwrap();
} else if name.as_os_str().len() != 0 {
zip.add_directory(name.to_string_lossy().into_owned(), options)
.unwrap();
}
}
zip.finish().unwrap();
2023-10-03 06:58:20 +03:00
}
2023-10-03 06:58:48 +03:00
}