g ++ che collega la dipendenza degli ordini quando si collega il codice c al codice c ++

Prima di oggi avevo sempre creduto che l’ordine che oggetti e librerie fossero passati a g ++ durante la fase di collegamento non era importante. Poi, oggi, ho provato a colbind dal codice c ++ al codice c. Ho avvolto tutte le intestazioni C in un blocco “C” esterno, ma il linker ha ancora avuto difficoltà nel trovare i simboli che conoscevo negli archivi degli oggetti C.

Perplesso, ho creato un esempio relativamente semplice per isolare l’errore di collegamento, ma con mia grande sorpresa, l’esempio più semplice collegato senza problemi.

Dopo un po ‘di tentativi ed errori, ho scoperto che emulando il modello di collegamento usato nell’esempio semplice, potevo ottenere il codice principale per colbind OK. Lo schema era prima il codice object, secondo gli archivi object per esempio:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

Qualcuno può far luce sul motivo per cui potrebbe essere così? Non ho mai visto questo problema durante il collegamento di codice c ++ ordinario.

L’ordine con cui specifichi i file object e le librerie è MOLTO importante in GCC – se non sei stato morso da questo prima di aver condotto una vita incantata. Il linker cerca i simboli nell’ordine in cui appaiono, quindi se hai un file sorgente che contiene una chiamata a una funzione di libreria, devi metterlo davanti alla libreria, o il linker non saprà che deve risolverlo. Un uso complesso delle librerie può significare che devi specificare la libreria più di una volta, il che è un dolore reale per avere ragione.

L’ordine della libreria passa a gcc / g ++ in realtà importa. Se A dipende da B , A deve essere elencato per primo. Il motivo è che ottimizza i simboli che non sono referenziati, quindi se prima vede la libreria B , e nessuno ha fatto riferimento a quel punto, allora non collegherà affatto nulla.

Una libreria statica è una raccolta di file object raggruppati in un archivio. Quando si collega a esso, il linker sceglie solo gli oggetti di cui ha bisogno per risolvere i simboli attualmente non definiti. Poiché gli oggetti sono collegati in ordine dato sulla riga di comando, gli oggetti della libreria saranno inclusi solo se la libreria viene dopo tutti gli oggetti che dipendono da essa.

Quindi l’ordine dei link è molto importante; se si utilizzano librerie statiche, è necessario fare attenzione a tenere traccia delle dipendenze e non introdurre dipendenze cicliche tra le librerie.

È ansible utilizzare gli archivi –start-group –end-group e scrivere le 2 librerie dipendenti anziché gli archivi

gcc main.o -L. -Wl, – start-group -lobj_A -lobj_b -Wl, – end-group