How to compile SDL3 Hello, World! to WebAssembly with Emscripten?

Hello,

I have successfully built simple SDL3 Hello, World! programs in both C and C++ using both clang 22.1.1. command line with Windows 11 SDK and CMake 4.3.0 with MSVC 19. A big thanks to the SDL developers and documentation writers!

Now my goal is to compile these programs to WebAssembly with Emscripten. If understand the instructions correctly, I need to first build the SDL library with emsdk

emcmake cmake -S vendored/SDL -B build -G "Visual Studio 18 2026"

ran successfully but

emcmake cmake --build build

fails with

emcmake: no compatible cmake generator found; Please install ninja or mingw32-make, or specify a generator explicitly using -G

emcmake cmake --build build -G "Visual Studio 18 2026"

fails with

Unknown argument -G

Does I need to install MSYS2? Where am I going wrong?

-Shane

Do you want to be able to compile it, or do you just need a binary so you can link and use wasm?

I don’t have a reason to compile it but I have done it before. I might go for it if there’s no binary release online. If you have a linux machine you may have better luck building on that. I might try it tonight if you want

Hi LevoD, thanks for your offer but I have since discovered the emcc flag -sUSE_SDL=3 which apparently links to a precompiled SDL3 library, so I no longer need to compile it myself.

Emscripten has its own compiler. I think you cannot use Visual Studio for Wasm (correct me if I am wrong, please).

I have built SDL3 without any problems using these simple commands:

> cd C:\libs\SDL3-3.4.2
> emcmake cmake -S . -B dist -DCMAKE_INSTALL_PREFIX="C:/libs/SDL3-devel-3.4.2-wasm" -DCMAKE_BUILD_TYPE=MinSizeRel
> cmake --build dist -j8
> cmake --install dist

Where:

  • -DCMAKE_INSTALL_PREFIX="C:/libs/SDL3-devel-3.4.2-wasm" - It is the path where you want to install SDL3
  • DCMAKE_BUILD_TYPE=MinSizeRel- It says to make a minimal size of build
  • cmake --build dist -j8 - It builds SDL3 to the dist folder and uses 8 cores of your CPU. You should change -j8 to your numbers of cores
  • cmake --install dist It installs all files to the -DCMAKE_INSTALL_PREFIX="C:/libs/SDL3-devel-3.4.2-wasm" folder

If you want I can describe how to build your first hello-world example to WASM. It will be helpful for me too because I need to practice in English.

Thanks @8Observer8 , Following this recipe I installed with MSYS2 and after some tweaks, emcmake cmake -S vendored/SDL -B build -G “Unix Makefiles” -DSDL_TESTS:BOOL=OFF ran without errors. However, when I tried to build with cd build/; emmake make, it failed with C:/Users/xxx/dev/msys64/home/xxx/sdl3/build/CMakeFiles/SDL3-static.dir/cmake_pch.h:4:10: fatal error:
‘/home/xxx/sdl3/vendored/SDL/src/SDL_internal.h’ file not found
4 | #include “/home/xxx/sdl3/vendored/SDL/src/SDL_internal.h”
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Which build environment are you using?

You do not need MinGW or MSVC. I have emsdk 4.0.15 only to build SDL3 to Wasm. Open CMD on the C disk and copy these commands:

> git clone https://github.com/emscripten-core/emsdk.git
> cd emsdk
> emsdk install 4.0.15
> emsdk activate 4.0.15

Note. It is very important to add this path C:\emsdk\upstream\emscripten to Path:

Unzip a fresh SDL3 source folder:

Open the CMD here and copy these commands:

> emcmake cmake -S . -B dist -DCMAKE_INSTALL_PREFIX="C:/libs/SDL3-devel-3.4.2-wasm" -DCMAKE_BUILD_TYPE=MinSizeRel
> cmake --build dist -j8
> cmake --install dist

And, please, show what is the result.

Do you try to build SDL3 library from source or do you try to build your own example? At first, you should built SDL3 library to Wasm at first.

Use the official examples that are ready to be using for Wasm. They contains SDL3-callbacks functions. You do not need to use emscripten_cancel_main_loop();.

For example, you can:

  • Create an empty folder for your project. For example, example-sdl3-c
  • Create a CMakeLists.txt file inside it with the following content:

CMakeLists.txt

cmake_minimum_required(VERSION 3.21)
project(hello-wasm-sdl3-c)

# Set the name of the future application (in Windows this would be app.exe, while for web it will be app.js / app.wasm)
add_executable(app)

# Set the C standard
set(CMAKE_C_STANDARD 11)

# Tell CMake where to find the SDL3 library configuration files
set(SDL3_DIR "C:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3")

# Load SDL3 package settings (compilation parameters and paths to headers)
find_package(SDL3 REQUIRED)

# Link SDL3 to our application (configures linking and include paths)
target_link_libraries(app PRIVATE SDL3::SDL3)

# Add source code to the project
target_sources(app
    PRIVATE
    src/main.c)
  • Create the src/main.c file in your project folder and copy the clear.c content to your src/main.c
  • Open CMD inside of your project folder
  • Type the configuration command:
emcmake cmake -S . -B dist -DCMAKE_BUILD_TYPE=Debug
  • Type the build command:
cmake --build dist
  • Two files will be created: app.js and app.wasm. You can copy them to your js folder and using this index.html file:

index.html

<!DOCTYPE html>
 
<html>
 
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello Wasm</title>
</head>

<body>
    <script async src="./js/app.js"></script>
</body>

I prefer use these two bat files to configure and build:

config-web.bat

emcmake cmake -S . -B dist/web ^
-DCMAKE_BUILD_TYPE=Debug

build-web.bat

cd dist\web
cmake --build . -j4

cd ..\..
mkdir public\js
set current_dir=%~dp0
copy "%current_dir%dist\web\app.wasm" "%current_dir%public\js"
copy "%current_dir%dist\web\app.js" "%current_dir%public\js"

It allows to configure and build with these two commands:

config-web
build-web

When I need to build my app to Release, I can change Debug to Release here:

config-web.bat

emcmake cmake -S . -B dist/web ^
-DCMAKE_BUILD_TYPE=Release

Done. emcmake insists on having -G generator -

C:\Users\xxx\dev\SDL>emcmake --version
emcmake is a helper for cmake, setting various environment
variables so that emcc etc. are used. Typical usage:

emcmake cmake [FLAGS]

C:\Users\xxx\dev\SDL>emcmake cmake -S . -B dist -DCMAKE_INSTALL_PREFIX=“C:/Users/xxxx/dev/SDL3-devel-3.4.2-wasm” -DCMAKE_BUILD_TYPE=MinSizeRel

emcmake: no compatible cmake generator found; Please install ninja or mingw32-make, or specify a generator explicitly using -G

Any ideas?

Excuse me! I realize why it works for me and not for you. I have MinGW in the PATH so CMake finds it automatically. I have installed the MinGW GCC 13.1 version because Qt 6.10 uses it. I use Win64 version without LLVM: https://winlibs.com/

When you download the MinGW (for example, in the mingw64_13.1 folder), add this path to your PATH: C:\mingw64_13.1\bin

Try to use emcmake again.

I went to https://winlibs.com/ and downloaded and unzipped GCC 15.2.0 (with POSIX threads) + MinGW-w64 13.0.0 (UCRT) - release 6 (LATEST) https://github.com/brechtsanders/winlibs_mingw/releases/download/15.2.0posix-13.0.0-ucrt-r6/winlibs-x86_64-posix-seh-gcc-15.2.0-mingw-w64ucrt-13.0.0-r6.zip and added mingw64\bin to my Path. Now emcmake cmake -S vendored/SDL -B build runs without errors. However cmake --build build fails with -

[  0%] Building C object CMakeFiles/SDL3-static.dir/cmake_pch.h.pch
In file included from :1:
In file included from C:/Users/xxxx/dev/SDL3/build/CMakeFiles/SDL3-static.dir/cmake_pch.h:4:
In file included from C:/Users/xxxx/dev/SDL3/vendored/SDL/src/SDL_internal.h:63:C:/Users/xxxx/dev/SDL3/vendored/SDL/include\build_config/SDL_build_config.h:54:2: error: Wrong SDL_build_config.h,
check your include path?
54 | #error Wrong SDL_build_config.h, check your include path?


This indicates a problem with the SDL path which is located at vendored\SDL. I have received this same error message while attempting different ways to build SDL3 with emsdk. Have you ever seen it?

You should delete the build folder. Simply re-running the command isn’t enough because CMake caches the previous (wrong) environment.

Please, try this:

  • Unzip the SDL3-3.4.2 again for a new build
  • Configure:
emcmake cmake -S . -B dist -DCMAKE_INSTALL_PREFIX="C:/Users/xxxx/dev/SDL3-devel-3.4.2-wasm" -DCMAKE_BUILD_TYPE=MinSizeRel
  • Build:
cmake --build dist
  • Install:
cmake --install dist

I discovered one of the includes in my SDL repo (located in vendored/SDL) was corrupted so I restored it to SDL/src/SDL_internal.h at main · libsdl-org/SDL · GitHub Next, I deleted my build directory and ran emcmake cmake -S vendored/SDL -B build. It reported -

emcmake: cmake -S vendored/SDL -B build ‘-DCMAKE_TOOLCHAIN_FILE=C:\Users\xxx\dev\emsdk\upstream\emscripten\cmake\Modules\Platform\Emscripten.cmake’ -DCMAKE_CROSSCOMPILING_EMULATOR=C:/Users/xxx/dev/emsdk/node/22.16.0_64bit/bin/node.exe -G ‘MinGW Makefiles’ in directory C:\Users\xxx\dev\SDL3 

...

-- SDL3 was configured with the following options:
--
-- Platform: Emscripten-1
-- 64-bit:   FALSE
-- Compiler: C:/Users/xxx/dev/emsdk/upstream/emscripten/emcc.bat
-- Revision: SDL-3.5.0-release-3.4.0-477-ga54dd7ba4
-- Vendor:

and ran without errors. Next I ran cmake -–build build and it built libSDL.a which appears to be static library (archive containing object files .o). I only found js and wasm files in the build/test directory. Is this normal?

I am working with a git clone of GitHub - libsdl-org/SDL: Simple DirectMedia Layer · GitHub Where did you get SDL3-devel-3.4.0-wasm ?

It will be created after you build and install SDL3 from source. Please, go here: Releases · libsdl-org/SDL · GitHub and download this archive:

Open CMD inside of the SDL3-3.4.2 folder and copy these commands one by one:

> emcmake cmake -S . -B dist -DCMAKE_INSTALL_PREFIX="C:/Users/xxxx/dev/SDL3-devel-3.4.2-wasm" -DCMAKE_BUILD_TYPE=MinSizeRel
> cmake --build dist
> cmake --install dist

The SDL3-devel-3.4.2-wasm folder with be created with the following content:

Note. In your case it will be created here C:/Users/xxxx/dev

You can use this SDL3 Wasm build in your projects:

set(SDL3_DIR "C:/libs/SDL3-devel-3.4.2-wasm/lib/cmake/SDL3")

Finally, it works! Thanks for your patient explanation. According to the CMake docs set(SDL3_DIR "C:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3") is simply assigning a value to a variable called SDL3_DIR). This variable does not appear to be used in CMakeLists.txt and I could not find any references to it in release-3.4.2 Since it is clearly needed in the build process, I assume it must be used in another script. Where is it called? I ask this because I will next attempt to use SDL_image 3.0 in a wasm program.

It is my example that creates SDL3_DIR in CMakeLists.txt:

CMakeLists.txt

cmake_minimum_required(VERSION 3.21)
project(finish-hello-wasm-sdl3-c)

# Set the C standard (must be set before add_executable)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)

# Set the name of the future application (in Windows this would be app.exe, 
# while for the web it will be app.js / app.wasm)
add_executable(app)

# Provide a hint to CMake on where to find the SDL3 library configuration files
set(SDL3_DIR "C:/libs/SDL3-devel-3.4.2-wasm/lib/cmake/SDL3")

# Load the SDL3 package settings (compilation parameters and header paths)
find_package(SDL3 REQUIRED)

# Link SDL3 to our application (configures linking and include paths)
target_link_libraries(app PRIVATE SDL3::SDL3)

# Add the source files to the executable build
target_sources(app
    PRIVATE
    src/main.c
)

finish-hello-wasm-sdl3-c.zip (4.5 KB)

If you use C++ you should change the lines above to:

# Set the C standard (must be set before add_executable)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

And change the file extension here to cpp:

# Add the source files to the executable build
target_sources(app
    PRIVATE
    src/main.cpp
)