【问题标题】:Error in compiling Rust into webassembly using emscripten on Windows在 Windows 上使用 emscripten 将 Rust 编译为 webassembly 时出错
【发布时间】:2021-08-01 02:22:06
【问题描述】:

我刚刚尝试在 Windows 上使用 emscripten 将 Rust 示例项目编译成 webassembly,但它会导致错误。 我该如何解决?

我做了什么:

  1. 安装 emscripten
>git clone https://github.com/emscripten-core/emsdk.git
>cd emsdk
>git pull
>emsdk install latest
>emsdk activate latest
>emsdk_env.bat
  1. 安装 rustup 从https://www.rust-lang.org/ja/tools/install 下载 rustup-init.exe 并运行它
  2. 通过 rustup 安装 wasm32 目标
>rustup target add wasm32-unknown-emscripten
  1. 创建示例项目
>cargo new --bin web_assembly
>cd web_assembly
  1. 尝试编译,出现错误
>cargo build --target wasm32-unknown-emscripten
   Compiling web_assembly v0.1.0 (F:\github\rusttest\web_assembly)
error: linking with `emcc.bat` failed: exit code: 1
  |
  = note: "cmd" "/c" "emcc.bat" "-s" "DISABLE_EXCEPTION_CATCHING=0" "-L" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib" "-L" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\self-contained" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.web_assembly.egwz9uoo-cgu.0.rcgu.o" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.web_assembly.egwz9uoo-cgu.1.rcgu.o" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.web_assembly.egwz9uoo-cgu.2.rcgu.o" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.web_assembly.egwz9uoo-cgu.3.rcgu.o" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.web_assembly.egwz9uoo-cgu.4.rcgu.o" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.web_assembly.egwz9uoo-cgu.5.rcgu.o" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.web_assembly.egwz9uoo-cgu.6.rcgu.o" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.web_assembly.egwz9uoo-cgu.7.rcgu.o" "-o" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.js" "-s" "EXPORTED_FUNCTIONS=[\"_main\",\"_rust_eh_personality\"]" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps\\web_assembly.3a2jxscq1lvbzwaf.rcgu.o" "-O0" "--memory-init-file" "0" "-g4" "-s" "DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[]" "-L" "F:\\github\\rusttest\\web_assembly\\target\\wasm32-unknown-emscripten\\debug\\deps" "-L" "F:\\github\\rusttest\\web_assembly\\target\\debug\\deps" "-L" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\libstd-28368703ab79076a.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\libpanic_unwind-c6cbccdff18b55f7.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\librustc_demangle-a5ffc5310c14c91c.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\libhashbrown-08c349e57dac68c0.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\librustc_std_workspace_alloc-ce3363c7b27912b6.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\libunwind-686deac84d1c117a.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\libcfg_if-1aefc0615f4a87c4.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\liblibc-35a51890c8428321.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\liballoc-d41456f5d5a426f6.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\librustc_std_workspace_core-2a7cc4e4deb2c4e8.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\libcore-997b7450818c8186.rlib" "C:\\Users\\Username\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\wasm32-unknown-emscripten\\lib\\libcompiler_builtins-68f9d21fef2c27f2.rlib" "-l" "c" "-s" "ERROR_ON_UNDEFINED_SYMBOLS=1" "-s" "ASSERTIONS=1" "-s" "ABORTING_MALLOC=0" "-Wl,--fatal-warnings"
  = note: shared:INFO: (Emscripten: Running sanity checks)
          emcc: warning: please replace -g4 with -gsource-map [-Wdeprecated]
          error: undefined symbol: __gxx_personality_v0 (referenced by top-level compiled C/C++ code)
          warning: Link with `-s LLD_REPORT_UNDEFINED` to get more information on undefined symbols
          warning: To disable errors for undefined symbols use `-s ERROR_ON_UNDEFINED_SYMBOLS=0`
          warning: ___gxx_personality_v0 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
          Error: Aborting compilation due to previous errors
          emcc: error: 'F:/github/emsdk/node/14.15.5_64bit/bin/node.exe F:\github\emsdk\upstream\emscripten\src\compiler.js C:\Users\Username\AppData\Local\Temp\tmpang8muuo.txt' failed (1)


error: aborting due to previous error

error: could not compile `web_assembly`

To learn more, run the command again with --verbose.

工具版本:

>emcc.bat --version
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.20-git (8ed0f4fee2abd04923c2fd2bf44835169ce2ac2e)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

>rustup --version
rustup 1.24.1 (a01bd6b0d 2021-04-27)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.52.1 (9bc8c42bb 2021-05-09)`

【问题讨论】:

  • 如果 Emscripten 不是硬性要求,您可能会对 wasm32-unknown-unknown 目标有更好的体验。我什至不确定 Emscripten 目标这些天是否得到了很好的维护。 Rust and WebAssembly book 提供教程和有用的资源。
  • 谢谢,它有效!也许我引用的文章有点老了。但是我应该如何用你的评论关闭这张票?请您回答一下好吗?

标签: windows rust webassembly emscripten rustup


【解决方案1】:

如果您想要/需要 emscripten(使用基于 c 或 c++ 的 crates 或喜欢工作 dwarf 调试),这里是修复构建错误的方法。

错误原因在这里描述:https://github.com/rust-lang/rust/issues/85821

解决方法是:

为缺少的函数创建存根(另存为文件 gxx_personality_v0_stub.cpp):

#include "unwind.h"
#include "stdint.h"

extern "C" _Unwind_Reason_Code __gxx_personality_v0   (int version, _Unwind_Action actions, uint64_t exceptionClass, _Unwind_Exception* unwind_exception, _Unwind_Context* context) {
    return  _URC_NO_REASON;
}

使用 emcc 构建:

emcc -c gxx_personality_v0_stub.cpp

创建/修改 .cargo/config 文件:

[build]
rustflags = ["-C", "link-args=gxx_personality_v0_stub.o"]

享受最新的 rust(使用 v1.55.0 测试)和 emscripten (v2.0.29)

注意:Stack unwind on panic 不适用于此存根。但是由于该函数在 emscripten 中无论如何都被存根了,因此您不会缺少任何功能。

【讨论】:

    【解决方案2】:

    Emscripten 使用树尖 LLVM,它可能与 Rust 使用的更稳定版本的 LLVM 不兼容。这意味着您必须使用特定版本的 Emscripten 和与 Rust 的 LLVM 版本非常匹配的 LLVM,而不是使用 latest

    自 Rust 52 以来最接近 Rust 的 LLVM 的 Emscripten 版本是 Emscripten 2.0.13,所以我会尝试使用它。

    记录和跟踪使用的最佳 Emscripten 版本的最佳资源是 https://blog.therocode.net/2020/10/a-guide-to-rust-sdl2-emscripten,尽管它尚未针对 Rust 52+ 进行更新。

    【讨论】:

    • 我刚试了 Rust 1.52、Emscripten 2.0.13 的组合,也出现了同样的错误。链接的博客文章 (1.47 / 1.39.20) 中提到的组合有效。
    【解决方案3】:

    如果您不严格要求 Emscripten,则应使用 Rust 的自定义 WASM 支持,可通过 wasm32-unknown-unknown 获得,因为这是大多数与 Rust 相关的 WASM 开发的地方。

    如果您想了解如何使用此目标的示例,请查看Rust WASM book

    【讨论】:

      【解决方案4】:

      您也可以使用 EMMAKEN_CFLAGS 作为解决方法:

      EMMAKEN_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0 --no-entry" cargo build --target wasm32-unknown-emscripten
      

      【讨论】:

        【解决方案5】:

        没有找到错误的真正原因。然而,我确定了哪个 emcc 版本停止使用 rust(用最新的稳定版 1.55.0 测试)。 Emscripten 2.0.9 有效,但 Emscripten 2.0.10 失败并出现 ___gxx_personality_v0 错误。

        【讨论】:

          猜你喜欢
          • 2020-08-23
          • 2020-12-06
          • 2018-09-21
          • 2020-04-22
          • 1970-01-01
          • 1970-01-01
          • 2019-01-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多