Requirements:
Raspberry Pi OS (other Linux distros may work as well).
In modern times, the Raspberry Pi works mostly like any other Linux device: for video, you can use X11, Wayland, or KMSDRM. For audio, you can use ALSA, PulseAudio, or PipeWire, etc. OpenGL, OpenGL ES, and Vulkan are known to work.
There is a video backend in SDL called "rpi" that uses a deprecated Broadcom interface (named "dispmanx") to draw directly to the console without X11. Newer Raspberry Pi OS releases don't support this (and work fine with our "kmsdrm" backend for the same purposes, a standard Linux interface). Don't panic if you can't use this backend, or CMake says it can't find libraries it needs for this.
SDL has, in past times, worked on the original Raspberry Pi and the RPi 2, but these devices are no longer targets we actively test; if they broke, please report bugs or send patches!
The Raspberry Pi 3 and later (in 32-bit and 64-bit mode) are still known to work well at the time of this writing. The Raspberry Pi Zero and Zero 2 are also known to work well.
The rest of this document is likely out of date; a lot has changed in recent years in both SDL and the Raspberry Pi universe, and this document has not been updated to reflect those details. Take the rest of this information with a grain of salt!
If your Pi has NEON support, make sure you add -mfpu=neon to your CFLAGS so that SDL will select some otherwise-disabled highly-optimized code. The original Pi and Pi Zero units don't have NEON; everything from the Pi2/PiZero2 and later do.
To cross compile SDL for Raspbian from your desktop machine, you'll need a Raspbian system root and the cross compilation tools. We'll assume these tools will be placed in /opt/rpi-tools
sudo git clone --depth 1 https://github.com/raspberrypi/tools /opt/rpi-tools
You'll also need a Raspbian binary image. Get it from: http://downloads.raspberrypi.org/raspbian_latest After unzipping, you'll get file with a name like: "
export SYSROOT=/opt/rpi-sysroot
sudo kpartx -a -v <path_to_raspbian_image>.img
sudo mount -o loop /dev/mapper/loop0p2 /mnt
sudo cp -r /mnt $SYSROOT
sudo apt-get install qemu binfmt-support qemu-user-static
sudo cp /usr/bin/qemu-arm-static $SYSROOT/usr/bin
sudo mount --bind /dev $SYSROOT/dev
sudo mount --bind /proc $SYSROOT/proc
sudo mount --bind /sys $SYSROOT/sys
Now, before chrooting into the ARM sysroot, you'll need to apply a workaround, edit $SYSROOT/etc/ld.so.preload and comment out all lines in it.
sudo chroot $SYSROOT
apt-get install libudev-dev libasound2-dev libdbus-1-dev libraspberrypi0 libraspberrypi-bin libraspberrypi-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev
exit
sudo umount $SYSROOT/dev
sudo umount $SYSROOT/proc
sudo umount $SYSROOT/sys
sudo umount /mnt
There's one more fix required, as the libdl.so symlink uses an absolute path which doesn't quite work in our setup.
sudo rm -rf $SYSROOT/usr/lib/arm-linux-gnueabihf/libdl.so
sudo ln -s ../../../lib/arm-linux-gnueabihf/libdl.so.2 $SYSROOT/usr/lib/arm-linux-gnueabihf/libdl.so
The final step is compiling SDL itself.
export CC="/opt/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc --sysroot=$SYSROOT -I$SYSROOT/opt/vc/include -I$SYSROOT/usr/include -I$SYSROOT/opt/vc/include/interface/vcos/pthreads -I$SYSROOT/opt/vc/include/interface/vmcs_host/linux"
cd <SDL SOURCE>
mkdir -p build;cd build
LDFLAGS="-L$SYSROOT/opt/vc/lib" ../configure --with-sysroot=$SYSROOT --host=arm-raspberry-linux-gnueabihf --prefix=$PWD/rpi-sdl3-installed --disable-pulseaudio --disable-esd
make
make install
To be able to deploy this to /usr/local in the Raspbian system you need to fix up a few paths:
perl -w -pi -e "s#$PWD/rpi-sdl3-installed#/usr/local#g;" ./rpi-sdl3-installed/lib/libSDL3.la ./rpi-sdl3-installed/lib/pkgconfig/sdl3.pc
If you get sound problems, buffer underruns, etc, run "sudo rpi-update" to update the RPi's firmware. Note that doing so will fix these problems, but it will also render the CMA - Dynamic Memory Split functionality useless.
Also, by default the Raspbian distro configures the GPU RAM at 64MB, this is too low in general, specially if a 1080p TV is hooked up.
See here how to configure this setting: http://elinux.org/RPiconfig
Using a fixed gpu_mem=128 is the best option (specially if you updated the firmware, using CMA probably won't work, at least it's the current case).
Make sure you belong to the "input" group.
sudo usermod -aG input `whoami`
If you notice that ALSA works but there's no audio over HDMI, try adding:
hdmi_drive=2
to your config.txt file and reboot.
Reference: http://www.raspberrypi.org/phpBB3/viewtopic.php?t=5062
The Text Input API is supported, with translation of scan codes done via the kernel symbol tables. For this to work, SDL needs access to a valid console. If you notice there's no SDL_EVENT_TEXT_INPUT message being emitted, double check that your app has read access to one of the following:
This is usually not a problem if you run from the physical terminal (as opposed to running from a pseudo terminal, such as via SSH). If running from a PTS, a quick workaround is to run your app as root or add yourself to the tty group, then re-login to the system.
sudo usermod -aG tty `whoami`
The keyboard layout used by SDL is the same as the one the kernel uses. To configure the layout on Raspbian:
sudo dpkg-reconfigure keyboard-configuration
To configure the locale, which controls which keys are interpreted as letters, this determining the CAPS LOCK behavior:
sudo dpkg-reconfigure locales
If you have desktop OpenGL headers installed at build time in your RPi or cross compilation environment, support for it will be built in. However, the chipset does not actually have support for it, which causes issues in certain SDL apps since the presence of OpenGL support supersedes the ES/ES2 variants. The workaround is to disable OpenGL at configuration time:
./configure --disable-video-opengl
Or if the application uses the Render functions, you can use the SDL_RENDER_DRIVER environment variable:
export SDL_RENDER_DRIVER=opengles2