emscripten
emscripten copied to clipboard
WASMFS Mouting OPFS from js
Please include the following in your bug report:
Version of emscripten/emsdk: emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.61-git (67fa4c16496b157a7fc3377afd69ee0445e8a6e3) clang version 19.0.0git (/startdir/llvm-project 7cfffe74eeb68fbb3fb9706ac7071f8caeeb6520) Target: wasm32-unknown-emscripten Thread model: posix InstalledDir: /opt/emscripten-llvm/bin
Failing command line in full:
emcc -sEXPORTED_RUNTIME_METHODS=FS,OPFS,getValue,setValue,UTF8ToString,lengthBytesUTF8,stringToUTF8,cwrap,ccall,addFunction,wasmfsOPFSGetOrCreateDir,wasmfs_create_directory -lopfs.js -sWASMFS -sFORCE_FILESYSTEM main.c -g -sASYNCIFY=2 --profiling -o index.htm
Full link command and output with -v appended:
Even for runtime issues it helps a lot if you can include the full link command.
Adding -v to the link command will show all of the sub-commands run which
can help us diagnose your issue.
/opt/emscripten-llvm/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/home/alice/.emscripten_cache/sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -g3 -v main.c -c -o /tmp/emscripten_temp_59kznkl1/main_0.o
clang version 19.0.0git (/startdir/llvm-project 7cfffe74eeb68fbb3fb9706ac7071f8caeeb6520)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /opt/emscripten-llvm/bin
(in-process)
"/opt/emscripten-llvm/bin/clang-19" -cc1 -triple wasm32-unknown-emscripten -emit-obj -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -fvisibility=hidden -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb -fdebug-compilation-dir=/home/alice/git-applications/emscriptenwasmfs -v -fcoverage-compilation-dir=/home/alice/git-applications/emscriptenwasmfs -resource-dir /opt/emscripten-llvm/lib/clang/19 -D EMSCRIPTEN -isysroot /home/alice/.emscripten_cache/sysroot -internal-isystem /opt/emscripten-llvm/lib/clang/19/include -internal-isystem /home/alice/.emscripten_cache/sysroot/include/wasm32-emscripten -internal-isystem /home/alice/.emscripten_cache/sysroot/include -Werror=implicit-function-declaration -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fignore-exceptions -iwithsysroot/include/fakesdl -iwithsysroot/include/compat -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o /tmp/emscripten_temp_59kznkl1/main_0.o -x c main.c
clang -cc1 version 19.0.0git based upon LLVM 19.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/home/alice/.emscripten_cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
/home/alice/.emscripten_cache/sysroot/include/fakesdl
/home/alice/.emscripten_cache/sysroot/include/compat
/opt/emscripten-llvm/lib/clang/19/include
/home/alice/.emscripten_cache/sysroot/include
End of search list.
/opt/emscripten-llvm/bin/clang --version
emcc: warning: -sASYNCIFY=2 (JSPI) is still experimental [-Wexperimental]
/opt/emscripten-llvm/bin/wasm-ld -o index.wasm -L/home/alice/.emscripten_cache/sysroot/lib/wasm32-emscripten /tmp/emscripten_temp_59kznkl1/main_0.o -lGL-getprocaddr -lal -lhtml5 -lstubs-debug -lnoexit -lc-debug -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-debug-noexcept -lsockets -lwasmfs-debug -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmpul2xwpwslibemscripten_js_symbols.so --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=wasmfs_flush --export=emscripten_builtin_memalign --export=wasmfs_create_file --export=_wasmfs_mount --export=_wasmfs_unmount --export=_wasmfs_read_file --export=_wasmfs_write_file --export=_wasmfs_open --export=_wasmfs_allocate --export=_wasmfs_close --export=_wasmfs_write --export=_wasmfs_pwrite --export=_wasmfs_rename --export=_wasmfs_mkdir --export=_wasmfs_unlink --export=_wasmfs_chdir --export=_wasmfs_mknod --export=_wasmfs_rmdir --export=_wasmfs_mmap --export=_wasmfs_munmap --export=_wasmfs_msync --export=_wasmfs_read --export=_wasmfs_pread --export=_wasmfs_symlink --export=_wasmfs_truncate --export=_wasmfs_ftruncate --export=_wasmfs_stat --export=_wasmfs_lstat --export=_wasmfs_chmod --export=_wasmfs_fchmod --export=_wasmfs_lchmod --export=_wasmfs_utime --export=_wasmfs_llseek --export=_wasmfs_identify --export=_wasmfs_readlink --export=_wasmfs_readdir_start --export=_wasmfs_readdir_get --export=_wasmfs_readdir_finish --export=_wasmfs_get_cwd --export=_emscripten_stack_alloc --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export=_emscripten_stack_restore --export=malloc --export=free --export=wasmfs_create_jsimpl_backend --export=wasmfs_create_opfs_backend --export=wasmfs_create_memory_backend --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --no-growable-memory --initial-heap=16777216 --no-entry --stack-first --table-base=1
/opt/emscripten-llvm/bin/llvm-objcopy index.wasm index.wasm --remove-section=producers
/usr/bin/wasm-emscripten-finalize -g --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers --dwarf index.wasm -o index.wasm --detect-features
/usr/bin/node /usr/lib/emscripten/src/compiler.mjs /tmp/tmpkfjok0o6.json
warning: invalid item in EXPORTED_RUNTIME_METHODS: wasmfs_create_directory
emcc: warning: warnings in JS library compilation [-Wjs-compiler]
/usr/bin/node /usr/lib/emscripten/tools/preprocessor.mjs /tmp/emscripten_temp_59kznkl1/settings.js shell.html
Note: Where possible, please avoid attaching screen shots of code or console logs. Instead, please include them as text so that they may be copied / searched. To make code blocks more readable and syntax highlighted, please escape them with three backticks before and after, like this:
withStackSave(async() => {
__wasmfs_mount(stringToUTF8OnStack("/opfs"), OPFS.createBackend())
})
doesn't work, gives an error
memory_backend.h:63 Uncaught (in promise) RuntimeError: invalid suspender object for suspend
at index.wasm.(anonymous namespace)::OPFSBackend::createDirectory(unsigned int) (http://localhost:8001/index.wasm:wasm-function[648]:0x1aca6)
at index.wasm.doMkdir(wasmfs::path::ParsedParent, int, wasmfs::Backend*) (http://localhost:8001/index.wasm:wasm-function[447]:0x11cbf)
at index.wasm.wasmfs_create_directory (http://localhost:8001/index.wasm:wasm-function[446]:0x119f5)
at index.wasm._wasmfs_mount (http://localhost:8001/index.wasm:wasm-function[608]:0x1a1e2)
at ret.<computed> (http://localhost:8001/index.js:2693:24)
at http://localhost:8001/index.js:655:12
at <anonymous>:2:5
at withStackSave (http://localhost:8001/index.js:2000:17)
at <anonymous>:1:1
but mounting memfs the same way
withStackSave(async() => {
__wasmfs_mount(stringToUTF8OnStack("/opfs"), MEMFS.createBackend())
})
works without error
I'm not sure what's going wrong, but __wasmfs_mount is an internal method, and isn't meant to be used from user code like that. We don't have any tests for using it that way. Instead, from C/C++ you can call wasmfs_create_directory to mount a backend as a directory, after calling wasmfs_create_opfs_backend to make an OPFS backend.
But cc @tlively @brendandahl as the larger issue here may be, do we have async creation/mounting support for OPFS? It seems that we have a TODO for it:
https://github.com/emscripten-core/emscripten/blob/8c81cac1bbae378bc7dde0c21c99602cbaf452d0/system/include/emscripten/wasmfs.h#L64-L73
I had an initial PR up adding async constructors, but it ran into some preliminary issues that I never ended up fixing: https://github.com/emscripten-core/emscripten/pull/20326