VirtualBox共享文件夹中emcc编译HelloWorld WebAssembly报错求助
问题:VirtualBox共享文件夹中emcc编译Wasm失败,非共享文件夹正常
在VirtualBox主机与虚拟机的共享文件夹内使用emcc编译HelloWorld WebAssembly程序时出现错误,在虚拟机本地非共享文件夹中编译则完全正常,求原因。
程序代码
#include <stdio.h> int main() { printf("hello, world!\n"); return 0; }
编译命令
$ emcc ../main.c
emcc版本
$ emcc -v emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.28 (f11d6196dd4e8748a726f19895c859b40ff6a4f3) clang version 16.0.0 (https://github.com/llvm/llvm-project ea4be70cea8509520db8638bb17bcd7b5d8d60ac) Target: wasm32-unknown-emscripten Thread model: posix
Python版本
$ python --version Python 3.8.10
生成的文件
-rwxrwx--- 1 root systemd-coredump 13835 dec 13 08:44 a.out.wasm* -rwxrwx--- 1 root systemd-coredump 13835 dec 13 08:44 a.out.wasm.tmp31770cd*
报错信息
Traceback (most recent call last): File "/home/alex/hdd/repo/emsdk/upstream/emscripten/emcc.py", line 4309, in <module> sys.exit(main(sys.argv)) File "/usr/lib/python3.8/contextlib.py", line 75, in inner return func(*args, **kwds) File "/home/alex/hdd/repo/emsdk/upstream/emscripten/emcc.py", line 4302, in main ret = run(args) File "/home/alex/hdd/repo/emsdk/upstream/emscripten/emcc.py", line 1319, in run phase_post_link(options, state, wasm_target, wasm_target, target) File "/usr/lib/python3.8/contextlib.py", line 75, in inner return func(*args, **kwds) File "/home/alex/hdd/repo/emsdk/upstream/emscripten/emcc.py", line 3022, in phase_post_link phase_emscript(options, in_wasm, wasm_target, memfile) File "/usr/lib/python3.8/contextlib.py", line 75, in inner return func(*args, **kwds) File "/home/alex/hdd/repo/emsdk/upstream/emscripten/emcc.py", line 3052, in phase_emscript emscripten.run(in_wasm, wasm_target, final_js, memfile) File "/home/alex/hdd/repo/emsdk/upstream/emscripten/emscripten.py", line 893, in run emscript(in_wasm, out_wasm, outfile_js, memfile) File "/home/alex/hdd/repo/emsdk/upstream/emscripten/emscripten.py", line 318, in emscript metadata = finalize_wasm(in_wasm, wasm_target, memfile) File "/home/alex/hdd/repo/emsdk/upstream/emscripten/emscripten.py", line 525, in finalize_wasm metadata = get_metadata(infile, outfile, modify_wasm, args) File "/usr/lib/python3.8/contextlib.py", line 75, in inner return func(*args, **kwds) File "/home/alex/hdd/repo/emsdk/upstream/emscripten/emscripten.py", line 451, in get_metadata metadata = extract_metadata.extract_metadata(infile) File "/home/alex/hdd/repo/emsdk/upstream/emscripten/tools/extract_metadata.py", line 303, in extract_metadata with webassembly.Module(filename) as module: File "/home/alex/hdd/repo/emsdk/upstream/emscripten/tools/webassembly.py", line 192, in __init__ raise InvalidWasmError(f'{filename} is not a valid wasm file') tools.webassembly.InvalidWasmError: a.out.wasm is not a valid wasm file Exception ignored in: <function Module.__del__ at 0x7f45e8756dc0> Traceback (most recent call last): File "/home/alex/hdd/repo/emsdk/upstream/emscripten/tools/webassembly.py", line 196, in __del__ assert not self.buf, '`__exit__` should have already been called, please use context manager' AssertionError: `__exit__` should have already been called, please use context manager
原因分析
核心是VirtualBox共享文件夹的文件系统兼容性问题:
- emcc编译时会先生成带
.tmp后缀的临时文件,再通过重命名操作得到最终的Wasm文件。 - VirtualBox默认的
vboxsf共享文件系统不支持原子性重命名操作,且存在文件缓冲同步延迟。 - 当emcc尝试读取刚重命名的
a.out.wasm时,文件内容可能还未完全同步到磁盘,导致读取到不完整的无效Wasm文件。
生成文件的权限显示归属systemd-coredump组,这是共享文件夹权限映射的附加问题,但不是触发编译失败的核心原因。
解决方法
- 指定输出到本地目录:
用-o参数将编译产物直接输出到虚拟机本地非共享目录:emcc ../main.c -o /home/alex/local_output/a.out.wasm - 修改共享文件夹挂载选项:
挂载时添加direct_io和sync参数强制文件操作实时同步:
也可以修改sudo mount -t vboxsf shared_folder /mnt/shared -o direct_io,sync/etc/fstab配置,确保开机自动应用这些选项。 - 本地拷贝后编译:
将共享文件夹中的代码先复制到虚拟机本地目录,编译完成后再把产物复制回共享文件夹。
内容的提问来源于stack exchange,提问作者olyuboch
相关产品推荐
相关产品推荐

