无法在 Linux 上编译为 .wasm

ern*_*rn0 5 linux llvm clang webassembly

概括

\n

(编辑:删除了所有不必要的信息,添加了Windows10体验,将Ubuntu上的CLANG升级到相同版本,由于旧的CLANG版本而删除了Debian10)

\n

我创建了一个非常简单的 WASM 模块,

\n
    \n
  • 在 MacOS 上编译,适用于 \xe2\x9c\x85,
  • \n
  • 在 MS-Windows10 上编译,适用于 \xe2\x9c\x85,
  • \n
  • 在 Ubuntu21.10 上编译:生成 318 字节的零 \xe2\x9d\x8c,
  • \n
\n

细节

\n

症状

\n

在 Ubuntu21 上,链接器生成长度正确但全是零的文件:

\n
$ hexdump inc.wasm\n0000000 0000 0000 0000 0000 0000 0000 0000 0000\n*\n0000130 0000 0000 0000 0000 0000 0000 0000\n000013e\n
Run Code Online (Sandbox Code Playgroud)\n

编译器还会生成一个名为 like 的临时文件inc.wasm.tmp611a2df,该文件与结果相同inc.wasm、大小相同、内容为零。

\n

构建命令

\n

编译命令:

\n
clang++ \\\n    --target=wasm32 \\\n    -nostdlib \\\n    -O3 \\\n    -o /tmp/inc.o \\\n    -c \\\n    inc.cpp\n
Run Code Online (Sandbox Code Playgroud)\n

它可以在任何平台上生成良好的目标文件(在 Ubuntu 上编译,然后在 MS-Windows10 上链接:有效)。

\n

链接命令是(在 MS-Windows10 上,使用插入符“^”而不是反斜杠“”):

\n
wasm-ld \\ \n    --no-entry \\\n    --export-all \\\n    --lto-O3 \\\n    --allow-undefined \\\n    --import-memory \\\n    /tmp/inc.o \\\n    -o inc.wasm\n
Run Code Online (Sandbox Code Playgroud)\n

版本

\n

苹果系统:

\n
$ clang --version\nHomebrew clang version 13.0.1\nTarget: x86_64-apple-darwin21.3.0\nThread model: posix\nInstalledDir: /usr/local/opt/llvm/bin\n
Run Code Online (Sandbox Code Playgroud)\n

乌班图21.10:

\n

编译器版本:

\n
$ clang --version\nUbuntu clang version 14.0.0-++20220316013357+add3ab7f4c8a-1~exp1~20220316133449.102\nTarget: x86_64-pc-linux-gnu\nThread model: posix\nInstalledDir: /usr/bin\n
Run Code Online (Sandbox Code Playgroud)\n

链接器版本:

\n
$ wasm-ld --version\nUbuntu LLD 14.0.0\n
Run Code Online (Sandbox Code Playgroud)\n

底线

\n

在带有 CLANG 版本 7 的 Debian10 上使用 strace,\nit 在创建结果文件后挂起,我在此处复制 strace 输出,但请记住,它是不同的版本:

\n
futex(0x7f514f8dc428, FUTEX_WAKE_PRIVATE, 2147483647) = 0\nfutex(0x7f514f8dc0c8, FUTEX_WAKE_PRIVATE, 2147483647) = 0\nfutex(0x7f514f8dc9d0, FUTEX_WAKE_PRIVATE, 2147483647) = 0\nfutex(0x7f514f8dc9d8, FUTEX_WAKE_PRIVATE, 2147483647) = 0\nopenat(AT_FDCWD, "/tmp/inc.o", O_RDONLY|O_CLOEXEC) = 3\nfstat(3, {st_mode=S_IFREG|0644, st_size=1556, ...}) = 0\npread64(3, "\\0asm\\1\\0\\0\\0\\1\\224\\200\\200\\200\\0\\4`\\1\\177\\1\\177`\\0\\0`\\2\\177\\177\\0`\\3\\177\\177"..., 1556, 0) = 1556\nclose(3)                                = 0\nbrk(0x1048000)                          = 0x1048000\nbrk(0x1046000)                          = 0x1046000\nstat("inc.wasm", 0x7ffc2e13ec08)        = -1 ENOENT (No such file or directory)\nopenat(AT_FDCWD, "/dev/urandom", O_RDONLY) = 3\nread(3, "6'\\242\\256", 4)                = 4\nclose(3)                                = 0\nopenat(AT_FDCWD, "inc.wasm.tmp0b96c6e", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0777) = 3\nfallocate(3, 0, 0, 1507)                = 0\nftruncate(3, 1507)                      = 0\nmmap(NULL, 1507, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0) = 0x7f514f918000\nsched_getaffinity(0, 128, [0])          = 64\nopenat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 4\nread(4, "0\\n", 8192)                    = 2\nclose(4)                                = 0\nmmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f514af2b000\nmprotect(0x7f514af2c000, 8388608, PROT_READ|PROT_WRITE) = 0\nclone(child_stack=0x7f514b72afb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f514b72b9d0, tls=0x7f514b72b700, child_tidptr=0x7f514b72b9d0) = 23331\nfutex(0x7ffc2e13eee8, FUTEX_WAIT_PRIVATE, 0, NULL\n
Run Code Online (Sandbox Code Playgroud)\n

我不知道发生了什么事。

\n

ern*_*rn0 5

我只是运气不好,有两个 Linux 虚拟机。一位朋友安装wasm-ld在他的 Arch Linux 上,并且开箱即用。

我已经将我的 Debian10 机器升级到 Debian11,安装wasm-ld-13后就可以正常工作了。

更新:创建了一个小项目,它展示了如何一步编译为 wasm: https: //github.com/ern0/howto-wasm-minimal