sdlDoc

Dokumentation für SDL2, Mingw, CLion

View on GitHub

Inhaltsverzeichnis

TOC Generator

Nutzung der SDL-Library unter CMake

Jetzt auch auf GitHub Pages: https://zeropointmax.github.io/sdlDoc/

// Maximilian Kerst 12/2019

// Yannis Becker 06/2020

Hinweis:

In diesem Tutorial sind viele Pfade und andere Elemente, die auf verschiedenen Systemen abweichen könnten. Daher sind (hoffentlich) alle Pfade, welche ggf. angepasst werden müssen, kursiv geschrieben oder anderweitig gekennzeichnet. In diesen Fällen appellieren wir an die Aufmerksamkeit des Lesers, sollte etwas nicht mit Copy-Paste aus diesem Tutorial funktionieren.

Sollten wesentliche Teile des Tutorials fehlen / falsch oder unvollständig sein, bitten wir um ein Issue auf GitHub, damit wir eine Lösung finden können.

Viel Spaß und Erfolg :-)

Installieren von SDL2

Wir brauchen die Pakete sdl2 und sdl2_image.

Installation auf Linux:

distributionsspezifisch, sollte aber schon installiert sein.

Beispiele:

sudo pacman -S sdl2 sdl2_image # Arch-Familie
sudo apt install libsdl2-dev libsdl2-2.0-0 libjpeg-dev libwebp-dev libtiff5-dev libsdl2-image-dev libsdl2-image-2.0-0 # Ubuntu-Familie ab 18.04

Installation auf Windows:

Bestimmen der MinGW-Architektur

Die MinGW Architektur kann von der Windows-Architektur abweichen. Das wird für die Installation relevant, da eine falsche Architektur der Pakete nicht funktionieren wird (und man diese anschließend wieder rausfummeln darf).

Einfachster Fall: Windows ist 32 Bit - MinGW ist auch 32 Bit, doh.

Für 64 Bit Windows:

Die erste Zeile der Ausgabe verrät, welche Architektur installiert ist. Beispiel:

gcc.exe (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0 –> hier handelt es sich um ein 64 Bit MinGW

gcc.exe (MinGW.org GCC-8.2.0-5) 8.2.0 –> hier handelt es sich um ein 32 Bit MinGW

Architektur benötigter Unterordner
32 Bit i686
64 Bit x86_64

herunterladen und entpacken

Variante 1: den Inhalt des benötigten Unterordners (siehe oben) so in das MinGW-Installationsverzeichnis entpacken, dass die Ordner bin, lib, include usw. im Archiv mit denen von MinGW verschmelzen.

Variante 2: den Inhalt des benötigten Unterordners (siehe oben) in ein willkürlich gewähltes Verzeichnis entpacken (möglichst kurzer Pfad und ohne Sonderzeichen / Leerzeichen), z.B.: C:\SDL2\. Hier unbedingt den Pfad merken, wir brauchen ihn später wieder. Ebenso entfällt hier die Möglichkeit, SDL2 via FindPkgConfig einzubinden

Welche Variante nehmen?

TL;DR: Empfohlen für Programmier-Übungen in der Gruppe: Variante 1

Einbinden von SDL2 in CMake am Beispiel von CLion

Hinweis: in diesem Abschnitt sollte das Projekt im CLion schon existieren. Sollten automatisch generierte Teile der CMakeLists.txt von den Beispielen unten abweichen, sind die automatisch generierten zu verwenden.

CLion fordert zum Reload der CMakeLists.txt auf, um die Änderungen zu übernehmen. Nach jeder Änderung sollte der Leser dem Nachkommen, da so Fehler in der Datei rechtzeitig bemerkt werden. Des Komforts halber kann auch Auto-Reload aktiviert werden.

Linux

folgenden Block in die CMakeLists.txt einfügen:

INCLUDE(FindPkgConfig)

PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)

INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})

Was passiert hier? Zuerst laden wir “FindPkgConfig” - ein Tool, welches die richtigen Pfade für SDL2 automatisch herzaubert. Dann lassen wir es SDL2 und SDL2_image suchen, was uns die Variablen “SDL2[…]” liefert. Mit INCLUDE_DIRECTORIES und TARGET_LINK_LIBRARIES weisen wir CMake an, dem Linker SDL2 mitzugeben.

die Datei sollte etwa so aussehen:

cmake_minimum_required(VERSION 3.15)
project(sdltest C)

set(CMAKE_C_STANDARD 11)

add_executable(sdltest main.c)

INCLUDE(FindPkgConfig)

PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)

INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})

<a href=https://stackoverflow.com/questions/23850472/how-to-use-sdl2-and-sdl-image-with-cmake>Quelle: Stackoverflow</a>

Weitere Erläuterungen zum CMakeLists.txt:

Zum testen kann man folgenden C-Code ausführen; nicht schön, aber erfüllt seinen Zweck:

#include <stdio.h>
#include <SDL.h>
int main(int argc, char* argv []) {
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        printf("Error initializing SDL!\n");
        return 1;
    }
    SDL_Quit();
    return 0;
}

Wenn der Returncode 0 ist, funktioniert SDL2 :-)

Windows

Windows erfordert etwas mehr Handarbeit. Der Quick-And-Dirty Weg ist, die Pfade direkt einzutragen, dann ist das Projekt jedoch nicht mehr portabel. Je nach Architektur von MinGW (siehe oben) kann man FindPkgConfig nachrüsten. Das ist der empfohlene Weg, da er auf allen kompatiblen Systemen gleich funktioniert und das Projekt portabel bleibt. (besonders gut für Projekte, die man später vielleicht noch brauchen könnte)

MinGW-Architektur verfügbare Methoden
32 Bit - direktes Einbinden
- FindPkgConfig
64 Bit direktes Einbinden

Von den nachfolgenden Methoden ist also eine umzusetzen.

Direkt einbinden

Hinweis: alle set-Zeilen müssen mit dem von der Installation verwendeten Pfad angepasst werden. Sollte SDL2 in die MinGW-Ordnerstruktur integriert worden sein, muss der MinGW-Installationspfad verwendet werden.

Folgenden Block angepasst in die CMakeLists.txt eintragen:

set(SDL2_DIR C:/dev/SDL2)
set(SDL2_LIB_DIR ${SDL2_DIR}/lib)

include_directories(${SDL2_DIR}/include)
target_link_libraries(${PROJECT_NAME} ${SDL2_LIB_DIR}/libSDL2.dll.a ${SDL2_LIB_DIR}/libSDL2main.a)

Was passiert hier? Die set-Zeilen erstellen CMake-Variablen, die den Pfad von SDL2 speichern. Mit INCLUDE_DIRECTORIES und TARGET_LINK_LIBRARIES weisen wir CMake an, dem Linker SDL2 mitzugeben.

Die CMakeLists.txt sollte damit etwa so aussehen:

cmake_minimum_required(VERSION 3.15)
project(sdltest C)

set(CMAKE_C_STANDARD 11)

add_executable(sdltest main.c)

set(SDL2_DIR C:/dev/SDL2)
set(SDL2_LIB_DIR ${SDL2_DIR}/lib)

include_directories(${SDL2_DIR}/include)
target_link_libraries(${PROJECT_NAME} ${SDL2_LIB_DIR}/libSDL2.dll.a ${SDL2_LIB_DIR}/libSDL2main.a)

Entgegen der offiziellen SDL-Doku sollte hier auf die Flag -mwindows verzichtet werden, um Funktionalität für das DOS-Fenster zu erhalten (stdout, …)

Weitere Erläuterungen zum CMakeLists.txt:

mit FindPkgConfig

Voraussetzung: eine installierte 32 Bit MinGW Entwicklungsumgebung

Folgende Pakete sind herunterzuladen:

PkgConfig

GLib

GetText Runtime


Quelle: Stackoverflow

Code zum testen:

#include <stdio.h>
#include <SDL.h> // evtl. #include <SDL2/SDL.h>
int WinMain(int argc, char* argv []) {
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        printf("Error initializing SDL!\n");
        return 1;
    }
    SDL_Quit();
    return 0;
}

zu beachten:

voll-statisch linken

Damit die erzeugten .exe files auch portabel sind, sollte man voll-statisch bauen, d.h. alle benötigten Libraries werden in die fertige .exe gepackt und müssen auf anderen Rechnen nicht im genau gleichen Ordner vorhanden sein.

Um das zu erreichen, muss folgender Block über add_executable eingefügt werden:

link_libraries("-static -lmingw32 -lSDL2main -lSDL2  -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc -lhid -lsetupapi")

Quelle: Prof. Dr. Klaus Kusche

Einbinden von C(++) Quell/-Headerdateien in ein CMake-Projekt am Beispiel von sdlinterf

Die CMakeLists.txt auf einem Linux-System sollte damit wie folgt aussehen (Windows analog):

cmake_minimum_required(VERSION 3.15)
project(sdltest C)

set(CMAKE_C_STANDARD 11)

add_executable(sdltest main.c lib/sdlinterf.c)

INCLUDE(FindPkgConfig)

PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)

INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/include)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})