Help to compile static version of libopenmpt for webassembly

Started by Alfnsionbgio, June 02, 2023, 10:30:37

Previous topic - Next topic

Alfnsionbgio

Hello, I want to add this library into a game I'm making. But I need static library for this, while precompiled version is dynamic library only. Which means I need to compile this library myself.

I downloaded make from here https://gnuwin32.sourceforge.net/packages/make.htm . Before that I used chocolatey to install make, but that one gave bugged console output at the very first line despite overwise working, so I uninstalled that.

I sometimes use just "make", and sometimes I use "emmake make", not sure which way is more correct.

I want to report that setting VERBOSE=1 results in this error during compilation:
process_begin: CreateProcess(NULL, true [CXX] common/ComponentManager.cpp, ...) failed.

Also "make clean" doesn't seem to work for me, apparently that needs "sed" and/or "grep". So I just delete and reunpack the entire folder instead.

I am very new to makefiles, and I don't know how to debug them.

Here are steps I tried to do to compile:
*) In file "Makefile", right below "all:", add this:
CONFIG=emscriptenstatic
*) In folder "build/make", copy file "config-emscripten.mk" and call it "config-emscriptenstatic.mk"
*) In file "build/make/config-emscriptenstatic.mk", replace this:
CXXFLAGS += -fPIC
CFLAGS   += -fPIC
with:
CXXFLAGS +=
CFLAGS   +=
and replace this:
SHARED_LIB=1
STATIC_LIB=0
EXAMPLES=1
with:
SHARED_LIB=0
STATIC_LIB=1
EXAMPLES=0
*) Run "emmake make". Or maybe just "make".

This results in libopenmpt.a which almost works for me, except there is some issue with either threading, or with thread local storage. Short story is, I think this library uses threading, probably due to me compiling it wrong. Longer story is, I'm developing game in beeflang, and I get exception in runtime when I link this library in, when accessing a tls variable inside beeflang runtime library. I can provide source code of my beeflang game if needed.

manx

Quote from: Alfnsionbgio on June 02, 2023, 10:30:37I downloaded make from here https://gnuwin32.sourceforge.net/packages/make.htm . Before that I used chocolatey to install make, but that one gave bugged console output at the very first line despite overwise working, so I uninstalled that.

I sometimes use just "make", and sometimes I use "emmake make", not sure which way is more correct.

I want to report that setting VERBOSE=1 results in this error during compilation:
process_begin: CreateProcess(NULL, true [CXX] common/ComponentManager.cpp, ...) failed.

Also "make clean" doesn't seem to work for me, apparently that needs "sed" and/or "grep". So I just delete and reunpack the entire folder instead.

Our Makefile is only built to work in Unix-like environments. So, if you want to build in Windows, you would absolutely need to use and run make from MSYS2 or Cygwin. I do not recommend that in this situation though, see below.

Quote from: Alfnsionbgio on June 02, 2023, 10:30:37I am very new to makefiles, and I don't know how to debug them.

Here are steps I tried to do to compile:
*) In file "Makefile", right below "all:", add this:
CONFIG=emscriptenstatic
*) In folder "build/make", copy file "config-emscripten.mk" and call it "config-emscriptenstatic.mk"
*) In file "build/make/config-emscriptenstatic.mk", replace this:
CXXFLAGS += -fPIC
CFLAGS  += -fPIC
with:
CXXFLAGS +=
CFLAGS  +=
and replace this:
SHARED_LIB=1
STATIC_LIB=0
EXAMPLES=1
with:
SHARED_LIB=0
STATIC_LIB=1
EXAMPLES=0
*) Run "emmake make". Or maybe just "make".

Emscripten is probably just a too-different-target to work with our Makefile as-is, even with your minimal changes. There are way too many incompatible build options for emscripten.

In any case, building libopenmpt with your own build system should be rather easy. In your specific case, you probably do not need MP3/OggVOrbis/zlib support (used for MO3, OXM, J2B formats), so you may build libopenmpt without these dependencies, which simplifies things somewhat more.

The commands for building a simple static libopenmpt library with emscripten should be as follows:
em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc common/*.cpp sounddsp/*.cpp soundlib/*.cpp soundlib/plugins/*.cpp soundlib/plugins/dmo/*.cpp libopenmpt/*.cpp
emar rcs libopenmpt.a *.o

Note that independent of how you build libopenmpt as a static or shared library or as individual object files, you absolutely need to use emscripten option
-s DISABLE_EXCEPTION_CATCHING=0 for linking libopenmpt and your program. Otherwise, libopenmpt cannot work properly. I do not know how to do that from/for beeflang.

Quote from: Alfnsionbgio on June 02, 2023, 10:30:37This results in libopenmpt.a which almost works for me, except there is some issue with either threading, or with thread local storage. Short story is, I think this library uses threading, probably due to me compiling it wrong. Longer story is, I'm developing game in beeflang, and I get exception in runtime when I link this library in, when accessing a tls variable inside beeflang runtime library. I can provide source code of my beeflang game if needed.

libopenmpt does not use threads or thread-local-storage itself internally. The libc and the libc++ that emscripten links and which libopenmpt depend on might use these though. It am notfamiliar with beeflang at all (it's the first time I even heard about it), so I cannot coment on any specific compatiblity problem here. What are the errors precisely?

Alfnsionbgio

Quote from: manx on June 03, 2023, 07:00:59The commands for building a simple static libopenmpt library with emscripten should be as follows:
em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc common/*.cpp sounddsp/*.cpp soundlib/*.cpp soundlib/plugins/*.cpp soundlib/plugins/dmo/*.cpp libopenmpt/*.cpp
emar rcs libopenmpt.a *.o

Hm, I get this error then I try those. Apparently windows command line doesn't replace wildchar with anything and passes them as is.

em++: error: common/*.cpp: No such file or directory ("common/*.cpp" was expected to be an input file, based on the commandline arguments provided)

I ended up doing commands like "for %A in (soundlib\plugins\dmo\*.cpp) do @echo %~nA" in command line, copypasting them into notepad++ and doing replace with it. Here is the final result.

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc common/ComponentManager.cpp common/Logging.cpp common/mptFileIO.cpp common/mptFileTemporary.cpp common/mptFileType.cpp common/mptPathString.cpp common/mptRandom.cpp common/mptStringBuffer.cpp common/mptTime.cpp common/Profiler.cpp common/serialization_utils.cpp common/version.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc sounddsp/AGC.cpp sounddsp/DSP.cpp sounddsp/EQ.cpp sounddsp/Reverb.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc soundlib/AudioCriticalSection.cpp soundlib/ContainerMMCMP.cpp soundlib/ContainerPP20.cpp soundlib/ContainerUMX.cpp soundlib/ContainerXPK.cpp soundlib/Dlsbank.cpp soundlib/Fastmix.cpp soundlib/InstrumentExtensions.cpp soundlib/ITCompression.cpp soundlib/ITTools.cpp soundlib/Load_667.cpp soundlib/Load_669.cpp soundlib/Load_amf.cpp soundlib/Load_ams.cpp soundlib/Load_c67.cpp soundlib/Load_dbm.cpp soundlib/Load_digi.cpp soundlib/Load_dmf.cpp soundlib/Load_dsm.cpp soundlib/Load_dsym.cpp soundlib/Load_dtm.cpp soundlib/Load_far.cpp soundlib/Load_fmt.cpp soundlib/Load_gdm.cpp soundlib/Load_gt2.cpp soundlib/Load_imf.cpp soundlib/Load_it.cpp soundlib/Load_itp.cpp soundlib/load_j2b.cpp soundlib/Load_mdl.cpp soundlib/Load_med.cpp soundlib/Load_mid.cpp soundlib/Load_mo3.cpp soundlib/Load_mod.cpp soundlib/Load_mt2.cpp soundlib/Load_mtm.cpp soundlib/Load_mus_km.cpp soundlib/Load_okt.cpp soundlib/Load_plm.cpp soundlib/Load_psm.cpp soundlib/Load_ptm.cpp soundlib/Load_s3m.cpp soundlib/Load_sfx.cpp soundlib/Load_stm.cpp soundlib/Load_stp.cpp soundlib/Load_symmod.cpp soundlib/Load_uax.cpp soundlib/Load_ult.cpp soundlib/Load_wav.cpp soundlib/Load_xm.cpp soundlib/Load_xmf.cpp soundlib/Message.cpp soundlib/MIDIEvents.cpp soundlib/MIDIMacros.cpp soundlib/MixerLoops.cpp soundlib/MixerSettings.cpp soundlib/MixFuncTable.cpp soundlib/ModChannel.cpp soundlib/modcommand.cpp soundlib/ModInstrument.cpp soundlib/ModSample.cpp soundlib/ModSequence.cpp soundlib/modsmp_ctrl.cpp soundlib/mod_specifications.cpp soundlib/MPEGFrame.cpp soundlib/OggStream.cpp soundlib/OPL.cpp soundlib/pattern.cpp soundlib/patternContainer.cpp soundlib/Paula.cpp soundlib/RowVisitor.cpp soundlib/S3MTools.cpp soundlib/SampleFormatBRR.cpp soundlib/SampleFormatFLAC.cpp soundlib/SampleFormatMediaFoundation.cpp soundlib/SampleFormatMP3.cpp soundlib/SampleFormatOpus.cpp soundlib/SampleFormats.cpp soundlib/SampleFormatSFZ.cpp soundlib/SampleFormatVorbis.cpp soundlib/SampleIO.cpp soundlib/Sndfile.cpp soundlib/Sndmix.cpp soundlib/Snd_flt.cpp soundlib/Snd_fx.cpp soundlib/SoundFilePlayConfig.cpp soundlib/Tables.cpp soundlib/Tagging.cpp soundlib/TinyFFT.cpp soundlib/tuning.cpp soundlib/tuningCollection.cpp soundlib/UMXTools.cpp soundlib/UpgradeModule.cpp soundlib/WAVTools.cpp soundlib/WindowedFIR.cpp soundlib/XMTools.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc soundlib/plugins/DigiBoosterEcho.cpp soundlib/plugins/LFOPlugin.cpp soundlib/plugins/PluginManager.cpp soundlib/plugins/PlugInterface.cpp soundlib/plugins/SymMODEcho.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc soundlib/plugins/dmo/Chorus.cpp soundlib/plugins/dmo/Compressor.cpp soundlib/plugins/dmo/Distortion.cpp soundlib/plugins/dmo/DMOPlugin.cpp soundlib/plugins/dmo/DMOUtils.cpp soundlib/plugins/dmo/Echo.cpp soundlib/plugins/dmo/Flanger.cpp soundlib/plugins/dmo/Gargle.cpp soundlib/plugins/dmo/I3DL2Reverb.cpp soundlib/plugins/dmo/ParamEq.cpp soundlib/plugins/dmo/WavesReverb.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc libopenmpt/libopenmpt_c.cpp libopenmpt/libopenmpt_cxx.cpp libopenmpt/libopenmpt_ext_impl.cpp libopenmpt/libopenmpt_impl.cpp

emar rcs libopenmpt.a AGC.o AudioCriticalSection.o Chorus.o ComponentManager.o Compressor.o ContainerMMCMP.o ContainerPP20.o ContainerUMX.o ContainerXPK.o DigiBoosterEcho.o Distortion.o Dlsbank.o DMOPlugin.o DMOUtils.o DSP.o Echo.o EQ.o Fastmix.o Flanger.o Gargle.o I3DL2Reverb.o InstrumentExtensions.o ITCompression.o ITTools.o LFOPlugin.o libopenmpt_c.o libopenmpt_cxx.o libopenmpt_ext_impl.o libopenmpt_impl.o Load_667.o Load_669.o Load_amf.o Load_ams.o Load_c67.o Load_dbm.o Load_digi.o Load_dmf.o Load_dsm.o Load_dsym.o Load_dtm.o Load_far.o Load_fmt.o Load_gdm.o Load_gt2.o Load_imf.o Load_it.o Load_itp.o load_j2b.o Load_mdl.o Load_med.o Load_mid.o Load_mo3.o Load_mod.o Load_mt2.o Load_mtm.o Load_mus_km.o Load_okt.o Load_plm.o Load_psm.o Load_ptm.o Load_s3m.o Load_sfx.o Load_stm.o Load_stp.o Load_symmod.o Load_uax.o Load_ult.o Load_wav.o Load_xm.o Load_xmf.o Logging.o Message.o MIDIEvents.o MIDIMacros.o MixerLoops.o MixerSettings.o MixFuncTable.o ModChannel.o modcommand.o ModInstrument.o ModSample.o ModSequence.o modsmp_ctrl.o mod_specifications.o MPEGFrame.o mptFileIO.o mptFileTemporary.o mptFileType.o mptPathString.o mptRandom.o mptStringBuffer.o mptTime.o OggStream.o OPL.o ParamEq.o pattern.o patternContainer.o Paula.o PluginManager.o PlugInterface.o Profiler.o Reverb.o RowVisitor.o S3MTools.o SampleFormatBRR.o SampleFormatFLAC.o SampleFormatMediaFoundation.o SampleFormatMP3.o SampleFormatOpus.o SampleFormats.o SampleFormatSFZ.o SampleFormatVorbis.o SampleIO.o serialization_utils.o Sndfile.o Sndmix.o Snd_flt.o Snd_fx.o SoundFilePlayConfig.o SymMODEcho.o Tables.o Tagging.o TinyFFT.o tuning.o tuningCollection.o UMXTools.o UpgradeModule.o version.o WavesReverb.o WAVTools.o WindowedFIR.o XMTools.o

Quote from: manx on June 03, 2023, 07:00:59What are the errors precisely?

I get this callstack when I run my webassembly game
Uncaught RuntimeError: index out of bounds
BfpThread_GetCurrentId http://localhost:8000/CaveGame.wasm:593832
BfInternalThread::ManualThreadInit(bf::System::Threading::Thread*) http://localhost:8000/CaveGame.wasm:578810
bf::System::Threading::Thread::ManualThreadInit() http://localhost:8000/CaveGame.wasm:576637
bf::System::Threading::Thread::Init() http://localhost:8000/CaveGame.wasm:455439
bf::System::Runtime::__BfStaticCtor() http://localhost:8000/CaveGame.wasm:359053
main http://localhost:8000/CaveGame.wasm:494597
createExportWrapper http://localhost:8000/CaveGame.js:912
callMain http://localhost:8000/CaveGame.js:11627
doRun http://localhost:8000/CaveGame.js:11677
run http://localhost:8000/CaveGame.js:11688

Here is the source code for that https://github.com/beefytech/Beef/blob/master/BeefySysLib/platform/posix/PosixCommon.cpp#L1396

To quote the author of that language, "The only "interesting" thing is that gCurrentThread is a TLS value. Still - this gets called on all programs. I don't see why it could break unless somehow this library is breaking TLS in general... too many TLS values for wasm/emscripten or something?"

Recompilation with above commands didn't help, still have the same issue. Well, but at least now I know that it is compiled more or less correctly. By the way, interesting how libopenmpt.a compiled now is 9600 KB, while libopenmpt.a I compiled with makefile was 13600 KB.

manx

Quote from: Alfnsionbgio on June 03, 2023, 09:23:12
Quote from: manx on June 03, 2023, 07:00:59The commands for building a simple static libopenmpt library with emscripten should be as follows:
em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc common/*.cpp sounddsp/*.cpp soundlib/*.cpp soundlib/plugins/*.cpp soundlib/plugins/dmo/*.cpp libopenmpt/*.cpp
emar rcs libopenmpt.a *.o

Hm, I get this error then I try those. Apparently windows command line doesn't replace wildchar with anything and passes them as is.

em++: error: common/*.cpp: No such file or directory ("common/*.cpp" was expected to be an input file, based on the commandline arguments provided)

I ended up doing commands like "for %A in (soundlib\plugins\dmo\*.cpp) do @echo %~nA" in command line, copypasting them into notepad++ and doing replace with it. Here is the final result.

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc common/ComponentManager.cpp common/Logging.cpp common/mptFileIO.cpp common/mptFileTemporary.cpp common/mptFileType.cpp common/mptPathString.cpp common/mptRandom.cpp common/mptStringBuffer.cpp common/mptTime.cpp common/Profiler.cpp common/serialization_utils.cpp common/version.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc sounddsp/AGC.cpp sounddsp/DSP.cpp sounddsp/EQ.cpp sounddsp/Reverb.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc soundlib/AudioCriticalSection.cpp soundlib/ContainerMMCMP.cpp soundlib/ContainerPP20.cpp soundlib/ContainerUMX.cpp soundlib/ContainerXPK.cpp soundlib/Dlsbank.cpp soundlib/Fastmix.cpp soundlib/InstrumentExtensions.cpp soundlib/ITCompression.cpp soundlib/ITTools.cpp soundlib/Load_667.cpp soundlib/Load_669.cpp soundlib/Load_amf.cpp soundlib/Load_ams.cpp soundlib/Load_c67.cpp soundlib/Load_dbm.cpp soundlib/Load_digi.cpp soundlib/Load_dmf.cpp soundlib/Load_dsm.cpp soundlib/Load_dsym.cpp soundlib/Load_dtm.cpp soundlib/Load_far.cpp soundlib/Load_fmt.cpp soundlib/Load_gdm.cpp soundlib/Load_gt2.cpp soundlib/Load_imf.cpp soundlib/Load_it.cpp soundlib/Load_itp.cpp soundlib/load_j2b.cpp soundlib/Load_mdl.cpp soundlib/Load_med.cpp soundlib/Load_mid.cpp soundlib/Load_mo3.cpp soundlib/Load_mod.cpp soundlib/Load_mt2.cpp soundlib/Load_mtm.cpp soundlib/Load_mus_km.cpp soundlib/Load_okt.cpp soundlib/Load_plm.cpp soundlib/Load_psm.cpp soundlib/Load_ptm.cpp soundlib/Load_s3m.cpp soundlib/Load_sfx.cpp soundlib/Load_stm.cpp soundlib/Load_stp.cpp soundlib/Load_symmod.cpp soundlib/Load_uax.cpp soundlib/Load_ult.cpp soundlib/Load_wav.cpp soundlib/Load_xm.cpp soundlib/Load_xmf.cpp soundlib/Message.cpp soundlib/MIDIEvents.cpp soundlib/MIDIMacros.cpp soundlib/MixerLoops.cpp soundlib/MixerSettings.cpp soundlib/MixFuncTable.cpp soundlib/ModChannel.cpp soundlib/modcommand.cpp soundlib/ModInstrument.cpp soundlib/ModSample.cpp soundlib/ModSequence.cpp soundlib/modsmp_ctrl.cpp soundlib/mod_specifications.cpp soundlib/MPEGFrame.cpp soundlib/OggStream.cpp soundlib/OPL.cpp soundlib/pattern.cpp soundlib/patternContainer.cpp soundlib/Paula.cpp soundlib/RowVisitor.cpp soundlib/S3MTools.cpp soundlib/SampleFormatBRR.cpp soundlib/SampleFormatFLAC.cpp soundlib/SampleFormatMediaFoundation.cpp soundlib/SampleFormatMP3.cpp soundlib/SampleFormatOpus.cpp soundlib/SampleFormats.cpp soundlib/SampleFormatSFZ.cpp soundlib/SampleFormatVorbis.cpp soundlib/SampleIO.cpp soundlib/Sndfile.cpp soundlib/Sndmix.cpp soundlib/Snd_flt.cpp soundlib/Snd_fx.cpp soundlib/SoundFilePlayConfig.cpp soundlib/Tables.cpp soundlib/Tagging.cpp soundlib/TinyFFT.cpp soundlib/tuning.cpp soundlib/tuningCollection.cpp soundlib/UMXTools.cpp soundlib/UpgradeModule.cpp soundlib/WAVTools.cpp soundlib/WindowedFIR.cpp soundlib/XMTools.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc soundlib/plugins/DigiBoosterEcho.cpp soundlib/plugins/LFOPlugin.cpp soundlib/plugins/PluginManager.cpp soundlib/plugins/PlugInterface.cpp soundlib/plugins/SymMODEcho.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc soundlib/plugins/dmo/Chorus.cpp soundlib/plugins/dmo/Compressor.cpp soundlib/plugins/dmo/Distortion.cpp soundlib/plugins/dmo/DMOPlugin.cpp soundlib/plugins/dmo/DMOUtils.cpp soundlib/plugins/dmo/Echo.cpp soundlib/plugins/dmo/Flanger.cpp soundlib/plugins/dmo/Gargle.cpp soundlib/plugins/dmo/I3DL2Reverb.cpp soundlib/plugins/dmo/ParamEq.cpp soundlib/plugins/dmo/WavesReverb.cpp

em++ -c -s DISABLE_EXCEPTION_CATCHING=0 -std=c++20 -Wall -Wextra -Wpedantic -Oz -DLIBOPENMPT_BUILD -I. -Icommon -Isrc libopenmpt/libopenmpt_c.cpp libopenmpt/libopenmpt_cxx.cpp libopenmpt/libopenmpt_ext_impl.cpp libopenmpt/libopenmpt_impl.cpp

emar rcs libopenmpt.a AGC.o AudioCriticalSection.o Chorus.o ComponentManager.o Compressor.o ContainerMMCMP.o ContainerPP20.o ContainerUMX.o ContainerXPK.o DigiBoosterEcho.o Distortion.o Dlsbank.o DMOPlugin.o DMOUtils.o DSP.o Echo.o EQ.o Fastmix.o Flanger.o Gargle.o I3DL2Reverb.o InstrumentExtensions.o ITCompression.o ITTools.o LFOPlugin.o libopenmpt_c.o libopenmpt_cxx.o libopenmpt_ext_impl.o libopenmpt_impl.o Load_667.o Load_669.o Load_amf.o Load_ams.o Load_c67.o Load_dbm.o Load_digi.o Load_dmf.o Load_dsm.o Load_dsym.o Load_dtm.o Load_far.o Load_fmt.o Load_gdm.o Load_gt2.o Load_imf.o Load_it.o Load_itp.o load_j2b.o Load_mdl.o Load_med.o Load_mid.o Load_mo3.o Load_mod.o Load_mt2.o Load_mtm.o Load_mus_km.o Load_okt.o Load_plm.o Load_psm.o Load_ptm.o Load_s3m.o Load_sfx.o Load_stm.o Load_stp.o Load_symmod.o Load_uax.o Load_ult.o Load_wav.o Load_xm.o Load_xmf.o Logging.o Message.o MIDIEvents.o MIDIMacros.o MixerLoops.o MixerSettings.o MixFuncTable.o ModChannel.o modcommand.o ModInstrument.o ModSample.o ModSequence.o modsmp_ctrl.o mod_specifications.o MPEGFrame.o mptFileIO.o mptFileTemporary.o mptFileType.o mptPathString.o mptRandom.o mptStringBuffer.o mptTime.o OggStream.o OPL.o ParamEq.o pattern.o patternContainer.o Paula.o PluginManager.o PlugInterface.o Profiler.o Reverb.o RowVisitor.o S3MTools.o SampleFormatBRR.o SampleFormatFLAC.o SampleFormatMediaFoundation.o SampleFormatMP3.o SampleFormatOpus.o SampleFormats.o SampleFormatSFZ.o SampleFormatVorbis.o SampleIO.o serialization_utils.o Sndfile.o Sndmix.o Snd_flt.o Snd_fx.o SoundFilePlayConfig.o SymMODEcho.o Tables.o Tagging.o TinyFFT.o tuning.o tuningCollection.o UMXTools.o UpgradeModule.o version.o WavesReverb.o WAVTools.o WindowedFIR.o XMTools.o

Yeah, that should be equivalent.

Quote from: Alfnsionbgio on June 03, 2023, 09:23:12
Quote from: manx on June 03, 2023, 07:00:59What are the errors precisely?

I get this callstack when I run my webassembly game
Uncaught RuntimeError: index out of bounds
BfpThread_GetCurrentId http://localhost:8000/CaveGame.wasm:593832
BfInternalThread::ManualThreadInit(bf::System::Threading::Thread*) http://localhost:8000/CaveGame.wasm:578810
bf::System::Threading::Thread::ManualThreadInit() http://localhost:8000/CaveGame.wasm:576637
bf::System::Threading::Thread::Init() http://localhost:8000/CaveGame.wasm:455439
bf::System::Runtime::__BfStaticCtor() http://localhost:8000/CaveGame.wasm:359053
main http://localhost:8000/CaveGame.wasm:494597
createExportWrapper http://localhost:8000/CaveGame.js:912
callMain http://localhost:8000/CaveGame.js:11627
doRun http://localhost:8000/CaveGame.js:11677
run http://localhost:8000/CaveGame.js:11688

Here is the source code for that https://github.com/beefytech/Beef/blob/master/BeefySysLib/platform/posix/PosixCommon.cpp#L1396

To quote the author of that language, "The only "interesting" thing is that gCurrentThread is a TLS value. Still - this gets called on all programs. I don't see why it could break unless somehow this library is breaking TLS in general... too many TLS values for wasm/emscripten or something?"

libopenmpt itself does not use threads or thread-local-storage at all. One thing that might be happening here, is that beeflang appears to rely on POSIX threads, which are not enabled in emscripten by default, so it might be emscripten goofing out because of mismatched settings between libopempt and beeflang. You probably should build libopenmpt with EXACTLY PRECISELY IDENTICAL emscripten flags as beeflang uses. This should least be
-pthread. You can try aqdding that to the em++ command when compiling libopenmpt. Maybe this helps?! I am merely guessing here.

Quote from: Alfnsionbgio on June 03, 2023, 09:23:12Recompilation with above commands didn't help, still have the same issue. Well, but at least now I know that it is compiled more or less correctly. By the way, interesting how libopenmpt.a compiled now is 9600 KB, while libopenmpt.a I compiled with makefile was 13600 KB.

Probably due to skipping libmpg123/minimp3, libogg+libvorbis/stb_vorbis, zlib/miniz dependencies. Also, Makefile compiles with -flto, which I skipped in the simple command for simplicity (also less error-prone for you).

Alfnsionbgio

Okay, I got this library to work with beeflang. I think the issue was in beeflang runtime calling pthread_self() even when multithreading was disabled. Not sure why pthread_self() worked just fine when this library wasn't linked though.

My quick patch was to comment out this line:
mThreadId = BfpThread_GetCurrentId();
in C:\Program Files\BeefLang\wasm\src\rt\Thread.h class BfInternalThread ManualThreadInit
And recompile C:\Program Files\BeefLang\bin\Beef042RT32_wasm.a by running C:\Program Files\BeefLang\wasm\build_wasm.bat

I think that, to properly fix this, I need to add something like "if multithreading disabed, return 0, overwise proceed as usual" at the beginning of BfpThread_GetCurrentId(). I'll annoy beeflang devs about that.

Thanks manx, you helped me find the culprit. This lib is pretty rad.

I heard good things about https://ufmod.sourceforge.io/ audio library, but that supports only xm files, and it will probably be painful to get it to work on webassembly. Might use that for pc version, and libopenmpt for online version. Heard FMOD can play tracker music and is free "for developers with less than $200k revenue per year, on a small (under $500k) development budget", but that's closed source. Heard there is miniFMOD out there, but can't find source code of that.

manx

Quote from: Alfnsionbgio on June 04, 2023, 08:42:28Okay, I got this library to work with beeflang. I think the issue was in beeflang runtime calling pthread_self() even when multithreading was disabled. Not sure why pthread_self() worked just fine when this library wasn't linked though.

My quick patch was to comment out this line:
mThreadId = BfpThread_GetCurrentId();
in C:\Program Files\BeefLang\wasm\src\rt\Thread.h class BfInternalThread ManualThreadInit
And recompile C:\Program Files\BeefLang\bin\Beef042RT32_wasm.a by running C:\Program Files\BeefLang\wasm\build_wasm.bat

I think that, to properly fix this, I need to add something like "if multithreading disabed, return 0, overwise proceed as usual" at the beginning of BfpThread_GetCurrentId(). I'll annoy beeflang devs about that.

https://github.com/beefytech/Beef/blob/master/wasm/build_wasm.bat looks like it is enabling thread support in emscripten via -s USE_PTHREADS=1, which is wrong (see https://github.com/emscripten-core/emscripten/blob/96a832cee0cb3c028687dd03fa761264c67bf7b9/src/settings.js#L2136).

I am really not an expert on beeflang or emscripten though, but maybe pointing the beeflang maintainers to https://emscripten.org/docs/porting/pthreads.html could maybe cear things up.

In any case, if beeflang builds with thread enabled, you ABSOLUTELY NEED TO BUILD AND LINK every other library also with threading enabled, and in particular you need to link everything together with threading enabled. https://emscripten.org/docs/porting/pthreads.html very explicitly says "Pass the compiler flag -pthread when compiling any .c/.cpp files, AND when linking to generate the final output .js file.". I do not know if you control the final linking or if this is done by the beeflang framework.

Quote from: Alfnsionbgio on June 04, 2023, 08:42:28This lib is pretty rad.

Thanks!

Quote from: Alfnsionbgio on June 04, 2023, 08:42:28I heard good things about https://ufmod.sourceforge.io/ audio library, but that supports only xm files, and it will probably be painful to get it to work on webassembly. Might use that for pc version, and libopenmpt for online version. Heard FMOD can play tracker music and is free "for developers with less than $200k revenue per year, on a small (under $500k) development budget", but that's closed source. Heard there is miniFMOD out there, but can't find source code of that.

uFMOD looks like a successor to minifmod. I would not recommend using either if you need proper playback quality.

Alfnsionbgio

Quote from: manx on June 04, 2023, 09:02:16https://github.com/beefytech/Beef/blob/master/wasm/build_wasm.bat looks like it is enabling thread support in emscripten via -s USE_PTHREADS=1, which is wrong (see https://github.com/emscripten-core/emscripten/blob/96a832cee0cb3c028687dd03fa761264c67bf7b9/src/settings.js#L2136).

That was it, thank you! Simply removing -s USE_PTHREADS=1 was all that was needed apparently.

I'll post a working sample game once things get a bit more stable.