Some time ago I've started to porting my SDL2 based angine to SDL3. There were some issues I was struggled with, but one day I woke up with a thing in my head to test if current build could be ported to emscripten.
Previous version of my engine was ported and everything went almost smooth. I've used emsdk and it's commands like 'emcmake cmake ..' and 'emmake make -j4' to build the project.
But this time I wanted to try something interesting and another way of handling the project. I'm using VSCode with "CMake tools" extension, which allows me to build the app from the IDE.
Using cmake-variants.yaml file I can have more build types! For example
buildType:
default: debug
choices:
debug:
short: Debug
long: Emit debug information
buildType: Debug
release:
short: Release
long: Optimize generated code
buildType: Release
release_emscipten:
short: Release Emscipten
long: Build for web
buildType: Release_Emscripten
First get emsdk build. https://emscripten.org/docs/tools_reference/emsdk.html
Then install latest emscripten core.
emsdk install latest
emsdk activate latest
emcmake is the wrapper for cmake for emscripten. There is a Emscripten.cmake file which is used to generate build configs, so I'm just using it. It's not correct way though but it works.
if (CMAKE_BUILD_TYPE STREQUAL "Release_Emscripten")
set(EMSDK_PATH $ENV{HOME}/SDK/emsdk)
include("${EMSDK_PATH}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake")
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin/html )
add_executable(${PROJECT_NAME} ${all_SRCS})
set(USE_FLAGS "-sUSE_SDL=3 -sUSE_SDL_MIXER=3 -sUSE_FREETYPE -sUSE_SDL_TTF=3 -sUSE_ZLIB=1 -Wno-experimental")
set(CMAKE_CXX_FLAGS "${USE_FLAGS}")
set(CMAKE_C_FLAGS "${USE_FLAGS}")
set(CMAKE_EXECUTABLE_SUFFIX .html)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
# Fix error with unrecognized option in wasm
set(CMAKE_C_LINK_DEPENDS_USE_LINKER FALSE)
set(CMAKE_CXX_LINK_DEPENDS_USE_LINKER FALSE)
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "--no-check-features --use-preload-plugins --preload-file ../assets -s WASM=0 -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=1gb -sPTHREAD_POOL_SIZE_STRICT=100")
endif()
Build was failed at first time because of [build] wasm-ld: error: unknown argument: --dependency-file=CMakeFiles/database-backup-recovery.dir/link.d
It was fixed with
set(CMAKE_C_LINK_DEPENDS_USE_LINKER FALSE)
set(CMAKE_CXX_LINK_DEPENDS_USE_LINKER FALSE)
Next thing is that SDL3_mixer was not ported yet! Gosh... It was the time to figure out if I can port it)
First of all SDL3 should be updated to the latest version https://github.com/emscripten-core/emscripten/pull/26572
Then I've spent lots of time to figure out the correct way to implement the port and tests for it. It was fun. I've added wav support by default and ogg/mp3 as optional.
https://github.com/emscripten-core/emscripten/pull/26571
To check the port build use commands from ${EMSDK_PATH}/upstream/emscripten folder. for any port
./embuilder clear sdl3_mixer
./embuilder build sdl3_mixer
For tests use
test/runner browser.test_sdl3_mixer_wav
test/runner browser.test_sdl3_mixer_music
test/runner other.test_sdl3_mixer
There is an option to setup Task in VSCode to execute compiled project in the browser. but for me it's fine to use nodes http-server . from the build folder.