2012-12-21 9 views
10

Ich baue ein Programm mit autoconf, automake und libtool. Meine Arbeit erfordert, dass ich (die meisten) Bibliotheken statisch verknüpfe. Dies war nicht ein Problem in der Vergangenheit, weil ich alles mit -all-static statisch verknüpfen konnte. Jetzt ist es ein Problem, weil ich eine Bibliothek verwenden muss, die nur dynamisch ist; es wurde uns von einem Dritten gegeben, und wir haben keine Quelle.Wie kann ein Benutzer von autotools eine Kombination aus statischer und dynamischer Verknüpfung angeben?

Natürlich verursacht jetzt -all-static den Build fehlschlagen. Ist es möglich, Littool zu sagen, alles statisch zu verknüpfen, außer für diese eine Bibliothek? Ist es möglich, Libtool eine beliebige Kombination von statischen und dynamische Verknüpfung zu haben, oder ist es alles oder nichts?

Bisher habe ich versucht, eine Convenience-Bibliothek mit LDFLAGS = -static zu erstellen, die von den Bibliotheken abhängt, die ich statisch verknüpfen möchte. Aber libtool verkettet die statischen Bibliotheken nicht, wie ich es mir erhofft hätte. Das Programm, das von der Bequemlichkeits-Bibliothek abhängig ist, verbindet noch dynamisch alles.

Ich habe auch versucht --disable-shared, aber das hat den Build nicht beeinflusst.


Diese Fragen sind ähnlich, aber meine Frage nicht wirklich beantworten:

Force linking a static library into a shared one with Libtool

Is it possible to link some — but not all — libraries statically with libtool?

(Ich will nicht gemeinsam genutzte Bibliotheken von meinem System löschen und den vollständigen Pfad für alles zu spezifizieren ist kaum besser als per Hand zu verknüpfen, aber vielleicht ist es der einzige Weg.)

Antwort

10

Sie haben n ot spezifizieren das Betriebssystem, aber nehmen wir an, dass es ein relativ neues Unix/Linux/OSX ist. Ist dies nicht der Fall, ignorieren Sie die folgende Warnung.

Bevor ich antworte, sollten Sie wissen, dass das Mischen von statischem und gemeinsam genutztem Code auf den meisten ELF-basierten Systemen (Unix/Linux) problematisch ist. Ein Grund dafür ist, dass es dazu führen kann, dass Code nicht mehr synchron läuft, wenn Sie vergessen, eine aktualisierte Abhängigkeit neu zu verknüpfen. Ein weiterer Grund liegt in der Natur des statischen Codes gegenüber PIC. Deshalb versucht libtool, es zu entmutigen.

aber sagen, dass in der Makefile.am (vorausgesetzt, Ihre endgültige Programm wird foo und die gemeinsam genutzte Bibliothek ist):

. 
    . 
    . 
    foo_SOURCES = foo.c abc.c def.c hij.c 
    foo_LDFLAGS = -all-static -Wl,-Bdynamic,-L/path/to,-lshared,-Bstatic 
    foo_LDADD = -L../path/to -lbar -lbaz 

Wichtig ist hier, dass libtool Sie ermöglicht kurzzuschließen die Kontrollen und GNU gcc -static Flag (die von Libtool verwendet wird) durch Übergabe von -Wl, Argumente direkt an den Linker (GNU ld). Um Leerzeichen zwischen Argumenten zu setzen, wird das Komma , delimiter verwendet.

Sowohl -Bstatic als auch -Bdynamic sind in GNU ld's info pages sowie der Hilfe-Bildschirm dokumentiert. Da Sie das verwendete Betriebssystem oder Compiler-Paket nicht erwähnt haben, gehe ich von GNU gcc und GNU ld unter Linux aus. Vielleicht möchten Sie überprüfen, indem Sie ld --help verwenden, um selbst zu sehen. Wenn es aus irgendeinem Grund nicht GNU ld ist, müssen Sie die entsprechenden Flags zu -Bstatic und -Bdynamic finden und gegebenenfalls ersetzen.

+1

Dies funktioniert, aber bei dem Verlust einiger Flexibilität.Ich brauche keinen dynamischen Build, aber wenn ich es jemals tun würde, müsste ich ein paar 'Makefile.am's bearbeiten, oder? Dies verursacht auch Probleme mit Makros wie 'AC_CHECK_LIB' (die nur ein' -l' zu 'LIBS' hinzufügen), aber ich denke, das ist zu erwarten. – tprk77

+2

Ich gab den einfachsten Ansatz möglich. Für etwas Phantasie, könnten Sie jedoch die Flags in Ihre 'configure.ac' ziehen. Dort können Sie 'DYNLIBS =" - Wl, -Bdynamic, -L/path/to, lshared, -Bstatic "' mit einem Aufruf von 'AC_SUBST ([DYNLIBS])' hinzufügen. Dann müssen Sie nur '$ (DYNLIBS)' in Ihrer 'Makefile.am' aufrufen. Dies würde Ihnen mehr Kontrolle geben, aber denken Sie daran, dass 'AC_CHECK_LIBS' nicht nach statischen vs. dynamischen Bibliotheken sucht. Ist es das, was du willst oder gibt es etwas anderes, das es flexibler machen würde? – NickW

+0

Ja, ich denke, das wird funktionieren, danke! – tprk77