Wasm项目集成data-fusion时zstd-sys依赖编译失败如何解决
问题描述
我是Rust初学者,在开发支持WebAssembly能力、引入data-fusion库的项目时遇到编译失败问题,初始报错如下:
error: failed to run custom build command for `zstd-sys v1.6.3+zstd.1.5.2`
核心报错信息:
- 编译目标为
wasm32-unknown-unknown,宿主机环境为x86_64-apple-darwin - 编译zstd、lz4依赖的C源码时,提示找不到
string.h、stdlib.h等系统头文件 - 手动添加
zstd-sys = "1.6.3+zstd.1.5.2"作为项目依赖后,报错仍然存在
完整错误日志核心片段:
warning: zstd/lib/common/zstd_deps.h:29:10: fatal error: 'string.h' file not found warning: #include <string.h> warning: ^~~~~~~~~~ warning: 1 error generated. warning: liblz4/lib/lz4.c:178:10: fatal error: 'stdlib.h' file not found warning: #include <stdlib.h> /* malloc, calloc, free */ warning: ^~~~~~~~~~ warning: 1 error generated. error: build failed Error: Compiling your crate to WebAssembly failed Caused by: failed to execute `cargo build`: exited with exit status: 101 full command: "cargo" "build" "--lib" "--release" "--target" "wasm32-unknown-unknown"
问题根因
wasm32-unknown-unknown是极简WASM编译目标,默认不提供C标准库头文件、sysroot等编译C代码所需的环境;而data-fusion依赖的zstd、lz4库默认会编译原生C源码实现,调用本地clang交叉编译时找不到WASM目标对应的C标准库头文件,直接报错。手动添加zstd-sys依赖没有修改其默认编译C源码的配置,所以无法解决问题。
解决方案
按优先级从高到低选择以下方案即可:
- 方案1:强制依赖使用纯Rust后端,跳过C源码编译(最适配
wasm32-unknown-unknown目标,不需要额外装工具链)
在项目Cargo.toml中添加以下配置,关闭zstd、lz4默认的C编译feature,启用纯Rust实现:
配置完成后清除之前的编译缓存:执行[dependencies] zstd = { version = "0.12", default-features = false, features = ["rust-backend"] } # 覆盖依赖默认feature,强制关闭C编译 [patch.crates-io] zstd-sys = { version = "1.6", features = ["pure-rust"] } lz4-sys = { version = "1.9", features = ["pure"] }cargo clean,再重新执行编译命令即可。 - 方案2:切换到带C标准库支持的WASI目标,适配C依赖编译
如果必须使用C版本的zstd、lz4实现,可以把编译目标从wasm32-unknown-unknown换成wasm32-wasi,搭配wasi-sdk提供的WASM版C标准库编译:- 安装wasi-sdk:执行
brew install wasi-sdk - 编译前配置环境变量,指定WASM目标的C编译器和sysroot路径:
export CC_wasm32_wasi=/usr/local/opt/wasi-sdk/bin/clang export CFLAGS_wasm32_wasi="--sysroot=/usr/local/opt/wasi-sdk/share/wasi-sysroot"- 将原来的编译命令目标改为
wasm32-wasi重新执行即可。
- 安装wasi-sdk:执行
- 方案3:给现有clang手动指定WASI sysroot路径,保留
wasm32-unknown-unknown目标
如果不想切换编译目标,可以安装wasi-sdk后,直接给当前clang添加sysroot参数,让它能找到WASM版本的系统头文件:
配置完成后重新编译即可。export CFLAGS_wasm32_unknown_unknown="--sysroot=/usr/local/opt/wasi-sdk/share/wasi-sysroot -D_WASI_EMULATED_MMAN"
内容的提问来源于stack exchange,提问作者MrElephant
相关产品推荐
相关产品推荐

