gpz500′s Weblog

19 settembre 2011

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

Lascia un commento »

Non c'è ancora nessun commento.

RSS feed dei commenti a questo articolo. TrackBack URI

Lascia un Commento

Fill in your details below or click an icon to log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Log Out / Modifica )

Foto Twitter

You are commenting using your Twitter account. Log Out / Modifica )

Foto di Facebook

You are commenting using your Facebook account. Log Out / Modifica )

Connecting to %s

Theme: Rubric. Blog su WordPress.com.

Follow

Get every new post delivered to your Inbox.