Set up your computer
You can read every lesson and watch every program in this browser. To change the code, you need tools on your own computer.
These lessons expect that you know basic C: variables, functions, and pointers. You need four things:
- A C compiler, which turns your C code into a program.
- CMake, which gives the compiler the correct options.
- SDL, the library that opens the window and draws in it.
- A text editor. Any editor is good for these lessons.
Step 1: Install the tools
Linux
On Ubuntu or Debian, install the compiler, CMake, and the libraries that SDL needs:
sudo apt install build-essential git cmake pkg-config \
libasound2-dev libpulse-dev libaudio-dev libfribidi-dev libjack-dev \
libsndio-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev \
libxfixes-dev libxi-dev libxss-dev libxtst-dev libxkbcommon-dev \
libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev \
libthai-dev libusb-1.0-0-dev libpipewire-0.3-dev libwayland-dev \
libdecor-0-dev liburing-devUbuntu 24.04 has no SDL3 package. CMake downloads and builds SDL3 for you in step 3.
On Fedora 43 or later, install the SDL3 package:
sudo dnf install gcc make cmake SDL3-develOn Arch, install the SDL3 package:
sudo pacman -S gcc make cmake sdl3On Ubuntu or Debian:
sudo apt install build-essential cmake libsdl2-devOn Fedora 43 or later:
sudo dnf install gcc make cmake sdl2-compat-develOn Arch:
sudo pacman -S gcc make cmake sdl2-compatThe sdl2-compat package gives you the SDL2 API, and it runs on SDL3.
macOS
Install the Apple compiler. A window opens, and you follow its steps.
xcode-select --installIf you do not have Homebrew, install Homebrew.
Then install CMake and SDL3:
brew install cmake sdl3Then install CMake and SDL2:
brew install cmake sdl2-compatThe sdl2-compat package gives you the SDL2 API, and it runs on SDL3.
Windows
Install MSYS2. MSYS2 gives you the compiler and a terminal.
Open the program named MSYS2 UCRT64 from the Start menu. Use this terminal for all the commands on this page.
Install the compiler, CMake, Ninja, and SDL3:
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-sdl3Install the compiler, CMake, Ninja, and SDL2:
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-SDL2Step 2: Make the project
Make a folder for the project:
mkdir hello
cd helloLinux
Save the two files below in the hello folder.
macOS
Save the two files below in the hello folder.
Windows
Save the two files below in the hello folder. In a default MSYS2 installation, the folder is C:\msys64\home\YOURNAME\hello.
/* Open a window and fill it with one color. */
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
/* SDL calls this once, when the program starts. */
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
if (!SDL_Init(SDL_INIT_VIDEO)) {
SDL_Log("SDL_Init failed: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (!SDL_CreateWindowAndRenderer("Hello, window", 640, 480, 0,
&window, &renderer)) {
SDL_Log("SDL_CreateWindowAndRenderer failed: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
SDL_SetRenderVSync(renderer, 1);
return SDL_APP_CONTINUE;
}
/* SDL calls this for each event, such as a click on the close button. */
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
if (event->type == SDL_EVENT_QUIT) {
return SDL_APP_SUCCESS;
}
return SDL_APP_CONTINUE;
}
/* SDL calls this again and again, once for each frame. */
SDL_AppResult SDL_AppIterate(void *appstate)
{
SDL_SetRenderDrawColor(renderer, 32, 96, 160, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
return SDL_APP_CONTINUE;
}
/* SDL calls this once, when the program ends. */
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
/* SDL destroys the window and the renderer for you. */
}cmake_minimum_required(VERSION 3.24)
project(hello C)
# Use an installed SDL 3.4 or later if there is one. If not, download and build it.
include(FetchContent)
FetchContent_Declare(
SDL3
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
GIT_TAG release-3.4.18
GIT_SHALLOW TRUE
FIND_PACKAGE_ARGS 3.4 CONFIG
)
FetchContent_MakeAvailable(SDL3)
add_executable(hello WIN32 main.c)
target_link_libraries(hello PRIVATE SDL3::SDL3)/* Open a window and fill it with one color. */
#include <SDL.h>
#include <stdbool.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static bool running = true;
/* The loop calls this again and again, once for each frame. */
static void frame(void)
{
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
}
SDL_SetRenderDrawColor(renderer, 32, 96, 160, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
SDL_Log("SDL_Init failed: %s", SDL_GetError());
return 1;
}
if (SDL_CreateWindowAndRenderer(640, 480, 0, &window, &renderer) != 0) {
SDL_Log("SDL_CreateWindowAndRenderer failed: %s", SDL_GetError());
SDL_Quit();
return 1;
}
SDL_SetWindowTitle(window, "Hello, window");
SDL_RenderSetVSync(renderer, 1);
#ifdef __EMSCRIPTEN__
/* A browser does not let a program stay in its own loop. */
emscripten_set_main_loop(frame, 0, 1);
#else
while (running) {
frame();
}
#endif
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}cmake_minimum_required(VERSION 3.16)
project(hello C)
find_package(SDL2 REQUIRED CONFIG)
add_executable(hello WIN32 main.c)
# Windows needs SDL2main. The other systems do not have this library.
if(TARGET SDL2::SDL2main)
target_link_libraries(hello PRIVATE SDL2::SDL2main)
endif()
target_link_libraries(hello PRIVATE SDL2::SDL2)The lesson Open a window explains each part of main.c.
Step 3: Build and run
Run these commands in the hello folder:
cmake -S . -B build
cmake --build build
./build/helloThe first command prepares the build. The second command compiles the program. The third command runs it.
If your system has no SDL3 package, the first two commands download and build SDL3. This happens one time for each project, and it takes some minutes.
A blue window with the title "Hello, window" opens. Close the window to end the program.
Step 4: Build for the browser
This step is optional. If you want your own programs on a web page, do this step.
Emscripten is a C compiler that makes programs for the browser. Install it in a folder of its own:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.shOn Windows, use Command Prompt for these commands. Type emsdk.bat for ./emsdk, and type emsdk_env.bat for the last line. You must also install Git for Windows first.
Run the last line of the block again in each new terminal.
Go back to the hello folder, then build and open the page:
emcc main.c -sUSE_SDL=3 -o index.html
emrun index.htmlemcc main.c -sUSE_SDL=2 -o index.html
emrun index.htmlThe first emcc command also builds SDL for the browser, so it takes longer than later builds.