FreeBSD : Installation de UFO : Alien Invasion

I/ UFO : Alien Invasion.

Code source :

https://github.com/HackTechDev/UFOAI4FreeBSD

Captures d'écran.

ufoai01.png

ufoai02.png

Portage FreeBSD 15.0 / Clang — résumé

Ce document résume le travail effectué pour faire compiler et fonctionner UFO: Alien Invasion sur FreeBSD 15.0 (amd64) avec la chaîne d'outils Clang 19 / libc++ fournie par le système, alors que le projet n'avait jusqu'ici été testé qu'avec GCC/glibc sous Linux.

Pour le détail technique complet de chaque diagnostic (messages d'erreur exacts, pistes explorées et abandonnées, extraits de code), voir ANALYSE.md. Ce fichier-ci n'en est qu'une vue d'ensemble.

Résultat

  • ufo, ufoded, ufo2map, ufomodel, ufoslicer, uforadiant et game.so compilent et s'exécutent sans erreur ni plantage.
  • Une partie complète (Skirmish, carte assemblée aléatoirement ou fixe) se joue sans crash.
  • uforadiant (l'éditeur de cartes) démarre, charge une carte et se ferme proprement.

1. Mettre en place la compilation

Problème Cause Correctif
./configure ne trouve pas jpeglib.h/xvid.h alors que les paquets sont installés cc ne cherche pas dans /usr/local/include par défaut sur FreeBSD Lancer configure avec CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib"
make échoue avec des erreurs de syntaxe dès la ligne 4 du Makefile make = BSD make sur FreeBSD, le projet utilise la syntaxe GNU Make Utiliser gmake (déjà installé) à la place de make
Cible testall désactivée Bibliothèque cunit absente pkg install cunit si les tests unitaires sont voulus (non fait, hors périmètre)

Configuration retenue :

CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" ./configure --enable-release --enable-ufo2map
gmake

2. Faire compiler le C++ existant avec Clang

Le code visait historiquement GCC ; Clang est plus strict sur plusieurs points du C++ moderne, révélant des soucis de code jusqu'ici jamais rencontrés :

Symptôme Cause Fichiers corrigés
ISO C++17 does not allow 'register' Mot-clé retiré du C++17, jamais mis à jour dans ce code hérité shared.cpp, r_font.cpp, WildcardMatcher.h, md5.cpp, hashfunc.h
constant expression ... cannot be narrowed to type 'int' Décalage de bit (1<<31) en dépassement de signe dans une liste d'initialisation cl_particle.cpp (PTL_ONLY_ONE_TYPE)
case value ... cannot be narrowed to type 'GLenum' Sentinelles négatives utilisées comme case d'un switch sur un type non signé r_gl.h (GL_TANGENT_ARRAY et consorts)
member access into incomplete type 'mxml_node_t' Accès direct à une structure interne rendue opaque dans mxml 3.x (vs 2.x) xml.cpp
ISO C++17 does not allow dynamic exception specifications Syntaxe throw(Type) supprimée en C++17 UMPFile.h, UMPFile.cpp
no viable overloaded '=' sur un std::map std::map<const Key, T> (const redondant) toléré par libstdc++, refusé par libc++ (FreeBSD) 9 fichiers de src/tools/radiant/
Édition de lien : undefined symbol: backtrace backtrace()/backtrace_symbols_fd() vivent dans libexecinfo sur FreeBSD, pas dans la libc comme sous Linux -lexecinfo ajouté pour ufo, ufoded, ufo2map, ufomodel, ufoslicer, testall
use of undeclared identifier 'WNOHANG'/'waitpid' <sys/wait.h> inclus pour Linux mais pas pour FreeBSD/OpenBSD exec.cpp (uforadiant)

3. Bugs révélés uniquement à l'exécution

Deux bugs réels du code, présents indépendamment du portage, ne se sont manifestés qu'avec Clang/FreeBSD :

  • Crash en jeu (SIGSEGV, tour de l'équipe du joueur)Inventory::holdsReactionFireWeapon() appelait une méthode sur un pointeur potentiellement nul, en s'appuyant sur un if (!this) return nullptr; interne. C'est un comportement indéfini en C++ (la norme garantit que this n'est jamais nul) : Clang -O2 supprime ce test, GCC ne le fait pas — d'où le crash uniquement ici. Corrigé en vérifiant la nullité côté appelant (inv_shared.cpp).

  • Crash au démarrage d'uforadiant — le rendu de texte OpenGL s'appuyait sur GtkGLExt + l'API PangoX abandonnée, incompatible avec le Pango moderne (HarfBuzz obligatoire depuis Pango 1.44) installé par les ports FreeBSD : saut à travers un pointeur de fonction nul. Remplacé par un rendu via PangoCairo vers une texture OpenGL (glfont.h/.cpp, igl.h, mainframe.cpp).

  • Crash à la fermeture d'uforadiant (SIGBUS)TextPanel::~TextPanel() déréférençait un widget GTK déjà détruit par GTK lui-même pendant l'arrêt du programme (use-after-free classique d'ordre de destruction). Corrigé en s'abonnant au signal "destroy" du widget, comme le fait déjà le reste du code pour ce genre de cas (TextPanel.h/.cpp).

Pour aller plus loin

  • Diagnostic complet, messages d'erreur et pistes explorées : ANALYSE.md
  • Historique détaillé des correctifs : git log sur la branche ufoai250 (18 commits, du diagnostic des dépendances jusqu'au dernier correctif uforadiant)
  • Conventions et architecture du projet : CLAUDE.md