Collegamento statico della funzione di libreria condivisa in gcc


138

Come posso collegare staticamente una funzione di libreria condivisa in gcc?


14
Cosa intendi per staticamente collegato? Vuoi che il tuo eseguibile sia distribuito senza richiedere il .so?
Emiliano

Risposte:


108

Fare riferimento a:

http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/

http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html

È necessaria la versione statica della libreria per collegarla.

Una libreria condivisa è in realtà un eseguibile in un formato speciale con punti di ingresso specificati (e alcuni problemi di indirizzamento inclusi). Non ha tutte le informazioni necessarie per collegarsi staticamente.

Non è possibile collegare staticamente una libreria condivisa (o collegare dinamicamente una libreria statica).

Il flag -staticimporrà al linker di utilizzare librerie statiche (.a) anziché condivise (.so). Ma le librerie statiche non sono sempre installate per impostazione predefinita, quindi potresti dover installare tu stesso la libreria statica.

Un altro possibile approccio è quello di utilizzare statizer o Ermine . Entrambi gli strumenti prendono come input un eseguibile collegato dinamicamente e come output creano un eseguibile autonomo con tutte le librerie condivise incorporate.


11
Quali informazioni ha la libreria statica, in modo che possa essere collegata staticamente, che la libreria dinamica non ha?
Kbolino,

75

Se vuoi collegare, diciamo, libapplejuice staticamente, ma non, diciamo, liborangejuice , puoi collegarti in questo modo:

gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary

C'è un avvertimento: se gli liborangejuiceusi libapplejuice, allora libapplejuicesaranno anche collegati dinamicamente.

Dovrai collegarti liborangejuicestaticamente insieme a libapplejuiceper ottenere libapplejuicestatico.

E non dimenticare di mantenere -Wl,-Bdynamicaltrimenti finirai per collegare tutto ciò che è statico, incluso libc(che non è una buona cosa da fare).


2
Non c'è modo di dire direttamente a gcc cosa collegare staticamente e non aggirarlo e parlare con il linker?
Elazar Leibovich,

1
@ElazarLeibovich non puoi ottenere una combinazione di statica e dinamica in quel modo.
Haozhun,

@EugeneBujak: l' avvertenza non si applica al mio sistema. Esempio: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libB usa libA , è collegato e lddnon mostra un riferimento a libA . L'eseguibile funziona bene. Testato con g ++ 4.7.3.
radix

Una dipendenza indiretta (nidificata), statica di una dipendenza diretta, dinamica, non diventa essa stessa collegata dinamicamente.
Vinny,

Considera quanto segue: binA dipende da libB.so che dipende da libC.a Come altri hanno già affermato, .so sono essi stessi eseguibili, quindi quando un oggetto condiviso è collegato, tutti i dipendenti della libreria statica vengono elaborati dal linker più o meno come se un eseguibile veniva collegato: gli unici simboli estratti dalla .a static lib sono quelli a cui fa riferimento (e non risolto) da .so. Ciò significa che se binA fa riferimento a un simbolo in libC.a, a cui non fa riferimento in nessun punto di libB.so, allora anche se binA si collega a libB.so, quel simbolo sarà indefinito (a meno che non venga utilizzato -Wl, -intero archivio durante il collegamento libB.so).
Vinny,

18

Se hai il file .a della tua libreria condivisa (.so) puoi semplicemente includerlo con il suo percorso completo come se fosse un file oggetto, come questo:

Questo genera main.o semplicemente compilando:

gcc -c main.c

Questo collega quel file oggetto con la corrispondente libreria statica e crea l'eseguibile (chiamato "main"):

gcc main.o mylibrary.a -o main

O in un singolo comando:

gcc main.c mylibrary.a -o main

Potrebbe anche essere un percorso assoluto o relativo:

gcc main.c /usr/local/mylibs/mylibrary.a -o main

12

Sì, so che questa è una domanda di 8 anni, ma mi è stato detto che era possibile collegarsi staticamente a una libreria di oggetti condivisi e questo è stato letteralmente il successo maggiore quando ho cercato ulteriori informazioni al riguardo.

Per dimostrare effettivamente che non è possibile collegare staticamente una libreria di oggetti condivisi con ld( gcclinker di) - al contrario di un gruppo di persone che insistono sul fatto che non è possibile - utilizzare il seguente gcccomando:

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so

(Naturalmente dovrete compilare objectname.oda sourcename.c, e, probabilmente, si dovrebbe fare il proprio libreria condivisa oggetto pure. Se lo fai, l'uso -Wl,--library-path,.in modo che ld possa trovare la libreria nella directory locale.)

L'errore effettivo che ricevi è:

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status

Spero che aiuti.


10

Un po 'in ritardo ma ... ho trovato un link che ho salvato un paio di anni fa e ho pensato che potesse essere utile per voi ragazzi:

CDE: crea automaticamente applicazioni Linux portatili

http://www.pgbovine.net/cde.html

  • Basta scaricare il programma
  • Eseguire il binario passando come argomento il nome del binario che si desidera rendere portatile, ad esempio: nmap

    ./cde_2011-08-15_64bit nmap

Il programma leggerà tutte le librerie collegate a nmap e alle sue dipendenze e le salverà tutte in una cartella chiamata cde-package / (nella stessa directory in cui ci si trova).

  • Infine, puoi comprimere la cartella e distribuire il binario portatile in qualunque sistema.

Ricorda, per avviare il programma portatile devi eseguire il binario che si trova in cde-package / nmap.cde

I migliori saluti


2
Pur non fornendo esattamente la risposta alla domanda, è una soluzione notevole al problema.
razong,

Il collegamento sembra essere morto ora.
sinan

0

In gcc, questo non è supportato. In realtà, questo non è supportato in nessun compilatore / linker esistente di cui sono a conoscenza.


4
Potresti spiegare come il collegamento statico non è supportato da nessun compilatore esistente?
dal

5
@noloader, collegamento statico della libreria dinamica?
nothrow
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.