Skip to content

Commit 5dc3da6

Browse files
author
Gentle
committed
add zlib, bzip2, libxz and zstd
1 parent 1571725 commit 5dc3da6

File tree

2 files changed

+167
-3
lines changed

2 files changed

+167
-3
lines changed

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,17 @@ tempfile = "3.13.0"
6565

6666
[build-dependencies]
6767
anyhow = "1.0.89"
68+
reqwest = { version = "0.12.15", features = [
69+
"blocking",
70+
"brotli",
71+
"deflate",
72+
"gzip",
73+
"zstd",
74+
] }
6875
tar = "0.4.41"
6976
zstd = "0.13.2"
7077
test-generator = { path = "test-generator" }
78+
flate2 = "1.1.1"
7179

7280
[workspace]
7381
members = ["runtime", "shared", "test-generator"]

build.rs

Lines changed: 159 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,11 @@ fn find_python_binary(cpython_dir: &Path) -> Option<&'static str> {
272272
fn maybe_make_cpython(repo_dir: &Path, wasi_sdk: &Path) -> Result<()> {
273273
let cpython_wasi_dir = repo_dir.join("cpython/builddir/wasi");
274274
if !cpython_wasi_dir.join("libpython3.14.so").exists() {
275+
fs::create_dir_all(&cpython_wasi_dir)?;
275276
if !cpython_wasi_dir.join("libpython3.14.a").exists() {
276277
let cpython_native_dir = repo_dir.join("cpython/builddir/build");
277278
if let None = find_python_binary(&cpython_native_dir) {
278279
fs::create_dir_all(&cpython_native_dir)?;
279-
fs::create_dir_all(&cpython_wasi_dir)?;
280280

281281
run(Command::new("../../configure")
282282
.current_dir(&cpython_native_dir)
@@ -288,9 +288,15 @@ fn maybe_make_cpython(repo_dir: &Path, wasi_sdk: &Path) -> Result<()> {
288288
run(Command::new("make").current_dir(&cpython_native_dir))?;
289289
}
290290
let Some(python_executable) = find_python_binary(&cpython_native_dir) else {
291-
bail!("python binary not found");
291+
anyhow::bail!("python binary not found");
292292
};
293293

294+
let lib_install_dir = cpython_wasi_dir.join("deps");
295+
build_zlib(wasi_sdk, &lib_install_dir)?;
296+
build_bzip2(wasi_sdk, &lib_install_dir)?;
297+
build_xz(wasi_sdk, &lib_install_dir)?;
298+
build_zstd(wasi_sdk, &lib_install_dir)?;
299+
294300
let config_guess =
295301
run(Command::new("../../config.guess").current_dir(&cpython_wasi_dir))?;
296302

@@ -299,7 +305,14 @@ fn maybe_make_cpython(repo_dir: &Path, wasi_sdk: &Path) -> Result<()> {
299305
"CONFIG_SITE",
300306
"../../Tools/wasm/wasi/config.site-wasm32-wasi",
301307
)
302-
.env("CFLAGS", "-fPIC")
308+
.env(
309+
"CFLAGS",
310+
format!("-fPIC -I{}/deps/include", cpython_wasi_dir.display()),
311+
)
312+
.env(
313+
"LDFLAGS",
314+
format!("-L{}/deps/lib", cpython_wasi_dir.display()),
315+
)
303316
.current_dir(&cpython_wasi_dir)
304317
.args([
305318
"../../configure",
@@ -336,6 +349,10 @@ fn maybe_make_cpython(repo_dir: &Path, wasi_sdk: &Path) -> Result<()> {
336349
.arg(cpython_wasi_dir.join("Modules/_hacl/libHacl_Hash_SHA3.a"))
337350
.arg(cpython_wasi_dir.join("Modules/_decimal/libmpdec/libmpdec.a"))
338351
.arg(cpython_wasi_dir.join("Modules/expat/libexpat.a"))
352+
.arg(cpython_wasi_dir.join("deps/lib/libz.a"))
353+
.arg(cpython_wasi_dir.join("deps/lib/libbz2.a"))
354+
.arg(cpython_wasi_dir.join("deps/lib/liblzma.a"))
355+
.arg(cpython_wasi_dir.join("deps/lib/libzstd.a"))
339356
.arg("-lwasi-emulated-signal")
340357
.arg("-lwasi-emulated-getpid")
341358
.arg("-lwasi-emulated-process-clocks")
@@ -395,3 +412,142 @@ fn make_pyo3_config(repo_dir: &Path) -> Result<()> {
395412

396413
Ok(())
397414
}
415+
416+
fn fetch_extract(url: &str, out_dir: &Path) -> Result<()> {
417+
let response = reqwest::blocking::get(url)?;
418+
let decoder = flate2::read::GzDecoder::new(response);
419+
let mut archive = tar::Archive::new(decoder);
420+
archive.unpack(out_dir)?;
421+
Ok(())
422+
}
423+
424+
fn add_compile_envs(wasi_sdk: &Path, command: &mut Command) {
425+
let sysroot = wasi_sdk.join("share/wasi-sysroot");
426+
let sysroot = sysroot.to_string_lossy();
427+
command
428+
.env("AR", wasi_sdk.join("bin/ar"))
429+
.env("CC", wasi_sdk.join("bin/clang"))
430+
.env("RANLIB", wasi_sdk.join("bin/ranlib"))
431+
.env(
432+
"CFLAGS",
433+
format!("--target=wasm32-wasi --sysroot={sysroot} -I{sysroot}/include/wasm32-wasip1 -D_WASI_EMULATED_SIGNAL -fPIC"),
434+
)
435+
.env(
436+
"LDFLAGS",
437+
format!("--target=wasm32-wasip2 --sysroot={sysroot} -L{sysroot}/lib -lwasi-emulated-signal")
438+
);
439+
}
440+
441+
fn copy_headers(from: &Path, to: &Path) -> Result<()> {
442+
for entry in fs::read_dir(from)? {
443+
let entry = entry?;
444+
let path = entry.path();
445+
446+
if let Some(ext) = path.extension() {
447+
if ext == "h" {
448+
let filename = path.file_name().unwrap();
449+
fs::copy(&path, to.join(filename))?;
450+
}
451+
}
452+
}
453+
Ok(())
454+
}
455+
456+
fn build_zlib(wasi_sdk: &Path, install_dir: &Path) -> Result<()> {
457+
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
458+
fetch_extract(
459+
"https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz",
460+
&out_dir,
461+
)?;
462+
let src_dir = out_dir.join("zlib-1.3.1");
463+
let mut configure = Command::new("./configure");
464+
configure
465+
.current_dir(&src_dir)
466+
.arg("--static")
467+
.arg(format!("--prefix={}", install_dir.display()));
468+
add_compile_envs(wasi_sdk, &mut configure);
469+
run(&mut configure)?;
470+
let mut make = Command::new("make");
471+
add_compile_envs(wasi_sdk, &mut make);
472+
make.current_dir(src_dir)
473+
.arg(format!("AR={}", wasi_sdk.join("bin/ar").display()))
474+
.arg(format!("ARFLAGS=rcs"))
475+
.arg(format!("CC={}", wasi_sdk.join("bin/clang").display()))
476+
.arg("static")
477+
.arg("install");
478+
run(&mut make)?;
479+
Ok(())
480+
}
481+
482+
fn build_bzip2(wasi_sdk: &Path, install_dir: &Path) -> Result<()> {
483+
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
484+
fetch_extract(
485+
"https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz",
486+
&out_dir,
487+
)?;
488+
let src_dir = out_dir.join("bzip2-1.0.8");
489+
let mut command = Command::new("make");
490+
command
491+
.current_dir(&src_dir)
492+
.arg(format!("CC={}", wasi_sdk.join("bin/clang").display()))
493+
.arg(format!("AR={}", wasi_sdk.join("bin/ar").display()))
494+
.arg(format!("RANLIB={}", wasi_sdk.join("bin/ranlib").display()))
495+
.arg("CFLAGS=\"-fPIC\"")
496+
.arg("libbz2.a");
497+
add_compile_envs(wasi_sdk, &mut command);
498+
run(&mut command)?;
499+
copy_headers(&src_dir, &install_dir.join("include"))?;
500+
fs::copy(src_dir.join("libbz2.a"), install_dir.join("lib/libbz2.a"))?;
501+
Ok(())
502+
}
503+
504+
fn build_xz(wasi_sdk: &Path, install_dir: &Path) -> Result<()> {
505+
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
506+
fetch_extract(
507+
"https://github.com/tukaani-project/xz/releases/download/v5.8.1/xz-5.8.1.tar.gz",
508+
&out_dir,
509+
)?;
510+
let src_dir = out_dir.join("xz-5.8.1");
511+
let mut command = Command::new("./autogen.sh");
512+
command.current_dir(&src_dir);
513+
add_compile_envs(wasi_sdk, &mut command);
514+
run(&mut command)?;
515+
let mut command = Command::new("./configure");
516+
command
517+
.current_dir(&src_dir)
518+
.arg(format!("--prefix={}", install_dir.display()))
519+
.arg("--host=wasm32-unknown-wasi")
520+
.arg("--enable-threads=no")
521+
.arg("--disable-xz")
522+
.arg("--disable-xzdec")
523+
.arg("--disable-lzmadec")
524+
.arg("--disable-lzmainfo")
525+
.arg("--disable-lzma-links")
526+
.arg("--disable-scripts")
527+
.arg("--disable-doc")
528+
.arg("--disable-shared")
529+
.arg("--enable-static");
530+
add_compile_envs(wasi_sdk, &mut command);
531+
run(&mut command)?;
532+
let mut command = Command::new("make");
533+
add_compile_envs(wasi_sdk, &mut command);
534+
command.current_dir(&src_dir).arg("all").arg("install");
535+
run(&mut command)?;
536+
Ok(())
537+
}
538+
539+
fn build_zstd(wasi_sdk: &Path, install_dir: &Path) -> Result<()> {
540+
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
541+
fetch_extract(
542+
"https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz",
543+
&out_dir,
544+
)?;
545+
let src_dir = out_dir.join("zstd-1.5.7/lib");
546+
let mut command = Command::new("make");
547+
add_compile_envs(wasi_sdk, &mut command);
548+
command.current_dir(&src_dir).arg("libzstd.a");
549+
run(&mut command)?;
550+
copy_headers(&src_dir, &install_dir.join("include"))?;
551+
fs::copy(src_dir.join("libzstd.a"), install_dir.join("lib/libzstd.a"))?;
552+
Ok(())
553+
}

0 commit comments

Comments
 (0)