You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加opencascade依赖后,Rust编译WebAssembly缺失algorithm头文件报错

问题:Rust + Webpack编译Wasm时添加opencascade依赖后cxx crate编译失败

添加opencascade = "0.2.0"依赖后执行npm run build(对应webpack脚本)时,cxx crate编译报错提示找不到<algorithm>头文件,移除该依赖则编译正常。cargo update执行成功,尝试过配置build.rs指定C++头文件路径但未解决。


Cargo.toml配置

[package]
name = "wasm-demo"
version = "0.1.0"
authors = ["Ravi"]
edition = "2018"
[env]
LIBC_INCLUDE_DIR = { value = "/usr/include/c++/11", force = true, relative = false }

build = "build.rs"

[lib]
crate-type = ["cdylib"]

[dependencies]
console_error_panic_hook = "=0.1.5"
js-sys = "0.3.19"
lazy_static = "1.3.0"
nalgebra = "0.18.0"
opencascade = "0.2.0"

wasm-bindgen = "0.2.44"

[dependencies.web-sys]
version = "0.3.4"
features = [
    'Document',
    'Element',
    'EventTarget',
    'HtmlCanvasElement',
    'MouseEvent',
    'WebGlBuffer',
    'WebGlProgram',
    'WebGlRenderingContext',
    'WebGlShader',
    'WebGlUniformLocation',
    'Window',
]

编译错误信息

[INFO]: 🌀  Compiling to Wasm...
warning: unused manifest key: env
    Blocking waiting for file lock on package cache
   Compiling cxx v1.0.122
   Compiling wasm-demo v0.1.0 (/home/xxx/learning/wasm)
The following warnings were emitted during compilation:

warning: cxx@1.0.122: In file included from /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cxx-1.0.122/src/cxx.cc:1:
warning: cxx@1.0.122: /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cxx-1.0.122/src/../include/cxx.h:2:10: fatal error: 'algorithm' file not found
warning: cxx@1.0.122: #include <algorithm>
warning: cxx@1.0.122:          ^~~~~~~~~~~
warning: cxx@1.0.122: 1 error generated.

error: failed to run custom build command for `cxx v1.0.122`

Caused by:
  process didn't exit successfully: `/home/xxx/learning/wasm/target/debug/build/cxx-9e222f77eeee6661/build-script-build` (exit status: 1)
  --- stdout
  TARGET = Some("wasm32-unknown-unknown")
  OPT_LEVEL = Some("0")
  HOST = Some("x86_64-unknown-linux-gnu")
  cargo:rerun-if-env-changed=CXX_wasm32-unknown-unknown
  CXX_wasm32-unknown-unknown = None
  cargo:rerun-if-env-changed=CXX_wasm32_unknown_unknown
  CXX_wasm32_unknown_unknown = None
  cargo:rerun-if-env-changed=TARGET_CXX
  TARGET_CXX = None
  cargo:rerun-if-env-changed=CXX
  CXX = None
  cargo:rerun-if-env-changed=CC_ENABLE_DEBUG_OUTPUT
  cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("true")
  cargo:rerun-if-env-changed=CXXFLAGS_wasm32-unknown-unknown
  CXXFLAGS_wasm32-unknown-unknown = None
  cargo:rerun-if-env-changed=CXXFLAGS_wasm32_unknown_unknown
  CXXFLAGS_wasm32_unknown_unknown = None
  cargo:rerun-if-env-changed=TARGET_CXXFLAGS
  TARGET_CXXFLAGS = None
  cargo:rerun-if-env-changed=CXXFLAGS
  CXXFLAGS = None
  cargo:warning=In file included from /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cxx-1.0.122/src/cxx.cc:1:
  cargo:warning=/home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cxx-1.0.122/src/../include/cxx.h:2:10: fatal error: 'algorithm' file not found
  cargo:warning=#include <algorithm>
  cargo:warning=         ^~~~~~~~~~~
  cargo:warning=1 error generated.

  --- stderr


  error occurred: Command "clang" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "--target=wasm32-unknown-unknown" "-std=c++11" "-Wall" "-Wextra" "-o" "/home/xxx/learning/wasm/target/wasm32-unknown-unknown/debug/build/cxx-6e717868d7b84106/out/a01d5fedadde4775-cxx.o" "-c" "/home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cxx-1.0.122/src/cxx.cc" with args clang did not execute successfully (status code exit status: 1).

build.rs代码

// use std::process::Command;

// fn main() {
//     // Set the include paths for the required C++ headers
//     let include_paths = ["/usr/include/c++/11" ];

//     // Compile the Rust libraries with the required C++ headers
//     let mut cmd = Command::new("cargo");
//     cmd.arg("build")
//         .args(&include_paths.iter().flat_map(|path| vec!["--extra-include-dir", path]).collect::<Vec<&str>>());

//     let output = cmd.output().expect("failed to execute cargo build");

//     if !output.status.success() {
//         panic!("failed to compile Rust libraries:\n{}", String::from_utf8_lossy(&output.stderr));
//     }
// }


fn main() {
    println!("cargo:rustc-link-search=native=/usr/include/c++/11");
    println!("cargo::rustc-env=LIBC_INCLUDE_DIR=/usr/include/c++/11");
    println!("cargo::rustc-env=LIBCXX_INCLUDE_DIR=/usr/include/c++/11");
    println!("cargo::rustc-env=GLIBC_INCLUDE_DIR=/usr/include/c++/11");
    
}
// use cc::Build;
// fn main() {
//     cc::Build::new()
//         .include("/usr/include/c++/11")  
//         .flag("-g");

// }
// use std::process::Command;

// fn main() {
//     // Set the include path for the standard C++ headers
//     let output = Command::new("g++")
//         .arg("-c")
//         .arg("-I/usr/include/c++/11")
//         .output()
//         .expect("failed to execute process");

//     if !output.status.success() {
//         panic!("failed to compile C++ code:\n{}", String::from_utf8_lossy(&output.stderr));
//     }

//     // Link the compiled object file
//     println!("cargo:rustc-link-lib=static=cpp_code");
// }

解决方法

1. 安装Wasm专用的C++工具链

编译wasm32-unknown-unknown目标时,主机系统的/usr/include/c++/11是针对x86架构的,无法被Wasm目标的clang识别。推荐使用Emscripten工具链,它自带完整的Wasm C++运行环境:

# 克隆并安装Emscripten
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh

2. 指定C++编译器环境变量

在执行npm run build前,设置环境变量让cargo使用Emscripten的编译器:

export CXX=em++
export CXXFLAGS="-stdlib=libc++"

3. 修复build.rs配置

原build.rs存在语法错误(cargo::rustc-env多打了一个冒号),且未正确传递包含路径给cxx构建脚本。替换为以下代码:

use cc::Build;

fn main() {
    // 获取Emscripten的系统头文件路径
    let emscripten_sysroot = std::env::var("EMSDK").unwrap_or_default() + "/upstream/emscripten/cache/sysroot/include";
    
    Build::new()
        .include(emscripten_sysroot)
        .flag("-std=c++11")
        .flag("--target=wasm32-unknown-unknown")
        .compile("dummy"); // 编译空目标以触发cc配置生效
    
    // 让cxx crate感知环境变量变化
    println!("cargo:rerun-if-env-changed=CXX");
    println!("cargo:rerun-if-env-changed=CXXFLAGS");
}

4. 清理Cargo.toml无效配置

删除Cargo.toml中无效的[env]段(编译提示unused manifest key: env):

# 删除以下内容
[env]
LIBC_INCLUDE_DIR = { value = "/usr/include/c++/11", force = true, relative = false }

内容的提问来源于stack exchange,提问作者Ravi Belkhindi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:53:10