Emscripten linking errors

I’m compiling the FMOD GDextension plugin for Godot for web. While this plugin compiles fine for all other platforms, it fails when building for web.

wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `JSFMOD::gSystemMap`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `JSFMOD::gSystemMap`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `JSFMOD::gSystemMap`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.160`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.160`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.161`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.161`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.161`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.161`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `JSFMOD::gSoundMap`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `JSFMOD::gSoundMap`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `JSFMOD::gSoundMap`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.160`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.160`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.161`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.161`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `JSFMOD::gChannelMap`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `JSFMOD::gChannelMap`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `JSFMOD::gChannelMap`; recompile with -fPIC
wasm-ld: error: ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a(fmod_os_js_api.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.160`; recompile with -fPIC
wasm-ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
em++: error: 'D:/Users/pmdevita/Downloads/fmod-gdextension/emsdk/upstream/bin\wasm-ld.exe -o demo\addons\fmod\libs\web\libGodotFmod.web.template_debug.wasm32.wasm --whole-archive -s ../fmod/api/studio/lib/upstream/w32/fmodstudioL_bindings.a src\fmod_cache.o src\fmod_server.o src\fmod_string_names.o src\register_types.o src\callback\event_callbacks.o src\callback\file_callbacks.o src\core\fmod_file.o src\core\fmod_sound.o src\data\performance_data.o src\tools\fmod_editor_export_plugin.o src\tools\fmod_editor_plugin.o src\nodes\fmod_bank_loader.o src\nodes\fmod_event_emitter_2d.o src\nodes\fmod_event_emitter_3d.o src\nodes\fmod_listener_2d.o src\nodes\fmod_listener_3d.o src\resources\fmod_dsp_settings.o src\resources\fmod_settings.o src\resources\fmod_software_format_settings.o src\resources\fmod_sound_3d_settings.o src\studio\fmod_bank.o src\studio\fmod_bus.o src\studio\fmod_event.o src\studio\fmod_event_description.o src\studio\fmod_parameter_description.o src\studio\fmod_vca.o -LD:\Users\pmdevita\Downloads\fmod-gdextension\fmod\api\studio\lib\upstream\w32 -LD:\Users\pmdevita\Downloads\fmod-gdextension\emsdk\upstream\emscripten\cache\sysroot\lib\wasm32-emscripten\pic godot-cpp\bin\libgodot-cpp.web.template_debug.wasm32.nothreads.a --no-whole-archive --keep-section=target_features -mllvm -combiner-global-alias-analysis=false -mllvm -wasm-enable-sjlj -mllvm -disable-lsr -mllvm -exception-model=wasm --import-memory --strip-debug --export-dynamic --export=__wasm_call_ctors --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=__wasm_apply_data_relocs --export-if-defined=fflush --experimental-pic --unresolved-symbols=import-dynamic --no-shlib-sigcheck -shared --stack-first' failed (returned 1)
scons: *** [demo\addons\fmod\libs\web\libGodotFmod.web.template_debug.wasm32.wasm] Error 1
scons: building terminated because of errors.

I’ve also attempted to build against the bitcode distribution. This does compile, but when I boot Godot in the browser with it, I get this error in the console. Not sure where I read it as well, but it seemed like bitcode was going to get phased out at some point, so I’d prefer to not use it if that’s the case.

Uncaught (in promise) LinkError: imported function 'env.__atomic_store_8' signature mismatch 

I’m using FMOD Engine 2.02.26, compiling with Emscripten 3.1.74 against Godot 4.3.

There have been some previous threads touching the same topic. This one Issues with compiling for HTML5 using emscripten is fairly old now though, and as far as I understand, dynamic linking is not experimental in Emscripten anymore.

There is also this thread Emscripten link errors - #4 by rwkay which looks to be doing the exact same thing but for GameMaker. I’m not sure I understand this problem with the licensing, it’s not like I have to get a special build of Unity or Unreal statically built with FMOD so I can use it on the web (the distribution of that would be definitely be against the EULA).

If possible, I would like to explore two solutions. The first would be the original request from the GameMaker thread - would it be possible to get a w32 build of FMOD compiled with -fPIC?

If that is not permissible, would it instead be possible to get a build of FMOD compiled as a wasm dynamic library? This could then be dynamically linked against like we do for the other platforms, and avoid any EULA-related concerns of static compilation. I’ll note that while yes, there are wasm builds of FMOD included in the SDK, they are compiled for use directly with Javascript and trying to build against them results in this error:

wasm-ld: error: ../fmod/api/studio/lib/upstream/wasm/fmodstudioL.wasm: not a relocatable wasm file

I’ll add some info if anyone wants to look at my work. My branch is here GitHub - pmdevita/fmod-gdextension at web-support and you can view the diff with the master branch here Comparing utopia-rise:master...pmdevita:web-support · utopia-rise/fmod-gdextension · GitHub I’m compiling without thread support since FMOD doesn’t support it. Scons command looks something like this

scons target=template_debug platform=web fmod_lib_dir=path/to/fmod/html threads=no verbose=yes

We found other issues with this as fmod uses Emscripten features to embed JavaScript calls and callbacks…

Unfortunately at the time we were testing it Emscripten did not support this within a dynamic library, this meant we had to abandon the approach that we had. We have put the FMOD support for WASM on hold just now - but I do think there is scope to add it in the future but it would involve glueing it in at a Javascript level rather than using dynamic linking at the Emscripten level.

If you can get it working with dynamic linking and Emscripten then let us know as it would be by far the easiest method to support it.

Russell

Thank you for the suggestions, I have floated both of these options to the Dev team for consideration.

The problem as I understand it (I’m a dev, not legal) would be this part of what you are trying to do:

-o demo\addons\fmod\libs\web\libGodotFmod.web.template_debug.wasm32.wasm

Which is to say you aren’t generating an end-user application, you are generating a library for use in an end-user application, which I think would violate our EULA.
In any case, I will chat with the Dev team and see if either of these options are viable.