emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.61k stars 3.28k forks source link

Unable to compile SDL2 mixer example project #18077

Open tmyqlfpir opened 1 year ago

tmyqlfpir commented 1 year ago

Hello.

I am attempting to compile a open source game that uses SDL2, but whenever it attempts to compile the required SDL2_mixer library it always fails at timidity. I've isolated the problem by using an barebones SDL2 mixer example project, which is attached to this issue (originally from here).

sdl2-mixer-sample-src.zip

The example project is compiled with the following command in the base directory.

emcc ./src/main.c -s USE_OGG=1 -s USE_VORBIS=1 -s USE_PTHREADS -s USE_SDL=2 -s USE_SDL_MIXER=2 -s SDL2_MIXER_FORMATS='["wav", "ogg"]' -s INITIAL_MEMORY=64MB -s ASYNCIFY=1 --preload-file ./assets -o ./test.html

I am using lubuntu within VirtualBox, and have ran --clear-cache before attempting to compile to html.

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.23 (5ae63ce7dd955df449cb419bfe5afc51d1bd57f2)
clang version 16.0.0 (https://github.com/llvm/llvm-project 8b587113b746f31b63fd6473083df78cef30a72e)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/user/Downloads/emsdk/upstream/bin
Failing command line in full: ``` emcc ./src/main.c -s USE_OGG=1 -s USE_VORBIS=1 -s USE_PTHREADS -s USE_SDL=2 -s USE_SDL_MIXER=2 -s SDL2_MIXER_FORMATS='["wav", "ogg"]' -s INITIAL_MEMORY=64MB -s ASYNCIFY=1 --preload-file ./assets -o ./test.html shared:INFO: (Emscripten: Running sanity checks) cache:INFO: generating system headers: sysroot_install.stamp... (this will be cached in "/home/user/Downloads/emsdk/upstream/emscripten/cache/sysroot_install.stamp" for subsequent builds) cache:INFO: - ok ports:INFO: retrieving port: sdl2 from https://github.com/libsdl-org/SDL/archive/release-2.24.0.zip ports:INFO: unpacking port: sdl2 cache:INFO: generating port: sysroot/lib/wasm32-emscripten/libSDL2-mt.a... (this will be cached in "/home/user/Downloads/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libSDL2-mt.a" for subsequent builds) system_libs:INFO: compiled 114 inputs cache:INFO: - ok ports:INFO: retrieving port: ogg from https://github.com/emscripten-ports/ogg/archive/version_1.zip ports:INFO: unpacking port: ogg cache:INFO: generating system library: sysroot/lib/wasm32-emscripten/libogg.a... (this will be cached in "/home/user/Downloads/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libogg.a" for subsequent builds) root:INFO: building port: ogg system_libs:INFO: compiled 2 inputs cache:INFO: - ok ports:INFO: retrieving port: vorbis from https://github.com/emscripten-ports/vorbis/archive/version_1.zip ports:INFO: unpacking port: vorbis cache:INFO: generating system library: sysroot/lib/wasm32-emscripten/libvorbis.a... (this will be cached in "/home/user/Downloads/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libvorbis.a" for subsequent builds) root:INFO: building port: vorbis system_libs:INFO: compiled 22 inputs cache:INFO: - ok ports:INFO: retrieving port: sdl2_mixer from https://github.com/libsdl-org/SDL_mixer/archive/release-2.0.4.zip ports:INFO: unpacking port: sdl2_mixer cache:INFO: generating port: sysroot/lib/wasm32-emscripten/libSDL2_mixer_ogg-wav.a... (this will be cached in "/home/user/Downloads/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libSDL2_mixer_ogg-wav.a" for subsequent builds) root:INFO: building port: sdl2_mixer Traceback (most recent call last): File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 4145, in sys.exit(main(sys.argv)) File "/usr/lib/python3.8/contextlib.py", line 75, in inner return func(*args, **kwds) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 4138, in main ret = run(args) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 1160, in run linker_inputs = phase_compile_inputs(options, state, newargs, input_files) File "/usr/lib/python3.8/contextlib.py", line 75, in inner return func(*args, **kwds) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 2832, in phase_compile_inputs compile_source_file(i, input_file) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 2812, in compile_source_file cmd = get_clang_command(input_file) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 2746, in get_clang_command return get_compiler(src_file) + get_cflags(state.orig_args, use_cxx(src_file)) + compile_args + [src_file] File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 903, in get_cflags ports.add_cflags(cflags, settings) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/ports/__init__.py", line 386, in add_cflags port.get(Ports, settings, shared) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/ports/sdl2.py", line 76, in get return [shared.Cache.get_lib(get_lib_name(settings), create, what='port')] File "/home/user/Downloads/emsdk/upstream/emscripten/tools/cache.py", line 126, in get_lib return self.get(name, *args, **kwargs) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/cache.py", line 142, in get with self.lock(shortname): File "/usr/lib/python3.8/contextlib.py", line 113, in __enter__ return next(self.gen) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/cache.py", line 62, in lock self.acquire_cache_lock(reason) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/cache.py", line 39, in acquire_cache_lock assert 'EM_CACHE_IS_LOCKED' not in os.environ, f'attempt to lock the cache while a parent process is holding the lock ({reason})' AssertionError: attempt to lock the cache while a parent process is holding the lock (sysroot/lib/wasm32-emscripten/libSDL2.a) Traceback (most recent call last): File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 4145, in sys.exit(main(sys.argv)) File "/usr/lib/python3.8/contextlib.py", line 75, in inner return func(*args, **kwds) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 4138, in main ret = run(args) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 1160, in run linker_inputs = phase_compile_inputs(options, state, newargs, input_files) File "/usr/lib/python3.8/contextlib.py", line 75, in inner return func(*args, **kwds) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 2832, in phase_compile_inputs compile_source_file(i, input_file) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 2812, in compile_source_file cmd = get_clang_command(input_file) File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 2746, in get_clang_command return get_compiler(src_file) + get_cflags(state.orig_args, use_cxx(src_file)) + compile_args + [src_file] File "/home/user/Downloads/emsdk/upstream/emscripten/emcc.py", line 903, in get_cflags ports.add_cflags(cflags, settings) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/ports/__init__.py", line 386, in add_cflags port.get(Ports, settings, shared) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/ports/sdl2_mixer.py", line 94, in get return [shared.Cache.get_lib(libname, create, what='port')] File "/home/user/Downloads/emsdk/upstream/emscripten/tools/cache.py", line 126, in get_lib return self.get(name, *args, **kwargs) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/cache.py", line 153, in get creator(str(cachename)) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/ports/sdl2_mixer.py", line 76, in create ports.build_port( File "/home/user/Downloads/emsdk/upstream/emscripten/tools/ports/__init__.py", line 148, in build_port system_libs.run_build_commands(commands) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/system_libs.py", line 85, in run_build_commands shared.run_multiple_processes(commands, env=clean_env()) File "/home/user/Downloads/emsdk/upstream/emscripten/tools/shared.py", line 215, in run_multiple_processes raise Exception('Subprocess %d/%d failed (%s)! (cmdline: %s)' % (idx + 1, len(commands), returncode_to_str(finished_process.returncode), shlex_join(commands[idx]))) Exception: Subprocess 1/28 failed (returned 1)! (cmdline: /home/user/Downloads/emsdk/upstream/emscripten/emcc -c /home/user/Downloads/emsdk/upstream/emscripten/cache/ports/sdl2_mixer/SDL_mixer-release-2.0.4/timidity/readmidi.c -o /home/user/Downloads/emsdk/upstream/emscripten/cache/ports-builds/sdl2_mixer/timidity/readmidi.c.o -g -sSTRICT -Werror -O2 -I/home/user/Downloads/emsdk/upstream/emscripten/cache/ports/sdl2_mixer/SDL_mixer-release-2.0.4 -sUSE_SDL=2 -O2 -DMUSIC_WAV -sUSE_VORBIS=1 -DMUSIC_OGG) ```
Full link command and output with `-v` appended.log * Too big to include into issue, attached here: [compile.log](https://github.com/emscripten-core/emscripten/files/9827286/compile.log)
sbc100 commented 1 year ago

The problem seems to be related to fact the sdl2 library has a pthread-variant but that sdl2_mixer does not.

As a workaround, until with come up with better fix, you should be able to build needed dependency by first building without -sUSE_PTHREADS

tmyqlfpir commented 1 year ago

Thanks! That works for the sdl2 mixer example, but for the open source game it'll eventually hit the linker stage, then print the following error: --shared-memory is disallowed by SDL_atomic.c.o because it was not compiled with 'atomics' or 'bulk-memory' features.

I am not sure how to progress as the game requires atomics and pthreads, and I've been able to compile it thus far.

sbc100 commented 1 year ago

What I mean is if you build libsdl first without threads then you shouldn't run into this issue. Its a workaround but it should work. The final build should not change. You can continue to use -sUSE_PTHREADS there.

For example, you could add ./embuilder build sdl2 to your build script, before you compile anything.

connorjclark commented 1 year ago

Note my analysis here re: the cache being locked.