diff --git a/Cargo.lock b/Cargo.lock index ee0b6cf..e2e8f25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,7 +286,7 @@ version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -319,15 +319,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "cpp_demangle" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" -dependencies = [ - "cfg-if", -] - [[package]] name = "cpufeatures" version = "0.2.17" @@ -410,7 +401,7 @@ dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", "cranelift-srcgen", - "heck 0.5.0", + "heck", "pulley-interpreter", ] @@ -562,15 +553,6 @@ dependencies = [ "syn", ] -[[package]] -name = "debugid" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" -dependencies = [ - "uuid", -] - [[package]] name = "digest" version = "0.10.7" @@ -683,12 +665,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - [[package]] name = "fd-lock" version = "4.0.4" @@ -706,12 +682,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - [[package]] name = "fluent-uri" version = "0.1.4" @@ -807,29 +777,11 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "futures-channel", "futures-core", - "futures-io", "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", - "slab", -] - -[[package]] -name = "fxprof-processed-profile" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25234f20a3ec0a962a61770cfe39ecf03cb529a6e474ad8cff025ed497eda557" -dependencies = [ - "bitflags 2.10.0", - "debugid", - "rustc-hash", - "serde", - "serde_derive", - "serde_json", ] [[package]] @@ -892,12 +844,6 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -1117,26 +1063,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "ittapi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b996fe614c41395cdaedf3cf408a9534851090959d90d54a535f675550b64b1" -dependencies = [ - "anyhow", - "ittapi-sys", - "log", -] - -[[package]] -name = "ittapi-sys" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f5385394064fa2c886205dba02598013ce83d3e92d33dbdc0c52fe0e7bf4fc" -dependencies = [ - "cc", -] - [[package]] name = "jobserver" version = "0.1.34" @@ -1340,6 +1266,7 @@ dependencies = [ "clap", "crossbeam-channel", "index_vec", + "libc", "line-index", "lsp-server", "lsp-types", @@ -1412,16 +1339,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "petgraph" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" -dependencies = [ - "fixedbitset", - "indexmap", -] - [[package]] name = "pin-project-lite" version = "0.2.16" @@ -1607,12 +1524,6 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -1749,19 +1660,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - [[package]] name = "sha2" version = "0.10.9" @@ -1789,12 +1687,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - [[package]] name = "smallvec" version = "1.15.1" @@ -1841,7 +1733,7 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -1891,19 +1783,6 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" -[[package]] -name = "tempfile" -version = "3.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" -dependencies = [ - "fastrand", - "getrandom 0.3.4", - "once_cell", - "rustix 1.1.2", - "windows-sys 0.61.2", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -2077,12 +1956,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - [[package]] name = "url" version = "2.5.7" @@ -2107,16 +1980,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "1.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "version_check" version = "0.9.5" @@ -2183,27 +2046,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-compose" -version = "0.240.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feeb9a231e63bd5d5dfe07e9f8daa53d5c85e4f7de5ef756d3b4e6a5f501c578" -dependencies = [ - "anyhow", - "heck 0.4.1", - "im-rc", - "indexmap", - "log", - "petgraph", - "serde", - "serde_derive", - "serde_yaml", - "smallvec", - "wasm-encoder 0.240.0", - "wasmparser 0.240.0", - "wat", -] - [[package]] name = "wasm-encoder" version = "0.240.0" @@ -2273,12 +2115,8 @@ dependencies = [ "cc", "cfg-if", "encoding_rs", - "futures", - "fxprof-processed-profile", - "gimli", "hashbrown 0.15.5", "indexmap", - "ittapi", "libc", "log", "mach2", @@ -2292,12 +2130,8 @@ dependencies = [ "semver", "serde", "serde_derive", - "serde_json", "smallvec", "target-lexicon", - "tempfile", - "wasm-compose", - "wasm-encoder 0.240.0", "wasmparser 0.240.0", "wasmtime-environ", "wasmtime-internal-cache", @@ -2323,7 +2157,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbe588bc688673cbd4085cbb82db681a6591c87538dce6aa44c0057a3c82bbca" dependencies = [ "anyhow", - "cpp_demangle", "cranelift-bitset", "cranelift-entity", "gimli", @@ -2331,7 +2164,6 @@ dependencies = [ "log", "object", "postcard", - "rustc-demangle", "semver", "serde", "serde_derive", @@ -2434,8 +2266,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "774ed19958d2fe67bdb817501aad9d399be50ee5752f63fdb866e061fc034186" dependencies = [ "cc", - "object", - "rustix 1.1.2", "wasmtime-internal-versioned-export-macros", ] @@ -2516,7 +2346,7 @@ checksum = "9ee6e4341cf80f6f2b50923553a92d14a0aa9f921fbf4370b3bde367db90f3e6" dependencies = [ "anyhow", "bitflags 2.10.0", - "heck 0.5.0", + "heck", "indexmap", "wit-parser", ] @@ -2617,7 +2447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9836f1ccbbfea133c07a7a0a0ce54162be6e338982adb8ae893e5eafc9e25c3a" dependencies = [ "anyhow", - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", diff --git a/Cargo.toml b/Cargo.toml index 1ab2287..885c8de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,19 @@ moss-core = { path = "crates/moss-core" } serde_json = "1" strum = "0.27" wasm-encoder = "0.241" -wasmtime = "39" wasmtime-wasi = "39" +libc = "0.2" + +[workspace.dependencies.wasmtime] +version = "39" +default-features = false +features = [ + "cranelift", + "parallel-compilation", + "pooling-allocator", + "cache", + "wat", +] [profile.release-with-debug] inherits = "release" diff --git a/crates/moss-cli/Cargo.toml b/crates/moss-cli/Cargo.toml index ad6ef9c..73e6bf7 100644 --- a/crates/moss-cli/Cargo.toml +++ b/crates/moss-cli/Cargo.toml @@ -16,3 +16,4 @@ moss-core = { workspace = true } serde_json = { workspace = true } wasmtime = { workspace = true } wasmtime-wasi = { workspace = true } +libc = { workspace = true } diff --git a/crates/moss-cli/build.rs b/crates/moss-cli/build.rs new file mode 100644 index 0000000..7b2fb3c --- /dev/null +++ b/crates/moss-cli/build.rs @@ -0,0 +1,49 @@ +use std::{env, path::Path}; + +fn main() { + println!("cargo:rerun-if-env-changed=BINARYEN_LIB_DIR"); + println!("cargo:rerun-if-env-changed=BINARYEN_STATIC"); + println!("cargo:rerun-if-env-changed=BINARYEN_STATIC_STDCPP"); + println!("cargo:rerun-if-env-changed=MCFGTHREAD_LIB_DIR"); + println!("cargo:rerun-if-env-changed=TARGET"); + + if let Some(dir) = env::var_os("BINARYEN_LIB_DIR") { + println!( + "cargo:rustc-link-search=native={}", + Path::new(&dir).display() + ); + } + if let Some(dir) = env::var_os("MCFGTHREAD_LIB_DIR") { + println!( + "cargo:rustc-link-search=native={}", + Path::new(&dir).display() + ); + } + + let kind = match env::var("BINARYEN_STATIC").as_deref() { + Ok("0") => "dylib", + Ok(_) => "static", + Err(_) => "dylib", + }; + println!("cargo:rustc-link-lib={kind}=binaryen"); + + if env::var("CARGO_CFG_TARGET_ENV").ok().as_deref() != Some("msvc") { + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default(); + let cpp_name = if target_os == "macos" { + "c++" + } else { + "stdc++" + }; + let static_cpp = env::var("BINARYEN_STATIC_STDCPP") + .map(|v| v != "0") + .unwrap_or_else(|_| { + matches!(env::var("CARGO_CFG_TARGET_ENV").as_deref(), Ok("musl")) + || target_os == "windows" + }); + let cpp_link = if static_cpp { "static" } else { "dylib" }; + println!("cargo:rustc-link-lib={cpp_link}={cpp_name}"); + if target_os == "windows" { + println!("cargo:rustc-link-lib=static=mcfgthread"); + } + } +} diff --git a/crates/moss-cli/src/bin/moss.rs b/crates/moss-cli/src/bin/moss.rs index 3c6583f..0544802 100644 --- a/crates/moss-cli/src/bin/moss.rs +++ b/crates/moss-cli/src/bin/moss.rs @@ -18,6 +18,9 @@ use moss_core::{ prelude::prelude, wasm::wasm, }; +#[path = "../binaryen.rs"] +mod binaryen; +use binaryen::{Opt, optimize_wasm, parse_opt}; use wasmtime::{Engine, Linker, Module, Store}; use wasmtime_wasi::{DirPerms, FilePerms, WasiCtxBuilder, p1::WasiP1Ctx}; @@ -38,7 +41,7 @@ impl Compiler<'_> { } } -fn compile(script: &str) -> anyhow::Result> { +fn compile(script: &str, opt: Option) -> anyhow::Result> { let source = fs::read_to_string(script)?; let compiler = Compiler { path: script, @@ -71,11 +74,14 @@ fn compile(script: &str) -> anyhow::Result> { })?; let start = names.fndefs[&(module, ir.strings.get_id("main").unwrap())]; let bytes = wasm(&ir, &names, lib, start); - Ok(bytes) + match opt { + Some(opt) => optimize_wasm(bytes, opt), + None => Ok(bytes), + } } -fn build(script: &str, output: Option<&Path>) -> anyhow::Result<()> { - let bytes = compile(script)?; +fn build(script: &str, output: Option<&Path>, opt: Option) -> anyhow::Result<()> { + let bytes = compile(script, opt)?; match output { Some(out) => { fs::write(out, bytes)?; @@ -91,8 +97,8 @@ fn build(script: &str, output: Option<&Path>) -> anyhow::Result<()> { Ok(()) } -fn run(script: &str, args: &[String]) -> anyhow::Result { - let bytes = compile(script)?; +fn run(script: &str, args: &[String], opt: Option) -> anyhow::Result { + let bytes = compile(script, opt)?; let engine = Engine::default(); let mut linker = Linker::new(&engine); wasmtime_wasi::p1::add_to_linker_sync(&mut linker, |ctx: &mut WasiP1Ctx| ctx)?; @@ -117,8 +123,8 @@ fn run(script: &str, args: &[String]) -> anyhow::Result { } } -fn run_exit(script: &str, args: &[String]) -> ExitCode { - match run(script, args) { +fn run_exit(script: &str, args: &[String], opt: Option) -> ExitCode { + match run(script, args, opt) { Ok(exit_code) => ExitCode::from(exit_code as u8), Err(err) => err_fail(err), } @@ -136,12 +142,33 @@ enum Commands { Run { script: String, args: Vec, + #[arg( + short = 'O', + long = "opt-level", + value_name = "LEVEL", + num_args = 0..=1, + default_missing_value = "2", + value_parser = parse_opt, + help = "Binaryen optimization level (0,1,2,3,s,z)" + )] + opt: Option, }, Build { script: String, #[arg(short)] output: Option, + + #[arg( + short = 'O', + long = "opt-level", + value_name = "LEVEL", + num_args = 0..=1, + default_missing_value = "2", + value_parser = parse_opt, + help = "Binaryen optimization level (0,1,2,3,s,z)" + )] + opt: Option, }, Lsp, } @@ -151,13 +178,17 @@ fn main() -> ExitCode { if let Some((file, args)) = std::env::args().skip(1).collect::>().split_first() { // Prevent collision with possible future subcommands. if file.contains("/") { - return run_exit(file, args); + return run_exit(file, args, None); } } let args = Cli::parse(); match args.command { - Commands::Run { script, args } => run_exit(&script, &args), - Commands::Build { script, output } => match build(&script, output.as_deref()) { + Commands::Run { script, args, opt } => run_exit(&script, &args, opt), + Commands::Build { + script, + output, + opt, + } => match build(&script, output.as_deref(), opt) { Ok(()) => ExitCode::SUCCESS, Err(err) => err_fail(err), }, diff --git a/crates/moss-cli/src/binaryen.rs b/crates/moss-cli/src/binaryen.rs new file mode 100644 index 0000000..0769d00 --- /dev/null +++ b/crates/moss-cli/src/binaryen.rs @@ -0,0 +1,110 @@ +use std::{ + ffi::{c_char, c_int, c_void}, + ptr, slice, +}; + +use anyhow::bail; +use libc::free; + +#[derive(Clone, Copy)] +pub struct Opt { + pub optimize_level: c_int, + pub shrink_level: c_int, +} + +pub fn parse_opt(value: &str) -> Result { + match value { + "0" => Ok(Opt { + optimize_level: 0, + shrink_level: 0, + }), + "1" => Ok(Opt { + optimize_level: 1, + shrink_level: 0, + }), + "2" => Ok(Opt { + optimize_level: 2, + shrink_level: 0, + }), + "3" => Ok(Opt { + optimize_level: 3, + shrink_level: 0, + }), + "s" | "Os" => Ok(Opt { + optimize_level: 2, + shrink_level: 1, + }), + "z" | "Oz" => Ok(Opt { + optimize_level: 2, + shrink_level: 2, + }), + other => Err(format!( + "invalid opt level `{other}`; expected one of 0,1,2,3,s,z" + )), + } +} + +pub fn optimize_wasm(mut bytes: Vec, opt: Opt) -> anyhow::Result> { + unsafe { + let module = BinaryenModuleReadWithFeatures( + bytes.as_mut_ptr() as *mut c_char, + bytes.len(), + BinaryenFeatureAll(), + ); + if module.is_null() { + bail!("Binaryen could not read module"); + } + + BinaryenSetOptimizeLevel(opt.optimize_level); + BinaryenSetShrinkLevel(opt.shrink_level); + BinaryenSetDebugInfo(false); + BinaryenModuleOptimize(module); + + let result = BinaryenModuleAllocateAndWrite(module, ptr::null()); + BinaryenModuleDispose(module); + + if result.binary.is_null() || result.binaryBytes == 0 { + bail!("Binaryen failed to emit optimized module"); + } + let optimized = + slice::from_raw_parts(result.binary as *const u8, result.binaryBytes).to_vec(); + + // The Binaryen C API allocates with malloc(). + free(result.binary); + if !result.sourceMap.is_null() { + free(result.sourceMap as *mut c_void); + } + Ok(optimized) + } +} + +#[repr(C)] +#[allow(non_snake_case)] +struct BinaryenModuleAllocateAndWriteResult { + binary: *mut c_void, + binaryBytes: usize, + sourceMap: *mut c_char, +} + +type BinaryenFeatures = u32; +type BinaryenModuleRef = *mut c_void; + +unsafe extern "C" { + fn BinaryenFeatureAll() -> BinaryenFeatures; + + fn BinaryenSetOptimizeLevel(level: c_int); + fn BinaryenSetShrinkLevel(level: c_int); + fn BinaryenSetDebugInfo(on: bool); + + fn BinaryenModuleReadWithFeatures( + input: *mut c_char, + input_size: usize, + feature_set: BinaryenFeatures, + ) -> BinaryenModuleRef; + fn BinaryenModuleDispose(module: BinaryenModuleRef); + fn BinaryenModuleOptimize(module: BinaryenModuleRef); + fn BinaryenModuleAllocateAndWrite( + module: BinaryenModuleRef, + source_map_url: *const c_char, + ) -> BinaryenModuleAllocateAndWriteResult; +} diff --git a/flake.nix b/flake.nix index 9927c80..8047cb1 100644 --- a/flake.nix +++ b/flake.nix @@ -48,6 +48,24 @@ ] ./.; strictDeps = true; }; + binaryen = + prev.binaryen.overrideAttrs (old: { + cmakeFlags = (old.cmakeFlags or [ ]) ++ [ + "-DBUILD_STATIC_LIB=ON" + "-DBUILD_SHARED_LIB=OFF" + "-DBUILD_SHARED_LIBS=OFF" + ]; + }); + withBinaryen = + pkg: args: + args + // { + buildInputs = (args.buildInputs or [ ]) ++ [ pkg ]; + env = (args.env or { }) // { + BINARYEN_LIB_DIR = "${pkg}/lib"; + BINARYEN_STATIC = "1"; + }; + }; # `cargoExtraArgs` default is "--locked": https://crane.dev/API.html cliArgs = { cargoExtraArgs = "--locked --package=moss-cli"; @@ -58,7 +76,7 @@ craneLib = crane.mkLib prev; cacheArgs = { # Reuse built deps across `moss-cli`/`moss-dev`/`cargo test`. - cargoArtifacts = craneLib.buildDepsOnly commonArgs; + cargoArtifacts = craneLib.buildDepsOnly (withBinaryen binaryen commonArgs); }; b2n = (bun2nix.overlays.default final prev).bun2nix; bunDeps = b2n.fetchBunDeps { @@ -89,7 +107,7 @@ ''; }; packages = { - default = craneLib.buildPackage (commonArgs // cacheArgs // cliArgs); + default = craneLib.buildPackage (withBinaryen binaryen (commonArgs // cacheArgs // cliArgs)); vscode = prev.vscode-utils.buildVscodeExtension rec { vscodeExtPublisher = "moss-lang"; vscodeExtName = "moss-vscode"; @@ -122,19 +140,53 @@ // rec { musl = target: + let + crossPkgs = + if target == "x86_64-unknown-linux-musl" then pkgs.pkgsCross.musl64 else pkgs.pkgsCross.aarch64-multiplatform-musl; + binaryen = + crossPkgs.binaryen.overrideAttrs (old: { + cmakeFlags = (old.cmakeFlags or [ ]) ++ [ + "-DBUILD_STATIC_LIB=ON" + "-DBUILD_SHARED_LIB=OFF" + "-DBUILD_SHARED_LIBS=OFF" + ]; + }); + in (craneLib.overrideToolchain ( p: p.rust-bin.stable.latest.default.override { targets = [ target ]; } )).buildPackage - (commonArgs // cliArgs // { CARGO_BUILD_TARGET = target; }); + (withBinaryen binaryen (commonArgs // cliArgs // { + CARGO_BUILD_TARGET = target; + env = { BINARYEN_STATIC_STDCPP = "0"; }; + })); windows = crossSystem: let pkgs = import nixpkgs { localSystem = system; crossSystem.config = crossSystem; + overlays = [ (import rust-overlay) ]; }; + binaryen = + pkgs.binaryen.overrideAttrs (old: { + cmakeFlags = (old.cmakeFlags or [ ]) ++ [ + "-DBUILD_STATIC_LIB=ON" + "-DBUILD_SHARED_LIB=OFF" + "-DBUILD_SHARED_LIBS=OFF" + ]; + }); + craneLib = crane.mkLib pkgs; + mcfgthreads = pkgs.callPackage "${nixpkgs}/pkgs/os-specific/windows/mcfgthreads" { }; in - (crane.mkLib pkgs).buildPackage (commonArgs // cliArgs); + craneLib.buildPackage ( + withBinaryen binaryen (commonArgs // cliArgs // { + buildInputs = (commonArgs.buildInputs or [ ]) ++ [ mcfgthreads ]; + env = { + BINARYEN_STATIC_STDCPP = "0"; + MCFGTHREAD_LIB_DIR = "${mcfgthreads}/lib"; + }; + }) + ); macos = package: pkgs.runCommand "moss" { nativeBuildInputs = [ pkgs.darwin.cctools ]; } '' @@ -159,7 +211,7 @@ ''; }); checks = { - cargo = craneLib.cargoTest (commonArgs // cacheArgs); + cargo = craneLib.cargoTest (withBinaryen binaryen (commonArgs // cacheArgs)); e2e = let dev = craneLib.buildPackage (commonArgs // cacheArgs // devArgs);