How can I write a one line command to build my game from source with SDL3 and SDL3_image

I’d like to learn a simple command to build my game from source.

I’d also like to migrate my sdl2 game to sdl3, and for this project I’m settled on GNU make for now.

I have pulled SDL3 3.20.2 and SDL3_image 3.2.4 from github (release versions).

I’m using ubuntu 22.04 for development. I installed these packages.

sudo apt-get install build-essential git make pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev libaudio-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 libpipewire-0.3-dev libwayland-dev libdecor-0-dev lpiburing-dev

Then I built SDL3.20.2 from source with cmake. Twice, actually, the difference being -DSDL_MAKE_POSITION_INDEPENDENT_CODE=ON in build2.

$ cmake -S . -B build -DSDL_TESTS=ON -D SDL_EXAMPLES=ON -D SDL_SHARED=ON -DSDL_STATIC=ON -D SDL_TEST_LIBRARY=ON -DSDL_INSTALL_TESTS=ON -DSDL_LIBC=ON 
$ cmake --build build
$ sudo cmake --install build --prefix /usr/local

#Try again
$ cmake -S . -B build2 -DSDL_MAKE_POSITION_INDEPENDENT_CODE=ON -DSDL_TESTS=ON -D SDL_EXAMPLES=ON -D SDL_SHARED=ON -DSDL_STATIC=ON -D SDL_TEST_LIBRARY=ON -DSDL_INSTALL_TESTS=ON -DSDL_LIBC=ON 
$ cmake --build build2
$ sudo cmake --install build2 --prefix /usr/local

A little hello world style project (I think it’s small enough for these forums. Also, I know I’m omitting important things like ignoring sigpipe, atexit cleanup, checking err).

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

int main(int argc, char *argv[]) {
        SDL_Init(SDL_INIT_VIDEO);
        SDL_Window *screen = SDL_CreateWindow("SomeGame", 800, 600, 0);
        SDL_Renderer *renderer = SDL_CreateRenderer(screen, NULL);
        SDL_SetRenderLogicalPresentation(renderer, 800, 600, SDL_LOGICAL_PRESENTATION_STRETCH);
        SDL_Surface *backgroundSurface = IMG_Load("art/background.png");
        SDL_Texture *backgroundTexture = SDL_CreateTextureFromSurface(renderer, backgroundSurface);
        int count = 0;
        while(count < 500) {
                SDL_RenderTexture(renderer, backgroundTexture, NULL, NULL);
                SDL_RenderPresent(renderer);
                count += 1;
        }

        SDL_DestroySurface(backgroundSurface);
        SDL_DestroyTexture(backgroundTexture);
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(screen);
        SDL_Quit();

        return 0;
}

I am building my game with commands equivalent to the following.

#!/bin/bash

/usr/bin/echo "Usage: build.sh source file with \".c\" ommitted"
/usr/bin/echo "Param1 $1"

export LD_LIBRARY_PATH=/usr/local/lib/

/usr/bin/gcc -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=5 -Wswitch-default -Wundef -Wunused -Wmaybe-uninitialized -Wuninitialized -DREENTRANT -o $1 $1.c -lSDL3 -lSDL3_image

This compiles and links without a critical error, but when I try to run the binary, I receive the following message,

error while loading shared libraries: libSDL3.so.0: cannot open shared object file: No such file or directory

Also,

$ ls /usr/local/lib
... snip ...
libSDL3.a
libSDL3_image.so
libSDL3_image.so.0
libSDL3_image.so.0.2.4
libSDL3.so
libSDL3.so.0
libSDL3.so.0.2.20
libSDL3_test.a
...snip...

I know I can statically link, but I don’t want to go that route. I’d learn to write cmakelist but not now.

I don’t want to debug by mail and take up too much of your time, but do you (forum gurus) have any quick thoughts?
.
.
.
Second quick question, does SDL3 support gcc --std=C89?

The export LD_LIBRARY_PATH=.. in your build script is only active during the runtime of that script, so useless for running your application.

You want to add a library search path to the executable, which can be done through -Wl,-rpath=/usr/local/lib. (documentation)
SDL’s pkg-config (*.pc*) files will also automatically add those flags.

e.g.

# add the pkg-config path
export PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig:$PKG_CONFIG_LIBDIR

gcc -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=5 -Wswitch-default -Wundef -Wunused -Wmaybe-uninitialized -Wuninitialized -DREENTRANT -o $1 $1.c $(pkg-config --cflags --libs sdl3-image)

In this commend, I left out pkg-config sdl3.
SDL3 is a dependency of SDL3_image and added automatically but it would be no error to add it explicitly.

Some days ago i run into the same issue.
A tutorial from Mike Shah helped me a lot.

Here is the tutorial video: https://www.youtube.com/watch?v=1S5qlQ7U34M
The interesting time stamp is about 16 Minutes.

After compiling and installing SDL3 (that is what you have already done) he gave the following commands:

pkg-config sdl3
pkg-config --libs sdl3
pkg-config --cflags sdl3
pkg-config --libs --cflags sdl3

And compiling your own program:

gcc yourcode.c -o myprog pkg-config --libs --cflags sdl3

1 Like

Yes. SDL3 itself needs to be built with a c99 compiler, but its headers are c89-compatible.

Reporting back after a getting successful runtime!

I used the following command.

/usr/bin/gcc -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=5 -Wswitch-default -Wundef -Wunused -Wmaybe-uninitialized -Wuninitialized -o p p.c -I/usr/local/include -L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags -lSDL3 -Wl,-rpath=/usr/local/lib -lSDL3 -lSDL3_image

For future forum readers, there may be elements of that command specific to my system (absolute paths/pkgconfig).

The changes I made from the OP are thus.

> Added $(pkg-config --cflags --libs sdl3), which rolled out to -I/usr/local/include -L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,–enable-new-dtags
> There happened to be a duplicate -Wl,-rpath=/usr/local/lib that I hard coded. This won’t be needed.
> Removed -DREENTRANT. That was a switch from my SDL2 game makefile; copy pasta.
.
.
.
Also, I’m happy to hear SDL3 headers are c89 compatible. This makes me optimistic for migrating many of my projects to SDL3… I’m already an SDL3 fan. 3D! Awesome!

THANKS