emscripten-core / emscripten-core/emscripten
OpenAL linking is mandatory
- Dominant language
- C++
- Stars
- 27.6k
- Forks
- 3.6k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 105
Description
**Version of emscripten/emsdk:**
```
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.41 (71634e036d20209a5d81c2b2171e145b44de1e12)
clang version 17.0.0 (https://github.com/llvm/llvm-project 88421ea973916e60c34beb26597a5fc33f83dd8f)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/icculus/projects/dragonruby/build-tools/host/Linux-amd64/emsdk/upstream/bin
```
**Failing command line in full:**
```
/home/icculus/projects/dragonruby/build-tools/host/Linux-amd64/emsdk/upstream/emscripten/emcc -O3 -DNDEBUG -flto=thin -Wl,-u,htons -Wl,-u,ntohs -Wl,-u,htonl -pthread -s USE_SDL=0 -s MAIN_MODULE -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=1gb -s ASSERTIONS=0 -s EXPORTED_RUNTIME_METHODS=['addRunDependency','removeRunDependency'] -s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=['$autoResumeAudioContext','$dynCall'] -lidbfs.js CMakeFiles/dragonruby.dir/audio.c.o CMakeFiles/dragonruby.dir/cvar.c.o CMakeFiles/dragonruby.dir/dragonruby_ffi.c.o CMakeFiles/dragonruby.dir/draw.c.o CMakeFiles/dragonruby.dir/fontatlas.c.o CMakeFiles/dragonruby.dir/fn.c.o CMakeFiles/dragonruby.dir/outputs.c.o CMakeFiles/dragonruby.dir/geometry.c.o CMakeFiles/dragonruby.dir/array.c.o CMakeFiles/dragonruby.dir/hash.c.o CMakeFiles/dragonruby.dir/matrix.c.o CMakeFiles/dragonruby.dir/ffi.c.o CMakeFiles/dragonruby.dir/game.c.o CMakeFiles/dragonruby.dir/http_server.c.o CMakeFiles/dragonruby.dir/janitor.c.o CMakeFiles/dragonruby.dir/logging.c.o CMakeFiles/dragonruby.dir/main.c.o CMakeFiles/dragonruby.dir/networking.c.o CMakeFiles/dragonruby.dir/rendercontext.c.o CMakeFiles/dragonruby.dir/renderstream.c.o CMakeFiles/dragonruby.dir/texture.c.o CMakeFiles/dragonruby.dir/tests.c.o CMakeFiles/dragonruby.dir/threadstream.c.o CMakeFiles/dragonruby.dir/threadstream_ruby.c.o CMakeFiles/dragonruby.dir/util.c.o CMakeFiles/dragonruby.dir/xml.c.o CMakeFiles/dragonruby.dir/vr.c.o CMakeFiles/dragonruby.dir/mojoAL/mojoal.c.o CMakeFiles/dragonruby.dir/physfs/extras/physfsrwops.c.o CMakeFiles/dragonruby.dir/yxml/yxml.c.o CMakeFiles/dragonruby.dir/cJSON/cJSON.c.o CMakeFiles/dragonruby.dir/main_ruby.c.o -o dragonruby-wasm.js /home/icculus/projects/dragonruby/SDL/lib/emscripten/libSDL2.a libmruby_core.a libmruby_gems.a libphysfs.a
```
**Full link command and output with `-v` appended:**
```
/home/icculus/projects/dragonruby/build-tools/host/Linux-amd64/emsdk/upstream/bin/wasm-ld -o dragonruby-wasm.wasm --whole-archive -u htons -u ntohs -u htonl CMakeFiles/dragonruby.dir/audio.c.o CMakeFiles/dragonruby.dir/cvar.c.o CMakeFiles/dragonruby.dir/dragonruby_ffi.c.o CMakeFiles/dragonruby.dir/draw.c.o CMakeFiles/dragonruby.dir/fontatlas.c.o CMakeFiles/dragonruby.dir/fn.c.o CMakeFiles/dragonruby.dir/outputs.c.o CMakeFiles/dragonruby.dir/geometry.c.o CMakeFiles/dragonruby.dir/array.c.o CMakeFiles/dragonruby.dir/hash.c.o CMakeFiles/dragonruby.dir/matrix.c.o CMakeFiles/dragonruby.dir/ffi.c.o CMakeFiles/dragonruby.dir/game.c.o CMakeFiles/dragonruby.dir/http_server.c.o CMakeFiles/dragonruby.dir/janitor.c.o CMakeFiles/dragonruby.dir/logging.c.o CMakeFiles/dragonruby.dir/main.c.o CMakeFiles/dragonruby.dir/networking.c.o CMakeFiles/dragonruby.dir/rendercontext.c.o CMakeFiles/dragonruby.dir/renderstream.c.o CMakeFiles/dragonruby.dir/texture.c.o CMakeFiles/dragonruby.dir/tests.c.o CMakeFiles/dragonruby.dir/threadstream.c.o CMakeFiles/dragonruby.dir/threadstream_ruby.c.o CMakeFiles/dragonruby.dir/util.c.o CMakeFiles/dragonruby.dir/xml.c.o CMakeFiles/dragonruby.dir/vr.c.o CMakeFiles/dragonruby.dir/mojoAL/mojoal.c.o CMakeFiles/dragonruby.dir/physfs/extras/physfsrwops.c.o CMakeFiles/dragonruby.dir/yxml/yxml.c.o CMakeFiles/dragonruby.dir/cJSON/cJSON.c.o CMakeFiles/dragonruby.dir/main_ruby.c.o /home/icculus/projects/dragonruby/SDL/lib/emscripten/libSDL2.a libmruby_core.a libmruby_gems.a libphysfs.a -L/home/icculus/projects/dragonruby/build-tools/host/Linux-amd64/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/thinlto-pic /home/icculus/projects/dragonruby/build-tools/host/Linux-amd64/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/thinlto-pic/crtbegin.o -lGL-mt -lal -lhtml5 -lbulkmemory -lstubs -lnoexit -lc-mt -ldlmalloc-mt -lcompiler_rt-mt -lc++-mt-noexcept -lc++abi-mt-noexcept -lsockets-mt --no-whole-archive -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --export-if-defined=setTempRet0 --export-if-defined=setThrew --export-if-defined=malloc --export-if-defined=_emscripten_thread_init --export-if-defined=_emscripten_thread_free_data --export-if-defined=_emscripten_thread_exit --export-if-defined=__errno_location --export-if-defined=htons --export-if-defined=ntohs --export-if-defined=memcpy --export-if-defined=free --export-if-defined=htonl --export-if-defined=_emscripten_timeout --export-if-defined=_emscripten_run_in_main_runtime_thread_js --export-if-defined=__cxa_is_pointer_type --export-if-defined=__dl_seterr --export-if-defined=__cxa_can_catch --export-if-defined=__cxa_increment_exception_refcount --export-if-defined=__cxa_decrement_exception_refcount --export-if-defined=fileno --export-if-defined=emscripten_builtin_memalign --export-if-defined=memcmp --export-if-defined=sleep --export-if-defined=pthread_self --export-if-defined=_emscripten_proxy_dlsync_async --export-if-defined=_emscripten_proxy_dlsync /tmp/tmpokggryf3libemscripten_js_symbols.so --import-memory --shared-memory --strip-debug --export-dynamic --export-if-defined=main --export-if-defined=_emscripten_thread_init --export-if-defined=_emscripten_thread_exit --export-if-defined=_emscripten_thread_crashed --export-if-defined=_emscripten_tls_init --export-if-defined=pthread_self --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_argc_argv --export-if-defined=__wasm_apply_data_relocs --export=malloc --export=setThrew --export=stackSave --export=stackRestore --export=stackAlloc --export=__errno_location --export=emscripten_dispatch_to_thread_ --export=_emscripten_thread_free_data --export=emscripten_main_runtime_thread_id --export=emscripten_main_thread_process_queued_calls --export=_emscripten_run_in_main_runtime_thread_js --export=emscripten_stack_set_limits --export=_emscripten_dlsync_self --export=_emscripten_dlsync_self_async --export=_emscripten_proxy_dlsync --export=_emscripten_proxy_dlsync_async --export=__dl_seterr --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --experimental-pic -pie -z stack-size=65536 --initial-memory=16777216 --no-entry --max-memory=1073741824
```
**Details:**
It looks like (in Emscripten 3.1.41 at least), OpenAL is always specified on the linker command line (`-lal`) when using `-s MAIN_MODULE` (or maybe always, and dead-code elimination removes it or other OpenAL implementations get favored, idk). This particular program uses MojoAL, which provides a full OpenAL 1.1 implementation in a single C file, so naturally we get a symbol conflict here vs Emscripten's included OpenAL:
```
wasm-ld: error: duplicate symbol: alcGetProcAddress
>>> defined in CMakeFiles/dragonruby.dir/mojoAL/mojoal.c.o
>>> defined in /home/icculus/projects/dragonruby/build-tools/host/Linux-amd64/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/thinlto-pic/libal.a(al.o)
```
My assumption is the the `--whole-archive` option that `-s MAIN_MODULE` includes is what triggers this error. Without `MAIN_MODULE` this program links successfully, because it seems to ignore the extra OpenAL library (or `-lal` isn't present in that case, perhaps?).
All of this to say: it would be _extremely_ nice if there was an `-s USE_OPENAL=0` option to match the existing `USE_SDL` and friends, to not attempt to link an OpenAL implementation by default.
Contributor guide
Assessment
This issue has not been assessed yet.