Compilation et installation de DRL (Linux x86-64)
Ce document récapitule toutes les étapes suivies pour configurer, compiler et faire tourner DRL (« That Trademark », the Roguelike) sur cette machine Linux x86-64, y compris le mode graphique (TILES). Environnement de référence : Ubuntu 22.04, FPC 3.2.2, Lua 5.1.5.
Code source : https://github.com/HackTechDev/DoomRoguelike_2608
1. Prérequis déjà présents sur la machine
- FreePascal
fpc3.2.2 (/usr/bin/fpc) - Lua 5.1
lua5.15.1.5 (/usr/bin/lua5.1) - Outils X11 dev (
libx11-dev,libxext-dev,libxrandr-dev,libxcursor-dev,libxi-dev,libxfixes-dev,libxss-dev),libgl1-mesa-dev,cmake,ninja-build,pkg-config(utilisés plus tard pour compiler SDL3)
Aucune installation apt n'a été nécessaire (tout était déjà présent sur la machine, y compris
les paquets -dev X11/GL utilisés pour la partie 5).
2. Dépendance obligatoire : fpcvalkyrie
DRL a besoin du moteur bas niveau fpcvalkyrie, un dépôt frère qui n'était pas présent au
départ. Cloné à côté du dépôt drl :
cd /home/util01/JEUX/DOOM/DOOMRL
git clone --branch master https://github.com/ChaosForge/fpcvalkyrie.git
Résultat : /home/util01/JEUX/DOOM/DOOMRL/fpcvalkyrie/.
3. Configuration du build (config.lua)
makefile.lua (à la racine de drl/) charge un fichier config.lua gitignoré, à créer à partir
du template Linux fourni :
cd /home/util01/JEUX/DOOM/DOOMRL/drl
cp config-linux.lua config.lua
Le chemin par défaut du template pointait vers une machine tierce (/home/epyon/...), corrigé
pour pointer vers le checkout réel de fpcvalkyrie :
-- config.lua
VALKYRIE_ROOT = "/home/util01/JEUX/DOOM/DOOMRL/fpcvalkyrie/"
OS = "LINUX"
4. Compilation du jeu
Le build est piloté par lua5.1 makefile.lua <cible>, qui wrap le compilateur FPC (via
fpcvalkyrie/scripts/lua_make.lua) et compile aussi l'outil makewad qui empaquette les règles
Lua + assets dans des fichiers .wad.
cd /home/util01/JEUX/DOOM/DOOMRL/drl
mkdir -p tmp pkg
lua5.1 makefile.lua lq
Cette commande :
- régénère
src/version.inc(version + révision git) via le hookpre_build, - compile
bin/drl(exécutable du jeu) etbin/makewad, - exécute
makewadpour générerbin/drl.wadetbin/core.wadà partir debin/data/**/*.lua, - tente d'empaqueter une release complète (
drl-linux-01010-lq.tar.gz) — cette dernière étape a émis deuxcpen échec (bin/data/drllq/sound/*.wav,bin/data/drllq/music/*.mid), car les assets audio sont volontairement absents du dépôt (gitignorés, normalement téléchargés depuisdrl.chaosforge.orgen CI, cf..github/workflows/ci.yml). Sans incidence sur la compilation : l'exécutable et les.wadsont bien produits, et le tarball est quand même généré.
Résultat : bin/drl (exécutable x86-64), bin/makewad, bin/drl.wad, bin/core.wad,
drl-linux-01010-lq.tar.gz.
5. Vérification en mode console
Test initial en mode texte (curses), plus simple car il ne dépend pas de SDL3 :
cd bin
LD_LIBRARY_PATH=. ./drl -console -nosound -god
Le runtime.log a confirmé un démarrage complet et sans erreur : chargement des modules
(core.wad, drl.wad), interprétation de tous les fichiers Lua de règles (beings.lua,
items.lua, ai.lua, etc.), initialisation du driver curses. Le jeu attend ensuite une entrée
clavier interactive (normal, aucun crash).
-nosound a été utilisé ici car, à ce stade, ni libSDL3.so (mauvaise architecture, voir partie 6)
ni SDL3_mixer (absent du dépôt, voir partie 7) n'étaient encore fonctionnels — sans ce flag,
l'initialisation audio provoquait un crash. Ce n'est plus nécessaire une fois les parties 6 à 8
appliquées (voir partie 9).
6. Mode graphique (TILES) : diagnostic du crash
Lancer ./drl -god -nosound (mode graphique, sans le flag -console) plantait immédiatement
avec EAccessViolation. Le message d'erreur (error.log) pointait vers un crash secondaire dans
la routine de nettoyage de fpcvalkyrie (vio.pas / vgenerics.pas), qui masquait la vraie cause.
Root cause trouvée avec gdb
En posant un breakpoint sur le symbole FPC_RAISEEXCEPTION (le point d'entrée du mécanisme
d'exceptions Object Pascal), la première exception réellement levée s'est révélée être :
LOAD (vlibrary.pas:68) : Can't load library "libSDL3.so.0.4.0"
C'est un échec de dlopen(). Vérification du fichier fourni dans le dépôt :
file ext/linux/libSDL3.so.0.4.0
# ELF 64-bit LSB shared object, ARM aarch64, ...
file ext/linux/libSDL3_image.so.0.4.0
# ELF 64-bit LSB shared object, ARM aarch64, ...
Cause du bug : les bibliothèques libSDL3.so.0.4.0 et libSDL3_image.so.0.4.0 vendues dans
ext/linux/ du dépôt sont compilées pour ARM64, alors que la machine est en x86-64.
dlopen() échoue silencieusement (mauvaise architecture ELF), ce qui déclenche une exception
Pascal ; le nettoyage automatique de l'objet partiellement construit crashe ensuite à son tour
(bug distinct dans fpcvalkyrie), ce qui masquait le vrai message d'erreur.
(libfmod.so et libsteam_api.so dans le même dossier sont, eux, bien en x86-64.)
7. Compilation de SDL3, SDL3_image et SDL3_mixer depuis les sources (x86-64)
Pas de paquet SDL3 disponible via apt sur Ubuntu 22.04 (trop récent), et pas de build x86-64
vendored dans le dépôt. Compilation depuis les sources officielles libsdl-org.
Version requise : SDL3_mixer exige SDL3 >= 3.4.0 (find_package échoue sinon). C'est
d'ailleurs exactement la branche que fpcvalkyrie attend : le nom de fichier littéral codé en dur
(libSDL3.so.0.4.0, voir plus bas) correspond au soname réel d'un build SDL 3.4.x
(libSDL3.so.0.4.14 pour la version utilisée ici), pas 3.2.x.
mkdir -p /tmp/.../scratchpad/sdl-build && cd /tmp/.../scratchpad/sdl-build
git clone --depth 1 --branch release-3.4.14 https://github.com/libsdl-org/SDL.git
git clone --depth 1 --branch release-3.2.4 https://github.com/libsdl-org/SDL_image.git
git clone --depth 1 --branch release-3.2.4 https://github.com/libsdl-org/SDL_mixer.git
# SDL3
cmake -S SDL -B build-sdl -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DSDL_SHARED=ON -DSDL_STATIC=OFF -DSDL_TEST_LIBRARY=OFF
ninja -C build-sdl -j$(nproc)
# -> build-sdl/libSDL3.so.0.4.14
# SDL3_image (lié contre le SDL3 fraîchement construit)
cmake -S SDL_image -B build-sdlimage -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=ON -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_TESTS=OFF \
-DCMAKE_PREFIX_PATH="$PWD/build-sdl" -DSDL3_DIR="$PWD/build-sdl"
ninja -C build-sdlimage -j$(nproc)
# -> build-sdlimage/libSDL3_image.so.0.2.4
# SDL3_mixer : nos assets sont uniquement .wav/.mid, donc seuls wave+midi(timidity)
# +aiff/voc/au sont activés. Ça évite aussi d'avoir besoin des sous-modules git
# vendored de SDL_mixer (ogg/vorbis/opus/flac/mpg123/gme/xmp/wavpack), qu'un
# `git clone --depth 1` ne récupère pas.
cmake -S SDL_mixer -B build-sdlmixer -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \
-DSDLMIXER_VENDORED=ON -DSDLMIXER_DEPS_SHARED=OFF \
-DSDLMIXER_FLAC=OFF -DSDLMIXER_GME=OFF -DSDLMIXER_MOD=OFF -DSDLMIXER_MP3=OFF \
-DSDLMIXER_OPUS=OFF -DSDLMIXER_VORBIS_STB=OFF -DSDLMIXER_VORBIS_VORBISFILE=OFF \
-DSDLMIXER_WAVPACK=OFF -DSDLMIXER_MIDI=ON -DSDLMIXER_WAVE=ON \
-DSDLMIXER_TESTS=OFF -DSDLMIXER_EXAMPLES=OFF -DSDLMIXER_INSTALL=OFF \
-DCMAKE_PREFIX_PATH="$PWD/build-sdl" -DSDL3_DIR="$PWD/build-sdl"
ninja -C build-sdlmixer -j$(nproc)
# -> build-sdlmixer/libSDL3_mixer.so.0.2.4
Les trois builds ont réussi sans dépendance manquante (X11/GLX/mesa déjà présents ; libtiff/libwebp système détectés automatiquement pour SDL3_image, les autres formats en mode vendored/stb).
Installation dans bin/
Le nom de fichier exact est important : le code Pascal (vsdl3library.pas /
vsdl3imagelibrary.pas / vsdl3mixerlibrary.pas) fait dlopen() sur des noms littéraux
(libSDL3.so.0.4.0, libSDL3_image.so.0.4.0, libSDL3_mixer-3.0.so.0), peu importe le vrai
soname produit par le build :
cp build-sdl/libSDL3.so.0.4.14 bin/libSDL3.so.0.4.0
cp build-sdlimage/libSDL3_image.so.0.2.4 bin/libSDL3_image.so.0.4.0
cp build-sdlmixer/libSDL3_mixer.so.0.2.4 bin/libSDL3_mixer-3.0.so.0
file confirme des binaires ELF x86-64 valides, et ldd ne montre plus aucune dépendance
manquante.
Deux bugs trouvés dans fpcvalkyrie (branches master et development)
Même avec la bonne lib installée, SDL3_mixer refusait toujours de charger. Diagnostic via
gdb (breakpoint sur FPC_RAISEEXCEPTION, qui intercepte la première exception Pascal réellement
levée, avant que le bug de nettoyage-après-échec-de-constructeur ne la masque) :
-
Symboles inexistants dans les bindings —
libs/vsdl3mixerlibrary.pasréférenceMIX_TrackLoopingetMIX_SetMasterGain/MIX_GetMasterGain, qui n'ont jamais existé sous ces noms dans aucune version deSDL3_mixer(vérifié viagit log -Ssur tout l'historique du dépôtSDL_mixer). Les vrais noms sontMIX_GetTrackLoopsetMIX_SetMixerGain/MIX_GetMixerGain. CommeGetSymbol()lève une exception fatale au moindre symbole manquant (et qu'aucun de ces trois bindings n'est utilisé ailleurs dansfpcvalkyrie), ce simple mismatch de nom empêchaitSDL3_mixerde se charger, quelle que soit la version installée. → un audit de tous les symboles attendus (extraits par regex depuis le fichier) contre le header réel deSDL_mixera confirmé que ces deux paires étaient les seules incohérences. -
SDL3(la lib de base) jamais chargée en mode audio seul —src/vsdlaudio.pas(TSDLAudio.Create) appelleLoadSDL3Mixermais jamaisLoadSDL3. En mode graphique ça fonctionnait "par accident" car le driver vidéo (TSDLIODriver) avait déjà appeléLoadSDL3avant que l'audio ne s'initialise. En mode-console(pas de driver vidéo),SDL_Initrestait un pointeur de fonction nul →EAccessViolationà l'adresse0x0.
Correctifs appliqués (dans le checkout ../fpcvalkyrie, pas dans le dépôt drl) :
# libs/vsdl3mixerlibrary.pas
- MIX_TrackLooping : function(track: PMIX_Track): Boolean; cdecl;
+ MIX_GetTrackLoops : function(track: PMIX_Track): Integer; cdecl;
- Pointer(MIX_TrackLooping) := GetSymbol('MIX_TrackLooping');
+ Pointer(MIX_GetTrackLoops) := GetSymbol('MIX_GetTrackLoops');
- MIX_SetMasterGain : function(mixer: PMIX_Mixer; gain: Single): Boolean; cdecl;
- MIX_GetMasterGain : function(mixer: PMIX_Mixer): Single; cdecl;
+ MIX_SetMixerGain : function(mixer: PMIX_Mixer; gain: Single): Boolean; cdecl;
+ MIX_GetMixerGain : function(mixer: PMIX_Mixer): Single; cdecl;
- Pointer(MIX_SetMasterGain) := GetSymbol('MIX_SetMasterGain');
- Pointer(MIX_GetMasterGain) := GetSymbol('MIX_GetMasterGain');
+ Pointer(MIX_SetMixerGain) := GetSymbol('MIX_SetMixerGain');
+ Pointer(MIX_GetMixerGain) := GetSymbol('MIX_GetMixerGain');
# src/vsdlaudio.pas (TSDLAudio.Create)
inherited Create;
+ if not LoadSDL3 then
+ raise EAudioException.Create('Unable to load SDL3');
if not LoadSDL3Mixer then
raise EAudioException.Create('Unable to load SDL3_mixer');
Après ces deux correctifs et un rebuild (lua5.1 makefile.lua lq), TSDLAudio s'initialise
proprement (<TSDLAudio//0> Initialized.) aussi bien en -console qu'en mode graphique, sans
crash à la fermeture non plus.
8. Téléchargement des assets audio
Les fichiers .wav/.mid sont gitignorés (absents du dépôt) et normalement récupérés en CI
depuis drl.chaosforge.org (voir .github/workflows/ci.yml). Même procédure ici :
mkdir -p bin/data/drllq/music bin/data/drllq/sound
curl -skfL https://drl.chaosforge.org/music_lq.zip -o music_lq.zip
curl -skfL https://drl.chaosforge.org/sound_lq.zip -o sound_lq.zip
unzip -oq music_lq.zip -d bin/data/drllq/music/
unzip -oq sound_lq.zip -d bin/data/drllq/sound/
Le -k (insecure) est nécessaire car le certificat TLS de drl.chaosforge.org ne valide pas
(problème côté serveur, pas un souci de confiance local) — la CI officielle du projet contourne le
même souci en pratique. Les zips (music_lq.zip, sound_lq.zip, et leurs équivalents _hq) ont
été vérifiés avec unzip -tq avant extraction.
9. Lancement en mode graphique (avec son) et capture d'écran
cd bin
DISPLAY=:0 LD_LIBRARY_PATH=. ./drl -god
Le runtime.log progresse cette fois normalement jusqu'à <TSDLIODriver> SDL IO system ready.,
une fenêtre "DRL" s'ouvre (1920×1200), sans aucune entrée dans error.log. Capture réalisée via :
wmctrl -lG # récupérer l'ID de la fenêtre DRL
import -window <id_fenetre> screenshot.png
Résultat : le menu principal du jeu s'affiche correctement (logo DRL, artwork, menu New
game / Challenge game / Settings / etc.), confirmant que le rendu graphique (SDL3 + OpenGL) et le
son (<TSDLAudio//0> Initialized., aucune entrée dans error.log) fonctionnent pleinement une
fois les bonnes bibliothèques en place et les correctifs fpcvalkyrie appliqués.
10. Script d'automatisation
Toutes les étapes ci-dessus (hors diagnostic) sont scriptées dans build_install.sh, à la racine
du dépôt : clonage de fpcvalkyrie, application des deux correctifs SDL3_mixer, génération de
config.lua, compilation du jeu, build de SDL3/SDL3_image/SDL3_mixer si les libs vendored ne
correspondent pas à l'architecture hôte, et téléchargement des assets audio. Idempotent (relançable
sans dupliquer le travail déjà fait).
./build_install.sh [lq|hq|all] # cible de build, lq par défaut
./build_install.sh --skip-sdl # ne pas (re)vérifier/compiler SDL3/SDL3_image/SDL3_mixer
./build_install.sh --skip-audio # ne pas télécharger les assets audio
Résumé des fichiers modifiés / créés (hors dépôt git ou gitignorés)
| Fichier | Rôle |
|---|---|
../fpcvalkyrie/ (dépôt cloné) |
Dépendance moteur obligatoire |
../fpcvalkyrie/libs/vsdl3mixerlibrary.pas, ../fpcvalkyrie/src/vsdlaudio.pas |
Patchés (bugs de bindings SDL3_mixer, voir partie 7) |
config.lua |
Config du build (chemin vers fpcvalkyrie, OS) |
bin/config.lua |
SoundEngine laissé à "DEFAULT" (= SDL sur Linux, fonctionne maintenant) |
src/version.inc |
Autogénéré par le build (version + révision git) |
bin/drl, bin/makewad, bin/*.wad |
Sorties de compilation |
bin/libSDL3.so.0.4.0, bin/libSDL3_image.so.0.4.0, bin/libSDL3_mixer-3.0.so.0 |
Builds x86-64 (les .so vendored ext/linux/ correspondants sont en ARM64 ou absents) |
bin/data/drllq/{music,sound}/* |
Assets audio téléchargés (gitignorés, absents du dépôt) |
drl-linux-01010-lq.tar.gz |
Package packagé par makefile.lua lq |
build_install.sh |
Script qui automatise tout ce qui précède |
11. Captures d'écran