|
6 | 6 | env, |
7 | 7 | fmt::Write as _, |
8 | 8 | fs::{self, File}, |
9 | | - io::{self, Write}, |
10 | | - iter, |
| 9 | + io::{self, Cursor, Write}, |
| 10 | + iter, mem, |
11 | 11 | path::{Path, PathBuf}, |
12 | 12 | process::Command, |
13 | 13 | }, |
14 | 14 | tar::Builder, |
| 15 | + wasm_encoder::{ComponentSectionId, Encode as _, RawSection, Section as _}, |
| 16 | + wasmparser::{Parser, Payload}, |
15 | 17 | zstd::Encoder, |
16 | 18 | }; |
17 | 19 |
|
18 | | -const ZSTD_COMPRESSION_LEVEL: i32 = 19; |
| 20 | +const DEBUG_RUNTIME: bool = false; |
| 21 | +const STRIP_RUNTIME: bool = !DEBUG_RUNTIME; |
| 22 | +const ZSTD_COMPRESSION_LEVEL: i32 = if DEBUG_RUNTIME { 0 } else { 19 }; |
19 | 23 | const DEFAULT_SDK_VERSION: &str = "30"; |
20 | 24 |
|
21 | 25 | // SQLite version to build - 3.51.2 (latest as of Jan 2026) |
@@ -249,7 +253,11 @@ fn compress(src_dir: &Path, name: &str, dst_dir: &Path, rerun_if_changed: bool) |
249 | 253 | File::create(dst_dir.join(format!("{name}.zst")))?, |
250 | 254 | ZSTD_COMPRESSION_LEVEL, |
251 | 255 | )?; |
252 | | - io::copy(&mut File::open(path)?, &mut encoder)?; |
| 256 | + if STRIP_RUNTIME && name.ends_with(".so") { |
| 257 | + io::copy(&mut Cursor::new(strip(&fs::read(path)?)?), &mut encoder)?; |
| 258 | + } else { |
| 259 | + io::copy(&mut File::open(path)?, &mut encoder)?; |
| 260 | + } |
253 | 261 | encoder.do_finish()?; |
254 | 262 | Ok(()) |
255 | 263 | } else { |
@@ -485,9 +493,12 @@ fn make_runtime( |
485 | 493 | .arg("build") |
486 | 494 | .arg("-Z") |
487 | 495 | .arg("build-std=panic_abort,std") |
488 | | - .arg("--release") |
489 | 496 | .arg("--target=wasm32-wasip1"); |
490 | 497 |
|
| 498 | + if !DEBUG_RUNTIME { |
| 499 | + cmd.arg("--release"); |
| 500 | + } |
| 501 | + |
491 | 502 | if async_ { |
492 | 503 | cmd.arg("--features=async"); |
493 | 504 | } |
@@ -515,9 +526,10 @@ fn make_runtime( |
515 | 526 | assert!(status.success()); |
516 | 527 | println!("cargo:rerun-if-changed=runtime"); |
517 | 528 |
|
518 | | - let path = out_dir |
519 | | - .join(target) |
520 | | - .join("wasm32-wasip1/release/libcomponentize_py_runtime.a"); |
| 529 | + let build = if DEBUG_RUNTIME { "debug" } else { "release" }; |
| 530 | + let path = out_dir.join(target).join(format!( |
| 531 | + "wasm32-wasip1/{build}/libcomponentize_py_runtime.a" |
| 532 | + )); |
521 | 533 |
|
522 | 534 | if path.exists() { |
523 | 535 | let clang = wasi_sdk.join(format!("bin/{CLANG_EXECUTABLE}")); |
@@ -726,3 +738,63 @@ fn build_sqlite(wasi_sdk: &Path, install_dir: &Path) -> Result<()> { |
726 | 738 |
|
727 | 739 | Ok(()) |
728 | 740 | } |
| 741 | + |
| 742 | +fn strip(input: &[u8]) -> anyhow::Result<Vec<u8>> { |
| 743 | + // Adapted from https://github.com/bytecodealliance/wasm-tools/blob/main/src/bin/wasm-tools/strip.rs |
| 744 | + // |
| 745 | + // TODO: Move that code into e.g. `wasm_encoder` so we can reuse it here |
| 746 | + // instead of duplicating it. |
| 747 | + |
| 748 | + let mut output = Vec::new(); |
| 749 | + let mut stack = Vec::new(); |
| 750 | + |
| 751 | + for payload in Parser::new(0).parse_all(input) { |
| 752 | + let payload = payload?; |
| 753 | + |
| 754 | + // Track nesting depth, so that we don't mess with inner producer sections: |
| 755 | + match payload { |
| 756 | + Payload::Version { encoding, .. } => { |
| 757 | + output.extend_from_slice(match encoding { |
| 758 | + wasmparser::Encoding::Component => &wasm_encoder::Component::HEADER, |
| 759 | + wasmparser::Encoding::Module => &wasm_encoder::Module::HEADER, |
| 760 | + }); |
| 761 | + } |
| 762 | + Payload::ModuleSection { .. } | Payload::ComponentSection { .. } => { |
| 763 | + stack.push(mem::take(&mut output)); |
| 764 | + continue; |
| 765 | + } |
| 766 | + Payload::End { .. } => { |
| 767 | + let mut parent = match stack.pop() { |
| 768 | + Some(c) => c, |
| 769 | + None => break, |
| 770 | + }; |
| 771 | + if output.starts_with(&wasm_encoder::Component::HEADER) { |
| 772 | + parent.push(ComponentSectionId::Component as u8); |
| 773 | + output.encode(&mut parent); |
| 774 | + } else { |
| 775 | + parent.push(ComponentSectionId::CoreModule as u8); |
| 776 | + output.encode(&mut parent); |
| 777 | + } |
| 778 | + output = parent; |
| 779 | + } |
| 780 | + _ => {} |
| 781 | + } |
| 782 | + |
| 783 | + if let Payload::CustomSection(ref c) = payload { |
| 784 | + let name = c.name(); |
| 785 | + if name != "name" && !name.starts_with("component-type:") && name != "dylink.0" { |
| 786 | + continue; |
| 787 | + } |
| 788 | + } |
| 789 | + |
| 790 | + if let Some((id, range)) = payload.as_section() { |
| 791 | + RawSection { |
| 792 | + id, |
| 793 | + data: &input[range], |
| 794 | + } |
| 795 | + .append_to(&mut output); |
| 796 | + } |
| 797 | + } |
| 798 | + |
| 799 | + Ok(output) |
| 800 | +} |
0 commit comments