shared libraries statisch hinzubinden



  • Hallo Zusammen,

    gibt es eine Möglichkeit, eine Anwendung so zu kompilieren, dass sie nach dem Binden keine weiteren Abhängigkeiten mehr besitzt?

    Mein Problem ist folgendes: Ich schreibe zur Zeit eine Applikation, welche auf Graphviz, ImageMagick, die GNU Plotutils und Transfig zur Grafikausgabe zurückgreift. Nun sollen diese Tools am besten mit der Applikation zusammen deployed werden, dass heißt, einfach in einem Unterverzeichnis der App. liegen und von dort aus, ohne weitere Abhängikeiten aufrufbar sein.

    Meine Idee war halt, alles statisch hinzuzubinden, was bisher allerdings noch nicht geklappt hat (gcc -static)

    schlitt@suse:~/test/static_compile> g++ test.cpp -o test_dynamic
    schlitt@suse:~/test/static_compile> g++ test.cpp -static -o test_static
    schlitt@suse:~/test/static_compile> ldd test_dynamic test_static
    test_dynamic:
            linux-gate.so.1 => (0xffffe000) libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40025000)
            libm.so.6 => /lib/tls/libm.so.6 (0x400e2000)
            libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40104000)
            libc.so.6 => /lib/tls/libc.so.6 (0x4010c000)
            /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
    test_static:
            not a dynamic executable
    schlitt@suse:~/test/static_compile>
    

    In diesem - zugegeben trivialen - Falle klappt das wunderbar, so wie ich mir das vorstelle. Weshalb kann ich die genannten Tools nicht auch auf diese Art&Weise kompilieren?

    Oder hat jemand eine andere Idee? Habe bereits in diversen Linuxforen nachgefragt und wurde letztendlich hierher verwiesen 😉

    Danke & Gruß
    Wusel



  • [quote=Wuseldusel]Weshalb kann ich die genannten Tools nicht auch auf diese Art&Weise kompilieren?[/quote]

    ich vermute, dass du auf deinem system die statischen versionen der bibliotheken nicht installiert hast. sag aber bitte trotzdem, wie du erkennst, dass die sache nicht so funktioniert, wie du willst. also z.b. eine fehlermeldung. verwendest du linux und wenn ja, welche distribution?



  • Hi,

    ich selbst verwende Debian Etch (32bit), das Zielsystem wird hauptsächlich ein SUSE Enterprise Server 9 (64bit) sein.

    Versucht habe ich es mit ./configure --enable-static --disable-shared, sowie mit dem Setzen der Compilerflags auf -static

    Fehlermeldungen gibt es keine, ldd spuckt dennoch Abhängigkeiten aus.



  • Du musst schauen ob es von den Bibliotheken, die Du linken möchtest, statische Versionen gibt. Diese haben die Dateiendung .a, liegen aber ansonsten normalerweise neben den shared libraries. Manchmal sind die statischen Bibliotheken erst im -dev Paket (Debian) dabei, manchmal auch garnicht.

    Im letzten Fall kannst Du höchstens noch versuchen, die entsprechende Bibliothek selbst aus dem Quellpaket zu bauen mit --enable-static.

    Oder Du lieferst alle Bibliotheken (inkl. der glibc) als shared library mit Deinem Produkt aus und verbiegst vor dem Programmstart (z.B. in einem Script) LD_LIBRARY_PATH auf die Position der selbst mitgelieferten Libs.



  • solltest du die dynamischen bibliotheken mitliefern wollen, würde sich $ORIGIN als -rpath anbieten:

    (1) gcc test.c -o test '-Wl,-rpath,$ORIGIN/'
    (2) gcc test.c -o test '-Wl,-rpath,$ORIGIN/../lib'
    

    du kannst (1) oder (2) verwenden. du kannst es auch kombinieren, was aber wenig sinn macht. $ORIGIN ist der pfad, in dem die exe liegt. die ' sind nötig, danmit die shell das $ORIGIN nicht als variable interpretiert. in makefiles sollte man wohl das $ mit \ escapen. auf welchen system das funktioniert, weiß ich allerdings nicht. es geht zumindest bei linux. (von solaris hab ich auch gehört, aber es selbst nie ausprobiert.)



  • @Lord:
    Wie würde ich das dann dem Makefile mitteilen, dass er die statischen Bibliotheken benutzen soll, bzw, wo er sie findet?

    @namenlos
    Super, so würde es klappen, habe es zumindest mit 'nem kleinen einzeiler.cpp hinbekommen 😉
    Werde morgen testen, ob ich eines der Tools so kompiliert bekomme. Falls das so klappt, müsste ich nur die ganzen Libraries auf 64bit crosskompilieren und das sind einige 😕 ...



  • deine bemerkung zu cross-compilieren kommt etwas unerwartet. wenn du die bibliotheken statischen verwenden willst, müssen sie ebenso cross-compiliert sein. inklusive der exe datei. entwickelst du auf einem 32 bit system für 64 bit?
    wenn du -static zum aufruf des gcc hinzufügst, verwendet ld automatisch die statischen versionen. sollte keine statische version vorhanden sein, meldet ld, dass es die bibliothek nicht gefunden hat. wohl bei fast allen distributionen befinden sich die statischen versionen im gleichen ordner wie die dynamischen.



  • namenlos schrieb:

    deine bemerkung zu cross-compilieren kommt etwas unerwartet. wenn du die bibliotheken statischen verwenden willst, müssen sie ebenso cross-compiliert sein. inklusive der exe datei. entwickelst du auf einem 32 bit system für 64 bit?

    Ja, leider 😕 Dass ich das statisch gelinkte Executable auch crosskompilieren müsste ist klar. Aber im Falle der dynamisch gelinkten Variante müsste ich halt alle Libraries einzeln kompilieren und ich befürchte, dabei treten bei jeder Library nochmals mindestens 100 neue Probleme auf 😉 Von daher wäre mir die statische Variante schon lieber.

    namenlos schrieb:

    wenn du -static zum aufruf des gcc hinzufügst, verwendet ld automatisch die statischen versionen. sollte keine statische version vorhanden sein, meldet ld, dass es die bibliothek nicht gefunden hat. wohl bei fast allen distributionen befinden sich die statischen versionen im gleichen ordner wie die dynamischen.

    Mh, merkwürdig, wenn ich beispielsweise Graphviz mit dem -static flag kompiliere, bekomme ich keine Fehler, aber auch keine statisch gelinkte Anwendung. Und zwar mit: ./configure --prefix=/pfad CFLAGS=-static



  • das liegt daran, dass CFLAGS kein parameter von configure ist, sondern eine umgebungsvariable.

    CFLAGS=-static ./configure --prefix=/pfad
    

    das ist aber auch nicht die lösung. -static ist eine option, um exe dateien zu linken. statische bibliotheken werden mir ar aus den nicht-pic compilierten object-dateien erzeugt. die lösung ist, das du configure mit --enable-static aufrufst.

    Wuseldusel schrieb:

    Aber im Falle der dynamisch gelinkten Variante müsste ich halt alle Libraries einzeln kompilieren und ich befürchte, dabei treten bei jeder Library nochmals mindestens 100 neue Probleme auf

    du musst die bibliotheken so und so compilieren. ob statisch oder dynamisch macht bezüglich der probleme keinen unterschied.

    du solltest dir überlegen, ob du nicht einfach in einer readme alle abhängigkeiten klar definierst, sodass sich diese jeder selbst installieren kann. das macht mehr sinn. mit den heutigen distributionen ist die installation eines software paketes kein problem mehr. alle bibliotheken mitzuliefern ist kein garant dafür, dass alles überall ohne probleme läuft.



  • namenlos schrieb:

    du solltest dir überlegen, ob du nicht einfach in einer readme alle abhängigkeiten klar definierst, sodass sich diese jeder selbst installieren kann. das macht mehr sinn. mit den heutigen distributionen ist die installation eines software paketes kein problem mehr. alle bibliotheken mitzuliefern ist kein garant dafür, dass alles überall ohne probleme läuft.

    Bin gerade noch dabei, etwas Überzeugungsarbeit zu leisten 😉 ...

    Noch eine Frage:
    Muss ich auf irgendetwas spezielles achten, wenn ich Quellen - z.B. ImageMagick - auf einem 64bit System kompilieren will? Also ich meine jetzt nicht cross, sondern direkt auf dem System selbst.



  • nein, musst du nicht.


Anmelden zum Antworten