foxygit / doom Log in
commit dd94fde39cf6c95045811a167d3df24685160023
Author:     James Baicoianu <james_github@baicoianu.com>
AuthorDate: Sat Jan 11 08:40:23 2025 -0800
Commit:     GitHub <noreply@github.com>
CommitDate: Sat Jan 11 17:40:23 2025 +0100

    Emscripten build target support (#1717)

    * Fixed deadlock in OPL code when compiled with emscripten

    * Autodetect emscripten build environemt in config scripts

    * cmake support for emscripten build target

    * Restored cmake logic for building with SDL_net and/or SDL_mixer disabled
---
 CMakeLists.txt             | 13 +++++++--
 configure.ac               | 28 +++++++++++++++++++
 opl/CMakeLists.txt         | 16 +++++++++--
 opl/opl.c                  | 10 +++++++
 pcsound/CMakeLists.txt     | 16 +++++++++--
 src/CMakeLists.txt         | 70 +++++++++++++++++++++++++++++++++-------------
 src/Makefile.am            |  1 +
 src/doom/CMakeLists.txt    | 26 +++++++++++++----
 src/heretic/CMakeLists.txt | 26 +++++++++++++----
 src/hexen/CMakeLists.txt   | 25 +++++++++++++----
 src/setup/CMakeLists.txt   | 17 +++++++++--
 src/strife/CMakeLists.txt  | 25 +++++++++++++----
 textscreen/CMakeLists.txt  |  7 ++++-
 13 files changed, 224 insertions(+), 56 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2caabfc8..5a058d77 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,19 +34,26 @@ option(CMAKE_FIND_PACKAGE_PREFER_CONFIG
 option(ENABLE_SDL2_NET "Enable SDL2_net" On)
 option(ENABLE_SDL2_MIXER "Enable SDL2_mixer" On)

-find_package(SDL2 2.0.14)
+if (NOT DEFINED EMSCRIPTEN)
+    find_package(SDL2 2.0.14)
+endif()
 if(ENABLE_SDL2_MIXER)
-    find_package(SDL2_mixer 2.0.2)
+    if (NOT DEFINED EMSCRIPTEN)
+        find_package(SDL2_mixer 2.0.2)
+    endif()
 else()
     add_compile_definitions(DISABLE_SDL2MIXER=1)
 endif()

 if(ENABLE_SDL2_NET)
-    find_package(SDL2_net 2.0.0)
+    if (NOT DEFINED EMSCRIPTEN)
+        find_package(SDL2_net 2.0.0)
+    endif()
 else()
     add_compile_definitions(DISABLE_SDL2NET=1)
 endif()

+
 # Check for libsamplerate.
 find_package(SampleRate)
 if(SampleRate_FOUND)
diff --git a/configure.ac b/configure.ac
index b4d76ac4..7bf04169 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,6 +10,29 @@ PACKAGE_URL="https://www.chocolate-doom.org/"
 PACKAGE_RDNS="org.chocolate_doom"
 PACKAGE_BUGREPORT="https://github.com/chocolate-doom/chocolate-doom/issues"

+dnl Check for Emscripten environment so we can set necessary environment variables
+AC_ARG_ENABLE(
+  [emscripten],
+  [AS_HELP_STRING([--enable-emscripten=@<:@no/yes@:>@],[compile to JavaScript using Emscripten])],,
+  [AS_CASE([$CC],
+           [*emcc.py], [enable_emscripten="yes"],
+           [*emcc], [enable_emscripten="yes"],
+           [enable_emscripten="no"]
+	  )
+ ]
+)
+
+AS_IF([test "x$enable_emscripten" = "xyes"],
+  AC_MSG_NOTICE([auto-detected use of Emscripten])
+  SDL_CFLAGS="-s USE_SDL=2"
+  SDL_LIBS="-s USE_SDL=2"
+  SDLMIXER_CFLAGS="-s USE_SDL=2 -s USE_SDL_MIXER=2"
+  SDLMIXER_LIBS="-s USE_SDL=2 -s USE_SDL_MIXER=2"
+  SDLNET_CFLAGS="-s USE_SDL=2 -s USE_SDL_NET=2"
+  SDLNET_LIBS="-s USE_SDL=2 -s USE_SDL_NET=2"
+  EM_LDFLAGS="-s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY=1 -s EXPORTED_RUNTIME_METHODS=[ccall,cwrap,FS,ENV,PATH,ERRNO_CODES] -s FORCE_FILESYSTEM"
+)
+
 AC_CONFIG_AUX_DIR(autotools)
 AC_CANONICAL_HOST

@@ -244,6 +267,7 @@ AC_CONFIG_HEADERS(config.h:config.hin)
 AC_SUBST(WINDOWS_RC_VERSION)
 AC_SUBST(SDLMIXER_CFLAGS)
 AC_SUBST(SDLMIXER_LIBS)
+AC_SUBST(EM_LDFLAGS)

 AC_SUBST(SDLNET_CFLAGS)
 AC_SUBST(SDLNET_LIBS)
@@ -262,6 +286,10 @@ AC_SUBST(PACKAGE_BUGREPORT)
 dnl Shut up the datarootdir warnings.
 AC_DEFUN([AC_DATAROOTDIR_CHECKED])

+AS_IF([test "x$enable_emscripten" = "xyes"],
+  EXEEXT=".html"
+)
+
 AC_CONFIG_FILES([
 Makefile
 man/Makefile
diff --git a/opl/CMakeLists.txt b/opl/CMakeLists.txt
index b9cc2dd8..289ca279 100644
--- a/opl/CMakeLists.txt
+++ b/opl/CMakeLists.txt
@@ -12,7 +12,17 @@ add_library(opl STATIC
 target_include_directories(opl
                            INTERFACE "."
                            PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
-target_link_libraries(opl SDL2::SDL2)
-if(ENABLE_SDL2_MIXER)
-    target_link_libraries(opl SDL2_mixer::SDL2_mixer)
+if (DEFINED EMSCRIPTEN)
+    if(ENABLE_SDL2_MIXER)
+        set_target_properties(opl PROPERTIES COMPILE_FLAGS "-s USE_SDL=2 -s USE_SDL_MIXER=2")
+        set_target_properties(opl PROPERTIES LINK_FLAGS "-s USE_SDL=2 -s USE_SDL_MIXER=2")
+    else()
+        set_target_properties(opl PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
+        set_target_properties(opl PROPERTIES LINK_FLAGS "-s USE_SDL=2")
+    endif()
+else()
+    target_link_libraries(opl SDL2::SDL2)
+    if(ENABLE_SDL2_MIXER)
+        target_link_libraries(opl SDL2_mixer::SDL2_mixer)
+    endif()
 endif()
diff --git a/opl/opl.c b/opl/opl.c
index 2b452e84..1561304f 100644
--- a/opl/opl.c
+++ b/opl/opl.c
@@ -28,6 +28,10 @@

 //#define OPL_DEBUG_TRACE

+#ifdef EMSCRIPTEN
+#include <emscripten.h>
+#endif
+

 static opl_driver_t *drivers[] =
 {
@@ -472,6 +476,11 @@ void OPL_Delay(uint64_t us)
         return;
     }

+#ifdef EMSCRIPTEN
+    // Use async sleep when compiled with emscripten
+    emscripten_sleep(us);
+#else
+
     // Create a callback that will signal this thread after the
     // specified time.

@@ -496,6 +505,7 @@ void OPL_Delay(uint64_t us)

     SDL_DestroyMutex(delay_data.mutex);
     SDL_DestroyCond(delay_data.cond);
+#endif
 }

 void OPL_SetPaused(int paused)
diff --git a/pcsound/CMakeLists.txt b/pcsound/CMakeLists.txt
index f9eb1f2e..6f199018 100644
--- a/pcsound/CMakeLists.txt
+++ b/pcsound/CMakeLists.txt
@@ -8,7 +8,17 @@ add_library(pcsound STATIC
 target_include_directories(pcsound
                            INTERFACE "."
                            PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
-target_link_libraries(pcsound SDL2::SDL2)
-if(ENABLE_SDL2_MIXER)
-    target_link_libraries(pcsound SDL2_mixer::SDL2_mixer)
+if (DEFINED EMSCRIPTEN)
+    if(ENABLE_SDL2_MIXER)
+        set_target_properties(pcsound PROPERTIES COMPILE_FLAGS "-s USE_SDL=2 -s USE_SDL_MIXER=2")
+        set_target_properties(pcsound PROPERTIES LINK_FLAGS "-s USE_SDL=2 -s USE_SDL_MIXER=2")
+    else()
+        set_target_properties(pcsound PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
+        set_target_properties(pcsound PROPERTIES LINK_FLAGS "-s USE_SDL=2")
+    endif()
+else()
+    target_link_libraries(pcsound SDL2::SDL2)
+    if(ENABLE_SDL2_MIXER)
+        target_link_libraries(pcsound SDL2_mixer::SDL2_mixer)
+    endif()
 endif()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6fbf0790..aa9d0a4b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -32,11 +32,31 @@ set(DEDSERV_FILES
 add_executable("${PROGRAM_PREFIX}server" WIN32 ${COMMON_SOURCE_FILES} ${DEDSERV_FILES})
 target_include_directories("${PROGRAM_PREFIX}server"
                            PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
-target_link_libraries("${PROGRAM_PREFIX}server" SDL2::SDL2main SDL2::SDL2)
-if(ENABLE_SDL2_NET)
-    target_link_libraries("${PROGRAM_PREFIX}server" SDL2_net::SDL2_net)
+
+if (DEFINED EMSCRIPTEN)
+    set(SDL_FLAGS "-s USE_SDL=2")
+    if(ENABLE_SDL2_MIXER)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_MIXER=2")
+        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_SDL_MIXER=2")
+    endif()
+    if(ENABLE_SDL2_NET)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_NET=2")
+        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_SDL_NET=2")
+    endif()
+else()
+    set(SDL_LINK_LIBS SDL2::SDL2main SDL2::SDL2)
+    if(ENABLE_SDL2_MIXER)
+        list(APPEND SDL_LINK_LIBS SDL2_mixer::SDL2_mixer)
+    endif()
+    if(ENABLE_SDL2_NET)
+        list(APPEND SDL_LINK_LIBS SDL2_net::SDL2_net)
+    endif()
 endif()

+target_link_libraries("${PROGRAM_PREFIX}server" ${SDL_LINK_LIBS})
+set_target_properties("${PROGRAM_PREFIX}server" PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")
+set_target_properties("${PROGRAM_PREFIX}server" PROPERTIES LINK_FLAGS "${SDL_FLAGS}")
+
 # Source files used by the game binaries (chocolate-doom, etc.)

 set(GAME_SOURCE_FILES
@@ -126,13 +146,7 @@ set(DEHACKED_SOURCE_FILES
 set(SOURCE_FILES ${COMMON_SOURCE_FILES} ${GAME_SOURCE_FILES})
 set(SOURCE_FILES_WITH_DEH ${SOURCE_FILES} ${DEHACKED_SOURCE_FILES})

-set(EXTRA_LIBS SDL2::SDL2main SDL2::SDL2 textscreen pcsound opl)
-if(ENABLE_SDL2_MIXER)
-    list(APPEND EXTRA_LIBS SDL2_mixer::SDL2_mixer)
-endif()
-if(ENABLE_SDL2_NET)
-    list(APPEND EXTRA_LIBS SDL2_net::SDL2_net)
-endif()
+set(EXTRA_LIBS ${SDL_LINK_LIBS} textscreen pcsound opl)
 if(SampleRate_FOUND)
     list(APPEND EXTRA_LIBS SampleRate::samplerate)
 endif()
@@ -154,6 +168,7 @@ endif()

 target_include_directories("${PROGRAM_PREFIX}doom" PRIVATE ${GAME_INCLUDE_DIRS})
 target_link_libraries("${PROGRAM_PREFIX}doom" doom ${EXTRA_LIBS})
+set_target_properties("${PROGRAM_PREFIX}doom" PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")

 if(MSVC)
     set_target_properties("${PROGRAM_PREFIX}doom" PROPERTIES
@@ -168,6 +183,7 @@ endif()

 target_include_directories("${PROGRAM_PREFIX}heretic" PRIVATE ${GAME_INCLUDE_DIRS})
 target_link_libraries("${PROGRAM_PREFIX}heretic" heretic ${EXTRA_LIBS})
+set_target_properties("${PROGRAM_PREFIX}heretic" PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")

 if(MSVC)
     set_target_properties("${PROGRAM_PREFIX}heretic" PROPERTIES
@@ -182,6 +198,7 @@ endif()

 target_include_directories("${PROGRAM_PREFIX}hexen" PRIVATE ${GAME_INCLUDE_DIRS})
 target_link_libraries("${PROGRAM_PREFIX}hexen" hexen ${EXTRA_LIBS})
+set_target_properties("${PROGRAM_PREFIX}hexen" PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")

 if(MSVC)
     set_target_properties("${PROGRAM_PREFIX}hexen" PROPERTIES
@@ -196,6 +213,7 @@ endif()

 target_include_directories("${PROGRAM_PREFIX}strife" PRIVATE ${GAME_INCLUDE_DIRS})
 target_link_libraries("${PROGRAM_PREFIX}strife" strife ${EXTRA_LIBS})
+set_target_properties("${PROGRAM_PREFIX}strife" PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")

 if(MSVC)
     set_target_properties("${PROGRAM_PREFIX}strife" PROPERTIES
@@ -227,13 +245,9 @@ endif()

 target_include_directories("${PROGRAM_PREFIX}setup"
                            PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
-target_link_libraries("${PROGRAM_PREFIX}setup" SDL2::SDL2main SDL2::SDL2 setup textscreen)
-if(ENABLE_SDL2_MIXER)
-    target_link_libraries("${PROGRAM_PREFIX}setup" SDL2_mixer::SDL2_mixer)
-endif()
-if(ENABLE_SDL2_NET)
-    target_link_libraries("${PROGRAM_PREFIX}setup" SDL2_net::SDL2_net)
-endif()
+target_link_libraries("${PROGRAM_PREFIX}setup" ${SDL_LINK_LIBS} setup textscreen)
+set_target_properties("${PROGRAM_PREFIX}setup" PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")
+
 if(WIN32)
     target_link_libraries("${PROGRAM_PREFIX}setup" winmm)
 endif()
@@ -243,12 +257,30 @@ if(MSVC)
                           LINK_FLAGS "/MANIFEST:NO")
 endif()

+if (DEFINED EMSCRIPTEN)
+    set_target_properties("${PROGRAM_PREFIX}setup" PROPERTIES LINK_FLAGS "${SDL_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY=1 -s EXPORTED_FUNCTIONS=_main,ccall,cwrap,FS,ENV,PATH,ERRNO_CODES")
+    set_target_properties("${PROGRAM_PREFIX}strife" PROPERTIES LINK_FLAGS "${SDL_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY=1 -s EXPORTED_FUNCTIONS=_main,ccall,cwrap,FS,ENV,PATH,ERRNO_CODES")
+    set_target_properties("${PROGRAM_PREFIX}doom" PROPERTIES LINK_FLAGS "${SDL_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY=1 -s EXPORTED_FUNCTIONS=_main,ccall,cwrap,FS,ENV,PATH,ERRNO_CODES")
+    set_target_properties("${PROGRAM_PREFIX}heretic" PROPERTIES LINK_FLAGS "${SDL_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY=1 -s EXPORTED_FUNCTIONS=_main,ccall,cwrap,FS,ENV,PATH,ERRNO_CODES")
+    set_target_properties("${PROGRAM_PREFIX}hexen" PROPERTIES LINK_FLAGS "${SDL_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY=1 -s EXPORTED_FUNCTIONS=_main,ccall,cwrap,FS,ENV,PATH,ERRNO_CODES")
+endif()
+
 add_executable(midiread midifile.c z_native.c i_system.c m_argv.c m_misc.c d_iwad.c deh_str.c m_config.c)
 target_compile_definitions(midiread PRIVATE "-DTEST")
 target_include_directories(midiread PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
-target_link_libraries(midiread SDL2::SDL2)
+if (DEFINED EMSCRIPTEN)
+    set_target_properties(midiread PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
+    set_target_properties(midiread PROPERTIES LINK_FLAGS "-s USE_SDL=2")
+else()
+    target_link_libraries(midiread SDL2::SDL2)
+endif()

 add_executable(mus2mid mus2mid.c memio.c z_native.c i_system.c m_argv.c m_misc.c d_iwad.c deh_str.c m_config.c)
 target_compile_definitions(mus2mid PRIVATE "-DSTANDALONE")
 target_include_directories(mus2mid PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
-target_link_libraries(mus2mid SDL2::SDL2)
+if (DEFINED EMSCRIPTEN)
+    set_target_properties(mus2mid PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
+    set_target_properties(mus2mid PROPERTIES LINK_FLAGS "-s USE_SDL=2")
+else()
+    target_link_libraries(mus2mid SDL2::SDL2)
+endif()
diff --git a/src/Makefile.am b/src/Makefile.am
index 68ec563a..29ed0d72 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -152,6 +152,7 @@ EXTRA_LIBS =                                               \
                $(top_builddir)/pcsound/libpcsound.a        \
                $(top_builddir)/opl/libopl.a                \
                @LDFLAGS@                                   \
+               @EM_LDFLAGS@                                \
                @SDL_LIBS@                                  \
                @SDLMIXER_LIBS@                             \
                @SDLNET_LIBS@
diff --git a/src/doom/CMakeLists.txt b/src/doom/CMakeLists.txt
index 36db89da..6e878a0f 100644
--- a/src/doom/CMakeLists.txt
+++ b/src/doom/CMakeLists.txt
@@ -68,10 +68,24 @@ add_library(doom STATIC
             wi_stuff.c      wi_stuff.h)

 target_include_directories(doom PRIVATE "../" "${CMAKE_CURRENT_BINARY_DIR}/../../")
-target_link_libraries(doom SDL2::SDL2)
-if(ENABLE_SDL2_MIXER)
-    target_link_libraries(doom SDL2_mixer::SDL2_mixer)
-endif()
-if(ENABLE_SDL2_NET)
-    target_link_libraries(doom SDL2_net::SDL2_net)
+
+if (DEFINED EMSCRIPTEN)
+    set(SDL_FLAGS "-s USE_SDL=2")
+    if(ENABLE_SDL2_MIXER)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_MIXER=2")
+    endif()
+    if(ENABLE_SDL2_NET)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_NET=2")
+    endif()
+else()
+    set(SDL_LINK_LIBS SDL2::SDL2)
+    if(ENABLE_SDL2_MIXER)
+        list(APPEND SDL_LINK_LIBS SDL2_mixer::SDL2_mixer)
+    endif()
+    if(ENABLE_SDL2_NET)
+        list(APPEND SDL_LINK_LIBS SDL2_net::SDL2_net)
+    endif()
 endif()
+target_link_libraries(doom ${SDL_LINK_LIBS})
+set_target_properties(doom PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")
+set_target_properties(doom PROPERTIES LINK_FLAGS "${SDL_FLAGS}")
diff --git a/src/heretic/CMakeLists.txt b/src/heretic/CMakeLists.txt
index ea39c44d..ac6d2fba 100644
--- a/src/heretic/CMakeLists.txt
+++ b/src/heretic/CMakeLists.txt
@@ -54,10 +54,24 @@ add_library(heretic STATIC
             s_sound.c           s_sound.h)

 target_include_directories(heretic PRIVATE "../" "${CMAKE_CURRENT_BINARY_DIR}/../../")
-target_link_libraries(heretic textscreen SDL2::SDL2)
-if(ENABLE_SDL2_MIXER)
-    target_link_libraries(heretic SDL2_mixer::SDL2_mixer)
-endif()
-if(ENABLE_SDL2_NET)
-    target_link_libraries(heretic SDL2_net::SDL2_net)
+
+if (DEFINED EMSCRIPTEN)
+    set(SDL_FLAGS "-s USE_SDL=2")
+    if(ENABLE_SDL2_MIXER)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_MIXER=2")
+    endif()
+    if(ENABLE_SDL2_NET)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_NET=2")
+    endif()
+else()
+    set(SDL_LINK_LIBS SDL2::SDL2)
+    if(ENABLE_SDL2_MIXER)
+        list(APPEND SDL_LINK_LIBS SDL2_mixer::SDL2_mixer)
+    endif()
+    if(ENABLE_SDL2_NET)
+        list(APPEND SDL_LINK_LIBS SDL2_net::SDL2_net)
+    endif()
 endif()
+target_link_libraries(heretic textscreen ${SDL_LINK_LIBS})
+set_target_properties(heretic PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")
+set_target_properties(heretic PROPERTIES LINK_FLAGS "${SDL_FLAGS}")
diff --git a/src/hexen/CMakeLists.txt b/src/hexen/CMakeLists.txt
index fe963224..3eba5d07 100644
--- a/src/hexen/CMakeLists.txt
+++ b/src/hexen/CMakeLists.txt
@@ -56,10 +56,23 @@ add_library(hexen STATIC
                                 xddefs.h)

 target_include_directories(hexen PRIVATE "../" "${CMAKE_CURRENT_BINARY_DIR}/../../")
-target_link_libraries(hexen SDL2::SDL2)
-if(ENABLE_SDL2_MIXER)
-    target_link_libraries(hexen SDL2_mixer::SDL2_mixer)
-endif()
-if(ENABLE_SDL2_NET)
-    target_link_libraries(hexen SDL2_net::SDL2_net)
+if (DEFINED EMSCRIPTEN)
+    set(SDL_FLAGS "-s USE_SDL=2")
+    if(ENABLE_SDL2_MIXER)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_MIXER=2")
+    endif()
+    if(ENABLE_SDL2_NET)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_NET=2")
+    endif()
+else()
+    set(SDL_LINK_LIBS SDL2::SDL2)
+    if(ENABLE_SDL2_MIXER)
+        list(APPEND SDL_LINK_LIBS SDL2_mixer::SDL2_mixer)
+    endif()
+    if(ENABLE_SDL2_NET)
+        list(APPEND SDL_LINK_LIBS SDL2_net::SDL2_net)
+    endif()
 endif()
+target_link_libraries(hexen ${SDL_LINK_LIBS})
+set_target_properties(hexen PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")
+set_target_properties(hexen PROPERTIES LINK_FLAGS "${SDL_FLAGS}")
diff --git a/src/setup/CMakeLists.txt b/src/setup/CMakeLists.txt
index fa7390c2..c25af659 100644
--- a/src/setup/CMakeLists.txt
+++ b/src/setup/CMakeLists.txt
@@ -15,7 +15,18 @@ add_library(setup STATIC
             txt_mouseinput.c    txt_mouseinput.h)

 target_include_directories(setup PRIVATE "../" "${CMAKE_CURRENT_BINARY_DIR}/../../")
-target_link_libraries(setup textscreen SDL2::SDL2)
-if(ENABLE_SDL2_MIXER)
-    target_link_libraries(setup SDL2_mixer::SDL2_mixer)
+
+if (DEFINED EMSCRIPTEN)
+    set(SDL_FLAGS "-s USE_SDL=2")
+    if(ENABLE_SDL2_MIXER)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_MIXER=2")
+    endif()
+else()
+    set(SDL_LINK_LIBS, "SDL2::SDL2")
+    if(ENABLE_SDL2_MIXER)
+        list(APPEND SDL_LINK_LIBS SDL2_mixer::SDL2_mixer)
+    endif()
 endif()
+target_link_libraries(setup textscreen ${SDL_LINK_LIBS})
+set_target_properties(setup PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")
+set_target_properties(setup PROPERTIES LINK_FLAGS "${SDL_FLAGS}")
diff --git a/src/strife/CMakeLists.txt b/src/strife/CMakeLists.txt
index 58d74dad..20d336cd 100644
--- a/src/strife/CMakeLists.txt
+++ b/src/strife/CMakeLists.txt
@@ -70,10 +70,23 @@ set(STRIFE_SOURCES
 add_library(strife STATIC ${STRIFE_SOURCES})

 target_include_directories(strife PRIVATE "../" "../../win32/" "${CMAKE_CURRENT_BINARY_DIR}/../../")
-target_link_libraries(strife textscreen SDL2::SDL2)
-if(ENABLE_SDL2_MIXER)
-    target_link_libraries(strife SDL2_mixer::SDL2_mixer)
-endif()
-if(ENABLE_SDL2_NET)
-    target_link_libraries(strife SDL2_net::SDL2_net)
+if (DEFINED EMSCRIPTEN)
+    set(SDL_FLAGS "-s USE_SDL=2")
+    if(ENABLE_SDL2_MIXER)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_MIXER=2")
+    endif()
+    if(ENABLE_SDL2_NET)
+        set(SDL_FLAGS "${SDL_FLAGS} -s USE_SDL_NET=2")
+    endif()
+else()
+    set(SDL_LINK_LIBS, "SDL2::SDL2")
+    if(ENABLE_SDL2_MIXER)
+        list(APPEND SDL_LINK_LIBS SDL2_mixer::SDL2_mixer)
+    endif()
+    if(ENABLE_SDL2_NET)
+        list(APPEND SDL_LINK_LIBS SDL2_net::SDL2_net)
+    endif()
 endif()
+target_link_libraries(strife textscreen ${SDL_LINK_LIBS})
+set_target_properties(strife PROPERTIES COMPILE_FLAGS "${SDL_FLAGS}")
+set_target_properties(strife PROPERTIES LINK_FLAGS "${SDL_FLAGS}")
diff --git a/textscreen/CMakeLists.txt b/textscreen/CMakeLists.txt
index 402ebfd7..7e33826d 100644
--- a/textscreen/CMakeLists.txt
+++ b/textscreen/CMakeLists.txt
@@ -25,4 +25,9 @@ add_library(textscreen STATIC
 target_include_directories(textscreen
                            INTERFACE "."
                            PRIVATE "../src/")
-target_link_libraries(textscreen m SDL2::SDL2)
+if (DEFINED EMSCRIPTEN)
+    set_target_properties(textscreen PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
+    set_target_properties(textscreen PROPERTIES LINK_FLAGS "-s USE_SDL=2")
+else()
+    target_link_libraries(textscreen m SDL2::SDL2)
+endif()