emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.57k stars 3.27k forks source link

Can't compile libSDL2.bc #9142

Closed arskiy closed 5 years ago

arskiy commented 5 years ago

While running embuilder.py build sdl2 or trying to compile code that uses the SDL2 library using Emscripten, embuilder enters an infinite loop of errors.

cache:INFO: generating port: libSDL2.bc... (this will be cached in "/home/arskiy/.emscripten_cache/asmjs/libSDL2.bc" for subsequent builds)
Traceback (most recent call last):
FileExistsError: [Errno 17] File exists: '/home/arskiy/.emscripten_cache/asmjs/ports-builds/sdl2/include'
Traceback (most recent call last):
  File "/home/arskiy/emsdk/fastcomp/emscripten/emcc.py", line 3492, in <module>
    sys.exit(run(sys.argv))
  File "/home/arskiy/emsdk/fastcomp/emscripten/emcc.py", line 1803, in run
    compile_source_file(i, input_file)
  File "/home/arskiy/emsdk/fastcomp/emscripten/emcc.py", line 1784, in compile_source_file
    args = get_clang_args([input_file]) + ['-c', '-o', output_file]
  File "/home/arskiy/emsdk/fastcomp/emscripten/emcc.py", line 1765, in get_clang_args
    args = system_libs.process_args(args, shared.Settings)
  File "/home/arskiy/emsdk/fastcomp/emscripten/tools/system_libs.py", line 1566, in process_args
    args = port.process_args(Ports, args, settings, shared)
  File "/home/arskiy/emsdk/fastcomp/emscripten/tools/ports/sdl2.py", line 70, in process_args
    get(ports, settings, shared)
  File "/home/arskiy/emsdk/fastcomp/emscripten/tools/ports/sdl2.py", line 59, in get
    return [shared.Cache.get(libname, create, what='port')]
  File "/home/arskiy/emsdk/fastcomp/emscripten/tools/cache.py", line 133, in get
    temp = creator()
  File "/home/arskiy/emsdk/fastcomp/emscripten/tools/ports/sdl2.py", line 33, in create
    shutil.copytree(source_include_path, dest_include_path)
  File "/usr/lib/python3.6/shutil.py", line 321, in copytree
    os.makedirs(dst)
  File "/usr/lib/python3.6/os.py", line 220, in makedirs
    mkdir(name, mode)
cache:INFO: generating port: libSDL2.bc... (this will be cached in "/home/arskiy/.emscripten_cache/asmjs/libSDL2.bc" for subsequent builds)

This was repeated 3100x times, until it finally error'd out. I've tried doing a clean install (including deleting ~/.emscripten*) of Emscripten multiple times using different ways, but none of them worked.

kripken commented 5 years ago

Possibly the ports dir is in a bad state after an initial error. Does emcc --clear-cache not help? Deleting the cache dir directly, as you say you did, should be equivalent, but worth trying anyhow. If it's not that, not sure what it could be. Permissions issue on the dir perhaps? (I can't reproduce locally, and our bots also build it ok.)

kripken commented 5 years ago

Also emcc --clear-ports may be necessary.

arskiy commented 5 years ago

Nope, unfortunately that doesn't works. This is what I did, please correct me if I did something wrong:

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
ls
./emsdk install latest
./emsdk activate latest
source emsdk_env.sh
emcc --clear-cache
emcc --clear-ports
embuilder.py build sdl2
(enters error loop)
kripken commented 5 years ago

Those commands look fine, and running them locally it works for me. Very strange.

Perhaps adding some print debugging before the failing line in sdl2.py can help, like this maybe:

$ git diff
diff --git a/tools/ports/sdl2.py b/tools/ports/sdl2.py
index 05e2f4df5..2a8444a07 100644
--- a/tools/ports/sdl2.py
+++ b/tools/ports/sdl2.py
@@ -29,7 +29,9 @@ def get(ports, settings, shared):
     # copy includes to a location so they can be used as 'SDL2/'
     source_include_path = os.path.join(ports.get_dir(), 'sdl2', SUBDIR + '', 'include')
     dest_include_path = os.path.join(shared.Cache.get_path('ports-builds'), 'sdl2', 'include')
+    print('debugging1', os.path.exists(dest_include_path))
     shared.try_delete(dest_include_path)
+    print('debugging2', os.path.exists(dest_include_path))
     shutil.copytree(source_include_path, dest_include_path)
     shutil.copytree(source_include_path, os.path.join(dest_include_path, 'SDL2'))
     # write out an SDL_config.h file, that configure would normally emit

When I run that I see

('debugging1', False)
('debugging2', False)

and then it continues successfully.

arskiy commented 5 years ago

Ok, after a bit of debugging I tried doing that in a VM. (after I have decided that I was going nowhere) Surprise surprise, it worked.

So, I came to the conclusion that there's something wrong with my Linux install, probably with some hidden Emscripten config that is breaking everything.

I'm not closing this because I'm going to test around a little bit more, searching for some file in my system that is breaking Emscripten

Thanks a lot for the help anyway.