Un’utile opzione dello GNU linker

Scrivere programmi in C/C++ usando la toolchain GCC è, in genere, piacevole e produttivo. A patto di conoscere alcune questioni che, a prima vista, possono sembrare di lana caprina.

La questione di lana caprina

Ad esempio, una cosa importante da sapere è che, a differenza di quando si linka un eseguibile, quando si fa il link di una libreria condivisa (file lib*.so), lo GNU linker (invocato direttamente con il comando ld, oppure indirettamente tramite il compilatore GCC) non dà alcun errore se ci sono simboli irrisolti. L’idea è quella di consentire comunque la creazione della libreria, rimandando la risoluzione dei simboli al momento in cui si farà il link di un eseguibile che ne faccia uso.

Facciamo un esempio concreto: supponiamo di realizzare la libreria libdinamica.so, che usa al suo interno la funzione richiesta() presa dalla libreria condivisa libdipendenza.so. Il comando di link per libdinamica.so sarà qualcosa del genere:

$ g++ -shared -o libdinamica.so oggetto1.o oggetto2.o oggetto3.o

che non contiene riferimenti alla libreria libdipendenza.so e non dà messaggi di errore. Un eventuale eseguibile che fa uso della libreria libdinamica.so dovrà essere linkato con il comando

$ g++ -o pincopallino oggetto4.o oggetto5.o -L. -ldinamica -ldipendenza

, ossia specificando entrambe le librerie (qui si suppone che tutti i file si trovino nella cartella corrente).

Se, invece, si fosse linkata la libreria con il comando

$ g++ -shared -o libdinamica.so oggetto1.o oggetto2.o oggetto3.o -L. -ldipendenza

il comando per linkare l’eseguibile avrebbe potuto essere

$ g++ -o pincopallino oggetto4.o oggetto5.o -L. -ldinamica

che è molto più logico perché, in generale, i file oggetto4.o e oggetto5.o possono essere del tutto agnostici riguardo alla libreria libdipendenza.so.

Il comportamento virtuoso

Un modo per costringerci ad adottare il “comportamento virtuoso” (quello di linkare libdipendenza.so con libdinamica.so, e non con l’eseguibile) è quello di richiedere al linker di lamentarsi dei simboli irrisolti anche durante la costruzione delle librerie condivise. L’opzione per attivare questo comportamento del linker è -no-undefined (che diventa -Wl,--no-undefined se invocata dal compilatore).

Con l’opzione -no-undefined, la prima versione del comando ha questo esito:

$ g++ -Wl,--no-undefined -shared -o libdinamica.so oggetto1.o oggetto2.o oggetto3.o
oggetto1.o: In function `usa_richiesta()':
oggetto1.cpp:(.text+0x13): undefined reference to `richiesta()'
collect2: ld returned 1 exit status
$

mentre l’unica forma che funziona sarà

$ g++ -Wl,--no-undefined -shared -o libdinamica.so oggetto1.o oggetto2.o oggetto3.o -L. -ldipendenza
Annunci

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...