• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

libtool linkt Bibliotheken aus dem falschen Verzeichnis

Hallo,

ich will hier gerade eine Anwendung kompilieren, die eine bestimmte Bibliothek enthält, welche zusätzlich auch schon systemweit installiert ist. Am besten sieht man das Problem direkt an der Kommandozeile, ausnahmsweise nicht als Code formatiert wegen Fettschrift:

*******
/bin/sh ../../libtool --tag=CXX --mode=link g++ -D_REENTRANT -DNOCONTROLS -fexceptions -Wall -Wno-char-subscripts -Woverloaded-virtual -Wno-unknown-pragmas -Wno-deprecated -Wformat=2 -Wpointer-arith -Wsign-compare -O2 -g -march=i586 -mtune=i686 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -DUSE_MMX -DMPEG4IP -I/usr/include/SDL -D_REENTRANT -o mp4live audio_encoder.o audio_encoder_tables.o video_encoder.o video_encoder_tables.o mp4live.o -L/usr/X11R6/lib -L/opt/gnome/lib -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -lfreetype -lfontconfig -lXrender -lX11 -lXext -lpng12 -lz -lglitz -lm -L/opt/gnome/lib -lglib-2.0 -lfaac -lmp3lame ./h261/libmp4live_h261.la gui/libmp4livegui.la libmp4live.la ../../lib/mpeg2ps/libmpeg2_program.la ../../lib/msg_queue/libmsg_queue.la ../../lib/mp4v2/libmp4v2.la ../../lib/mp4av/libmp4av.la ../../lib/rtp/libuclmmbase.la ../../lib/sdp/libsdp.la ../../lib/gnu/libmpeg4ip_gnu.la ../../lib/utils/libutils.la -lpthread -L/usr/lib -lSDL -lpthread libmp4livepreview.la -lavcodec -lz -lavutil -lvorbis -lvorbisenc -lfaad -lxvidcore -lx264 -ldl
*******

libtool macht daraus folgendes:

*******
g++ -D_REENTRANT -DNOCONTROLS -fexceptions -Wall -Wno-char-subscripts -Woverloaded-virtual -Wno-unknown-pragmas -Wno-deprecated -Wformat=2 -Wpointer-arith -Wsign-compare -O2 -g -march=i586 -mtune=i686 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -DUSE_MMX -DMPEG4IP -I/usr/include/SDL -D_REENTRANT -o mp4live audio_encoder.o audio_encoder_tables.o video_encoder.o video_encoder_tables.o mp4live.o -L/usr/X11R6/lib -L/opt/gnome/lib /opt/gnome/lib/libgtk-x11-2.0.so /opt/gnome/lib/libgdk-x11-2.0.so /opt/gnome/lib/libatk-1.0.so /opt/gnome/lib/libgdk_pixbuf-2.0.so /opt/gnome/lib/libpangocairo-1.0.so /opt/gnome/lib/libpangoft2-1.0.so /opt/gnome/lib/libpango-1.0.so /usr/lib/libcairo.so /opt/gnome/lib/libgobject-2.0.so /opt/gnome/lib/libgmodule-2.0.so /usr/lib/libfontconfig.so /usr/lib/libfreetype.so /usr/lib/libexpat.so -lXrender -lpng12 /usr/lib/libglitz.so /opt/gnome/lib/libglib-2.0.so /usr/lib/libfaac.so /usr/lib/libmp4v2.so /usr/lib/libmp3lame.so ./h261/.libs/libmp4live_h261.a gui/.libs/libmp4livegui.a ./.libs/libmp4live.a ../../lib/mpeg2ps/.libs/libmpeg2_program.a ../../lib/msg_queue/.libs/libmsg_queue.a ../../lib/mp4v2/.libs/libmp4v2.a ../../lib/mp4av/.libs/libmp4av.a ../../lib/rtp/.libs/libuclmmbase.a ../../lib/sdp/.libs/libsdp.a ../../lib/gnu/.libs/libmpeg4ip_gnu.a ../../lib/utils/.libs/libutils.a -L/usr/lib /usr/lib/libSDL.so -lXext /usr/lib/libaa.so -lslang -lX11 -lgpm -lpthread ./.libs/libmp4livepreview.a /usr/lib/libstdc++.so -lc -lgcc_s -lavcodec -lz -lavutil /usr/lib/libvorbisenc.so /usr/lib/libvorbis.so /usr/lib/libogg.so -lm /usr/lib/libfaad.so -lxvidcore -lx264 -ldl
*******

Um das Problem in Worten zu beschreiben: Das zu kompilierende Programm braucht die libmp4v2 und die libfaac. Die libfaac soll aus /usr/lib genommen werden, die libmp4v2 soll jedoch nicht aus /usr/lib genommen werden, weil sie im Paket schon enthalten ist.

Genau so sieht die Kommandozeile auch aus: "-lfaac" => wird aus dem Systemverzeichnis genommen; "../../lib/mp4v2/libmp4v2.la" mit komplettem relativem Pfad => wird aus dem Verzeichnis genommen, wo der Pfad hinzeigt.

Aber leider meint libtool schlauer zu sein und nimmt sich noch eine libmp4v2 dazu, die ich gar nicht bestellt habe, was dazu führt, dass die libmp4v2 gleich doppelt dazugelinkt wird, einmal die dynamische Version aus /usr/lib und einmal die statische Version aus dem Paket selbst. Wie lässt sich dieses Eigenleben abstellen?

PS: Falls die Frage kommen sollte, warum ich statische Bibliotheken nehme: Das muss so sein, weil die beiden Versionen der libmp4v2 inkompatibel sind. Mit dynamischen Bibliotheken habe ich es schon probiert, da steigt er komplett aus. Mit den statischen Bibliotheken bekomme ich zumindest eine ausführbare Datei, die auf den ersten Blick zu funktionieren scheint, aber so ganz geheuer ist mir das mit der doppelt reingelinkten inkompatiblen Bibliothek nicht.

Was ich bisher probiert habe:

- "-L/usr/lib" rausgenommen => keine Auswirkung
- "-L../../lib/mp4v2/.libs" hinzugefügt => keine Auswirkung
- "export LIBRARY_PATH=../../lib/mp4v2/.libs" ausgeführt => keine Auswirkung
- Den von libtool generierten g++-Aufruf von Hand geändert => funktioniert und produziert eine funktionierende ausführbare Datei, will ich aber nicht, weil man das nicht von einem Skript aus machen kann

Was ich bisher nicht probiert habe:

- "/usr/lib/libmp4v2.so" entfernt => Es kann nicht sein, dass ein Programm die Abwesenheit von Bibliotheken erfordert, um erwartungsgemäß zu funktionieren
 

oc2pus

Ultimate Guru
welche libtool Version verwendest du ?
(die 1.5.18 oder die 1.5.20)

evtl hilft dir das weiter:
http://www.delorie.com/gnu/docs/libtool/libtool_17.html
 
OP
T

traffic

Guru
Installiert ist libtool-1.5.18-2.

Der Link hilft leider nicht sonderlich weiter. Die passende Option wäre ja eigentlich diese hier:
`-Llibdir'
Search libdir for required libraries that have already been installed.
Hört sich gut an, tut aber leider nicht das, was ich will bzw. erwarte.

Ich werd's mal hiermit probieren:
`-Wl,flag'
`-Xlinker flag'
Pass a linker specific flag directly to the linker.
Allzu optimistisch bin ich allerdings nicht, weil das Teil die nicht erwünschte Bibliothek mit dem absoluten Pfad hinzufügt. Das kann man nicht so ohne Weiteres durch eine normale Linker-Option wieder loswerden.

Eigentlich bräuchte ich eine Option für libtool, damit die "/usr/lib/libmp4v2.so" gar nicht erst hinzugefügt wird oder zumindest nicht mit dem absoluten Pfad. Die finde ich aber leider nicht in der Dokumentation. Stünde dort stattdessen "-lmp4v2", wäre es wahrscheinlich kein Problem.
 

oc2pus

Ultimate Guru
traffic schrieb:
Installiert ist libtool-1.5.18-2.
ein Versuch wäre es Wert: zieh dir die 1.5.20er Version .. und checke mal

ansonsten scheint das eine "Leiche" im libtool Keller zu sein:
http://www.cygwin.com/ml/cygwin/2003-05/msg00397.html und folgende ....
 
OP
T

traffic

Guru
Also, erst mal vielen Dank für die Hilfe.

Das Problem ist allerdings nicht die DESTDIR-Geschichte. Der DESTDIR-Bug bestand darin, dass libtool die Bibliotheken beim Installieren neu linkt und dafür nicht die Bibliotheken aus DESTDIR, sondern aus dem eigentlichen Dateisystem nimmt. Dieser Bug ist in aktuellen libtool-Versionen gefixt.

Das Problem hier ist aber nicht nicht dieser Bug, sondern eigentlich ein "Feature". libtool linkt nicht nur die explizit angegebenen Bibliotheken, sondern nimmt stillschweigend auch noch alle rekursiven Bibliotheken dazu, was dazu führt, dass alle möglichen Pakete gegen mehr Bibliotheken gelinkt werden, als eigentlich nötig wäre. Das hat nichts mit DESTDIR zu tun, sondern damit, was in der entsprechenden *.la-Datei steht. Hier geht es um die /usr/lib/libfaac.la, da steht folgendes drin:

# Libraries that this one depends upon.
dependency_libs=' /usr/lib/libstdc++.la -lm -lc -lgcc_s /usr/lib/libmp4v2.la /usr/lib/libstdc++.la'

Deswegen fügt er die libmp4v2 aus /usr/lib dazu, weil es in der *.la-Datei drin steht. Das kann ich nicht lösen, ohne die *.la-Datei zu ändern. Aber diese *.la-Datei ändern kann ich auch nicht. Details zu diesem "Feature" von libtool und warum es auf modernen Linux-Systemen nicht hilfreicht, sondern schädlich ist:

http://lists.debian.org/debian-devel-announce/2005/11/msg00016.html

Ohne gepatchtes libtool scheint es im Moment nicht lösbar zu sein, deswegen lasse ich das betroffene Programm jetzt einfach weg. mpeg4ip besteht aus ca. 20 Programmen und dieses mp4live brauche ich nicht => --disable-mp4live, der Rest funktioniert problemlos.
 
Oben