Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 76 additions & 1 deletion zstd-safe/zstd-sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::{env, fmt, fs};

#[cfg(feature = "bindgen")]
Expand Down Expand Up @@ -210,7 +211,7 @@ fn compile_zstd() {
// Hide symbols from resulting library,
// so we can be used with another zstd-linking lib.
// See https://github.com/gyscos/zstd-rs/issues/58
if ! cfg!(target_env = "msvc") {
if !cfg!(target_env = "msvc") {
config.flag("-fvisibility=hidden");
}
config.define("XXH_PRIVATE_API", Some(""));
Expand Down Expand Up @@ -263,13 +264,87 @@ fn cargo_print(content: &dyn fmt::Display) {
}
}

fn check_clang_wasm_support() {
// Use cc-rs to find the exact compiler it will use for this target,
// so we probe the same binary that compile_zstd() will invoke.
let compiler = cc::Build::new().get_compiler();
let clang = compiler.path().to_string_lossy().to_string();

// We must attempt actual code generation (not just -fsyntax-only),
// because Apple clang can parse for wasm32 but cannot emit code for it.
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let test_obj = out_dir.join("__wasm_probe.o");

let output = Command::new(compiler.path())
.args([
"--target=wasm32-unknown-unknown",
"-x", "c",
"-c", // compile to object (exercises the backend)
"-o",
])
.arg(&test_obj)
.arg("-") // read from stdin
.stdin(std::process::Stdio::null())
.output();

match output {
Err(e) => {
panic!(
"\n\n\
Could not run `{}`: {}\n\
\n\
To build for wasm32-unknown-unknown on macOS you need LLVM's clang,\n\
which ships with wasm32 target support. Fix:\n\
\n\
brew install llvm\n\
export PATH=\"/opt/homebrew/opt/llvm/bin:$PATH\"\n\
\n\
Then re-run your build.\n",
clang, e
);
}
Ok(out) => {
let stderr = String::from_utf8_lossy(&out.stderr);
if stderr
.contains("No available targets are compatible with triple")
{
panic!(
"\n\n\
The `clang` on your PATH ({}) does not support\n\
target `wasm32-unknown-unknown`.\n\
\n\
This is likely the Apple/Xcode clang, which omits wasm backends.\n\
Fix by installing LLVM via Homebrew and prepending it to PATH:\n\
\n\
brew install llvm\n\
export PATH=\"/opt/homebrew/opt/llvm/bin:$PATH\"\n\
\n\
Then re-run your build.\n\
\n\
Alternatively, pin the env var for just this build:\n\
\n\
CC=/opt/homebrew/opt/llvm/bin/clang cargo build \
--target wasm32-unknown-unknown\n",
clang
);
}
// Probe succeeded — clean up the test object
let _ = fs::remove_file(&test_obj);
}
}
}

fn main() {
cargo_print(&"rerun-if-env-changed=ZSTD_SYS_USE_PKG_CONFIG");

let target_arch =
std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();

if target_arch == "wasm32" {
check_clang_wasm_support();
}

if target_arch == "wasm32" || target_os == "hermit" {
cargo_print(&"rustc-cfg=feature=\"std\"");
}
Expand Down