4

我只是尝试在 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)`
4

5 回答 5

7

如果您想要/需要 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 中无论如何都被存根,因此您不会缺少任何功能。

于 2021-09-15T18:26:05.783 回答
5

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 进行更新+。

于 2021-05-26T22:58:59.997 回答
3

您还可以使用EMCC_CFLAGS作为解决方法:

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

在旧版本中,此标志称为EMMAKEN_CFLAGS

EMMAKEN_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0 --no-entry" cargo build --target wasm32-unknown-emscripten
于 2021-12-07T04:51:11.857 回答
2

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

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

于 2021-05-10T18:18:40.097 回答
1

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

于 2021-09-13T13:46:14.507 回答