SDL3 WebAssembly: Setup for C and C++ (Emscripten) SDL3 для WebAssembly: Настройка для C и C++ (Emscripten)

A guide to configuring SDL3 with CMake and Emscripten (emsdk) for WebAssembly. Руководство по настройке SDL3 с использованием CMake и Emscripten (emsdk) для WebAssembly.

1. Obtain SDL3 for Wasm 1. Получение SDL3 для Wasm

2. Project Configuration (CMakeLists.txt) 2. Конфигурация проекта (CMakeLists.txt)

CMakeLists.txt (C version)
set(CMAKE_BUILD_TYPE "Debug")

cmake_minimum_required(VERSION 3.21)
project(rectangles-sdl3)

# Set the C standard
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)

# Specify the exact location of the library configuration files
# The variable name must strictly match: LibraryName_DIR
set(SDL3_DIR "C:/libs/SDL3-devel-3.4.10-wasm/lib/cmake/SDL3")

# Check for the presence of the library in the system
# If it is not found, CMake will abort the configuration with an error
# REQUIRED means the library is mandatory for the build
find_package(SDL3 REQUIRED)

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

# Add source code to the project
target_sources(app
    PRIVATE
    src/main.c
)
 
# Link the library to our application (configures linking and include paths)
target_link_libraries(app PRIVATE SDL3::SDL3)
CMakeLists.txt (C++ version)
set(CMAKE_BUILD_TYPE "Debug")

cmake_minimum_required(VERSION 3.21)
project(rectangles-sdl3)

# Set the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Specify the exact location of the library configuration files
# The variable name must strictly match: LibraryName_DIR
set(SDL3_DIR "C:/libs/SDL3-devel-3.4.10-wasm/lib/cmake/SDL3")

# Check for the presence of the library in the system
# If it is not found, CMake will abort the configuration with an error
# REQUIRED means the library is mandatory for the build
find_package(SDL3 REQUIRED)

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

# Add source code to the project
target_sources(app
    PRIVATE
    src/main.cpp
)
 
# Link the library to our application (configures linking and include paths)
target_link_libraries(app PRIVATE SDL3::SDL3)

3. Source Code 3. Исходный код

src/main.c (or src/main.cpp):
#define SDL_MAIN_USE_CALLBACKS 1 // Use callback functions instead of main()

#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>

// We will use this renderer to draw into this window every frame
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;

// This function runs once at startup
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
    if (!SDL_Init(SDL_INIT_VIDEO))
    {
        SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }

    if (!SDL_CreateWindowAndRenderer("SDL3 Rectangles", 500, 500, SDL_WINDOW_RESIZABLE, &window, &renderer))
    {
        SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }

    SDL_SetRenderVSync(renderer, 1);

    return SDL_APP_CONTINUE; // Continue program execution!
}

// This function runs whenever a new event occurs (mouse input, key presses, etc.)
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
    if (event->type == SDL_EVENT_QUIT)
    {
        return SDL_APP_SUCCESS; // Terminate the program, reporting success to the OS
    }
    return SDL_APP_CONTINUE; // Continue program execution!
}

// This function runs once per frame and is the heart of the program
SDL_AppResult SDL_AppIterate(void *appstate)
{
    SDL_SetRenderDrawColor(renderer, 38, 43, 51, 255);

    // Clear the window with the draw color
    SDL_RenderClear(renderer);

    SDL_FRect rect1;
    rect1.x = 100;
    rect1.y = 50;
    rect1.w = 200;
    rect1.h = 60;
    SDL_SetRenderDrawColor(renderer, 220, 80, 80, SDL_ALPHA_OPAQUE);
    SDL_RenderFillRect(renderer, &rect1);

    SDL_FRect rect2;
    rect2.x = 50;
    rect2.y = 200;
    rect2.w = 100;
    rect2.h = 50;
    SDL_SetRenderDrawColor(renderer, 80, 180, 100, SDL_ALPHA_OPAQUE);
    SDL_RenderFillRect(renderer, &rect2);

    // Present the freshly cleared result to the screen
    SDL_RenderPresent(renderer);

    return SDL_APP_CONTINUE; // Continue program execution!
}

// This function runs once upon shutdown
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
    // SDL will clean up the window and renderer for us
}
public/index.html:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

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

</html>

4. Automation Scripts (.bat) 4. Скрипты автоматизации (.bat)

Batch files automate repetitive tasks. Run these from your terminal to configure and package your project. Файлы .bat автоматизируют повторяющиеся задачи. Запускайте их из терминала для настройки и упаковки проекта.

config-wasm.bat
emcmake cmake -S . -B dist/web
build-wasm.bat
cd dist\web
cmake --build .

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"

5. Build and Run 5. Сборка и запуск

Configure and build the project: Сконфигурируйте и соберите проект:

# Configure
config-wasm

# Build
build-wasm

Now, start your local server: Теперь запустите локальный сервер:

# Option 1: Using Node.js (http-server)
http-server -c-1

# Option 2: Using Python
python -m http.server 8080
Open localhost:8080 in your browser and check the console (F12 or Ctrl+Shift+J) to see the output. Откройте localhost:8080 в браузере и проверьте консоль (F12 или Ctrl+Shift+J), чтобы увидеть результат.

6. Source Code & Downloads 6. Исходный код и загрузки

You can download the complete configured project as a ZIP archive or explore the source code directly on GitHub: Вы можете скачать готовую настроенную сборку проекта в виде ZIP-архива или изучить исходный код прямо на GitHub:


Support My Work Поддержать проект

If these tutorials helped you, consider buying me a coffee! Если эти туториалы вам помогли, вы можете поддержать автора.

Sberbank (Russia only) Сбербанк (только для РФ)

Sberbank SBP QR Code

Direct transfer via phone number (Russia only) Перевод по номеру телефона (только для РФ)

+7 (917) 212-29-59

USDT TRC20

USDT TRC20 QR Code

Support via Cryptocurrency Поддержка криптовалютой

TMtY1YifNf6FKvgeFmqKGQR4NStKr3csGp