Description
When emscripten is installed to a location with read-only permissions (such as when installed with Nix) and the EM_CACHE
environment variable is set to a folder with read-write-execute permissions, the emcc
command still crashes when installing the system headers in the EM_CACHE
.
Version of emscripten/emsdk:
Please include the output emcc -v
here
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 4.0.8-git
clang version 20.1.4
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /nix/store/cf6j1f9f0z1syny3dgbickzc42zgcxhf-clang-20.1.4/bin
This bug does not occur with emcc 3.1.73
Failing command line in full:
If this is compile or link-time failure please include the full failing command
along with its entire output.
Log
Using an example.cpp
with the contents:
#include <iostream>
int main(int argc, char** argv) {
return 0;
}
Running emcc
:
% EM_CACHE="$PWD"/emscriptencache emcc example.cpp
cache:INFO: generating system headers: sysroot_install.stamp... (this will be cached in "/private/tmp/example/emscriptencache/sysroot_install.stamp" for subsequent builds)
Traceback (most recent call last):
File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/emcc.py", line 1597, in <module>
sys.exit(main(sys.argv))
^^^^^^^^^^^^^^
File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/contextlib.py", line 81, in inner
return func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^
File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/emcc.py", line 1590, in main
ret = run(args)
^^^^^^^^^
File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/emcc.py", line 670, in run
linker_args = phase_compile_inputs(options, state, newargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/contextlib.py", line 81, in inner
return func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^
File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/emcc.py", line 919, in phase_compile_inputs
system_libs.ensure_sysroot()
File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/contextlib.py", line 81, in inner
return func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^
File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/tools/system_libs.py", line 2519, in ensure_sysroot
cache.get('sysroot_install.stamp', install_system_headers, what='system headers')
File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/tools/cache.py", line 179, in get
creator(str(cachename))
File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/tools/system_libs.py", line 2486, in install_system_headers
copytree_exist_ok(src, dest)
File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/tools/system_libs.py", line 2463, in copytree_exist_ok
shutil.copytree(src, dst, dirs_exist_ok=True)
File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/shutil.py", line 600, in copytree
return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/shutil.py", line 554, in _copytree
raise Error(errors)
shutil.Error: [('/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/system/lib/compiler-rt/include/sanitizer', '/private/tmp/example/emscriptencache/sysroot/include/sanitizer', "[Errno 13] Permission denied: '/private/tmp/example/emscriptencache/sysroot/include/sanitizer'")]
Example of permissions in system installation (/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/system/lib/compiler-rt/include/sanitizer
):
total 692
dr-xr-xr-x 18 root nixbld 576 Dec 31 1969 .
dr-xr-xr-x 3 root nixbld 96 Dec 31 1969 ..
-r--r--r-- 1 root nixbld 4973 Dec 31 1969 allocator_interface.h
-r--r--r-- 1 root nixbld 13654 Dec 31 1969 asan_interface.h
-r--r--r-- 1 root nixbld 20763 Dec 31 1969 common_interface_defs.h
-r--r--r-- 1 root nixbld 1133 Dec 31 1969 coverage_interface.h
-r--r--r-- 1 root nixbld 10102 Dec 31 1969 dfsan_interface.h
-r--r--r-- 1 root nixbld 5043 Dec 31 1969 hwasan_interface.h
-r--r--r-- 1 root nixbld 219473 Dec 31 1969 linux_syscall_hooks.h
-r--r--r-- 1 root nixbld 3993 Dec 31 1969 lsan_interface.h
-r--r--r-- 1 root nixbld 2648 Dec 31 1969 memprof_interface.h
-r--r--r-- 1 root nixbld 5992 Dec 31 1969 msan_interface.h
-r--r--r-- 1 root nixbld 355693 Dec 31 1969 netbsd_syscall_hooks.h
-r--r--r-- 1 root nixbld 2835 Dec 31 1969 nsan_interface.h
-r--r--r-- 1 root nixbld 1513 Dec 31 1969 scudo_interface.h
-r--r--r-- 1 root nixbld 14952 Dec 31 1969 tsan_interface.h
-r--r--r-- 1 root nixbld 11232 Dec 31 1969 tsan_interface_atomic.h
-r--r--r-- 1 root nixbld 1044 Dec 31 1969 ubsan_interface.h
Note that the corresponding folder in EM_CACHE
-- /private/tmp/example/emscriptencache/sysroot/include/sanitizer
-- is not actually created.
The files that do get installed have the permission bits copied from the system installation:
ls -la emscriptencache/sysroot/include/fakesdl | head -n 5
total 212
dr-xr-xr-x 55 bryantan wheel 1760 Dec 31 1969 .
dr-xr-xr-x 21 bryantan wheel 672 Dec 31 1969 ..
-r--r--r-- 1 bryantan wheel 72 Dec 31 1969 SDL.h
-r--r--r-- 1 bryantan wheel 72 Dec 31 1969 SDL_assert.h
A workaround for this bug is to copy the system installation of the cache manually and change the permissions bits before running emcc
.
EM_CACHE="$PWD"/emscriptencache
cp -r /nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/cache "$EM_CACHE"
chmod u+rwX -R "$EM_CACHE"
emcc example.cpp