Start > Algorithmik > Labyrinthe und Irrgärten > labgen > Fehlerhafte Paketierung von Glut

Fehlerhafte Paketierung von Glut

Seit dem FreeGlut-Paket 3.4.0 findet labgen die Glut-Laufzeitbibliothek nicht mehr:

$ labgen
labgen: error while loading shared libraries: libglut.so.3: cannot open shared
object file: No such file or directory

Auch andere haben scheinbar dieses Problem:

Der dynamische Linker findet libglut.so.3 nicht mehr. Kein Wunder, eine solche Datei existiert im aktuellen Paket auch nicht mehr:

$ ldd labgen
linux-vdso.so.1 (0x00007fff5a190000)
libglut.so.3 => not found
libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007f9d7a73c000)
libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007f9d7a48a000)
libGLX.so.0 => /lib/x86_64-linux-gnu/libGLX.so.0 (0x00007f9d7a457000)...

libglut.so.3 existierte noch unter dem Vorgängerpaket im üblichen Bibliothekspfad als Symlink auf libglut.so.3.9.0:

$ ls -la libglut*
lrwxrwxrwx 2 root root     16 Mai  9  2020 libglut.so.3 -> libglut.so.3.9.0
-rw-r--r-- 2 root root 311296 Mai  9  2020 libglut.so.3.9.0

Jetzt gibt es stattdessen eine libglut.so.3.12.0 und einen Symlink libglut.so.3.12 darauf:

$ ls -la libglut*
lrwxrwxrwx 1 root root     17 Apr 18  2024 libglut.so.3.12 -> libglut.so.3.12.0
-rw-r--r-- 1 root root 343872 Apr 18  2024 libglut.so.3.12.0

Da der dynamische Linker beim Erstellen von labgen aber gegen das interne SONAME-Feld libglut.so.3 der damals vorliegenden Bibliothek libglut.so.3.9.0 gelinkt hatte, braucht labgen auch unter dem neuen Paket immer noch libglut.so.3. Ein SymLink libglut.so.3, der auf libglut.so.3.12 zeigt, würde helfen, wurde aber durch das Paket nicht erstellt.

Ein zweites Problem ist der Wert libglut.so.3.12 des SONAME-Feldes der aktuellen Glut-Bibliothek, welches nicht dem Standard­namens­schema (nur Hauptversion im SONAME-Feld, s. Man Pages: Shared Libraries) entspricht:

$ objdump -p /usr/lib/x86_64-linux-gnu/lib[gG][lL]*.so | grep SONAME
SONAME  libGL.so.1
SONAME  libGLU.so.1
SONAME  libglut.so.3.12
SONAME  libGLX.so.0

Es gibt dieses Schema aus einem guten Grund: Solange nämlich die FreeGlut-Entwickler im Quellkode die bestehenden Funktions­aufrufe nicht ändern, sondern nur interne Änderungen oder Optimierungen vornehmen, sollte nur die Unter­versions­nummer angehoben werden und somit laufen alle Programme, die freeglut brauchen, unverändert weiter; sie müssen nicht neu kompiliert werden, s. a. Redhat - Creating C or C++ Applications:

A library foo version X.Y is ABI-compatible with other versions with the same value of X in the version number. Minor changes preserving compatibility increase the number Y. Major changes that break compatibility increase the number X.

Da sich nun aber auf einmal auch die Unterversionsnummer im SONAME-Feld findet, müßte ab sofort labgen (und jedes andere Programm) bei jedem Anheben der Unterversionsnummer von libglut rekompiliert werden.

Woher stammt der Bruch mit ABI-Kompatibilität und Namens­schema?

In der originalen, mit cmake verwalteten FreeGlut-Distribution findet sich folgender Code:

IF(FREEGLUT_BUILD_SHARED_LIBS)
  SET_TARGET_PROPERTIES(freeglut PROPERTIES VERSION ${SO_MAJOR}.${SO_MINOR}.${SO_REV}
  SOVERSION ${SO_MAJOR} OUTPUT_NAME ${LIBNAME})
ENDIF()
IF(FREEGLUT_BUILD_STATIC_LIBS)
  SET_TARGET_PROPERTIES(freeglut_static PROPERTIES OUTPUT_NAME ${LIBNAME})
ENDIF()

Wie man sieht, enthält er die Anweisung, ins interne SONAME-Feld nur die Hauptversion zu setzen, was korrekt ist. Die offizielle Quelle (upstream) ist also sauber.

Die nächste mögliche Fehlerquelle bilden die Paket­betreuung der Linux-Distros. Da Software zuerst durch Debian pakettiert und in Folge durch Ubuntu und Mint (ggf. mit kleinen Änderungen) übernommen wird, kann sich ein Fehler ab da (downstream) durchziehen. Schauen wir uns zunächst die Änderungen im Debian-Repo an:

File: 20_update_soversion.cmake
file content (17 lines) | stat: -rw-r--r-- 775 bytes
Description: Expand so-version to 3.11
...
Last-Update: 2021-08-18

Index: freeglut-3.4.0/CMakeLists.txt
===================================================================
--- freeglut-3.4.0.orig/CMakeLists.txt
+++ freeglut-3.4.0/CMakeLists.txt
@@ -475,7 +475,7 @@ ELSE()
     ENDIF()

 IF(FREEGLUT_BUILD_SHARED_LIBS)
-  SET_TARGET_PROPERTIES(freeglut PROPERTIES VERSION ${SO_MAJOR}.${SO_MINOR}.${SO_REV}
   SOVERSION ${SO_MAJOR} OUTPUT_NAME ${LIBNAME})
+  SET_TARGET_PROPERTIES(freeglut PROPERTIES VERSION ${SO_MAJOR}.${SO_MINOR}.${SO_REV}
   SOVERSION ${SO_MAJOR}.${SO_MINOR} OUTPUT_NAME ${LIBNAME})
 ENDIF()
 IF(FREEGLUT_BUILD_STATIC_LIBS)
   SET_TARGET_PROPERTIES(freeglut_static PROPERTIES OUTPUT_NAME ${LIBNAME})

Und hier werden wir schon fündig: Durch die Debian-Paketbetreuung wurde cmake angewiesen, neben der Haupt- auch die Unterversionsnummer in die dynamische Glut-Bibliothek einzutragen. Dies führt zum Bruch der ABI-Kompatibilität und steht auch im Widerspruch zu Debians eigener Namenskonvention für dynamische Bibliotheken. Der Fehler wurde downstream auch nicht korrigiert; er zieht sich also durch bis Linux Mint!

Das Woher ist damit beantwortet. Der Bug wurde gemeldet und die Paket­betreuung hat ihn im (noch unveröffentlichtem) Debian 13 (Trixie) behoben.

Bis das ausgerollt wird, gibt es folgende mögliche Notbehelfe (dazu wurde labgen/1.3.1 so gepatcht, daß es wieder von einer libglut-Bibliothek mit dem SONAME-Feld libglut.so.3 abhängt, um auch auf etwas älteren Systemen lauffähig zu bleiben):

  1. Im Bibliotheksverzeichnis einen SymLink libglut.so.3 auf libglut.so.3.12 anlegen:
    $ cd /usr/lib/x86_64-linux-gnu
    $ sudo ln -s libglut.so.3.12 libglut.so.3
    Nachteil: Bei jeder Anhebung der Unterversion oder bei Systemupgrades muß dieser Link angepaßt werden:
    $ sudo ln -s libglut.so.3.13 libglut.so.3
    $ sudo ln -s libglut.so.3.14 libglut.so.3
    $ sudo ln -s libglut.so.3.15 libglut.so.3
    ...
  2. Soll die Bibliothek auch System-Upgrades überleben, empfiehlt sich statt­dessen die Installation der Bibliothek in das upgrade-sichere Verzeichnis /usr/local/lib/x86_64-linux-gnu/ (das Verzeichnis sollte in /etc/ld.so.conf.d/x86_64-linux-gnu.conf bereits gesetzt sein; wenn nicht, ist es einzutragen. Alternativ kann labgen mit LD_LIBRARY_PATH=/usr/local/lib labgen gestartet werden).
  3. Debians altes Paket umgehen und FreeGlut direkt von der sauberen Quelle (GitHub oder Sourceforge) herunterladen und kompilieren.
  4. Debians korrigiertes Paket aus Trixie installieren.
© 2024, 2025 asdala.de: Kon­takt & Daten­obhut