2012-02-21 19 views
26

Abbiamo una base di codice suddivisa in librerie statiche. Sfortunatamente, le librerie hanno dipendenze circolari; ad esempio, libfoo.a dipende da libbar.a e viceversa.Risoluzione delle dipendenze circolari collegando due volte la stessa libreria?

So che il modo "corretto" per gestire questa situazione è quello di utilizzare --start-group e --end-group opzioni del linker, in questo modo:

g++ -o myApp -Wl,--start-group -lfoo -lbar -Wl,--end-group 

Ma nelle nostre Makefiles esistenti, il problema è in genere gestito in questo modo:

g++ -o myApp -lfoo -lbar -lfoo 

(Immaginate questo esteso a ~ 20 biblioteche con complesse interdipendenze.)

vado attraverso ou r Makefile che cambiano la seconda forma alla prima, ma ora i miei colleghi mi chiedono perché ... E a parte "perché è più pulito" e un vago senso che l'altra forma sia rischiosa, non ho una buona risposta.

Quindi, è possibile collegare la stessa libreria più volte sempre creare un problema? Ad esempio, il collegamento potrebbe fallire con simboli definiti in modo multiplo se lo stesso .o viene inserito due volte? O c'è qualche rischio di finire con due copie dello stesso oggetto statico, creando bug sottili?

Fondamentalmente, desidero sapere se esiste la possibilità di errori di collegamento o di runtime per collegare più volte la stessa libreria; e se è così, come attivarli. Grazie.

+0

L'unico problema a cui riesco a pensare è quando riesci a collegarti con due diverse versioni della stessa libreria. È difficile da fare e (IMO) è improbabile che si verifichi su Linux. Inoltre, solo 20 librerie non sembrano molto. Vale la pena camminare attraverso i makefile? Potresti passare quel tempo a fare qualcos'altro. – SigTerm

+3

Questo problema scompare solo se si correggono le librerie in modo da non avere dipendenze circolari. –

+3

Suppongo che rimuovere le dipendenze circolari esaminando e suddividendo le librerie non sia fattibile? Perché sarebbe il modo più pulito –

risposta

5

Tutto quello che posso offrire è una mancanza di controesempio. Non ho mai visto la prima forma prima (anche se è chiaramente migliore) e ho sempre visto questo risolto con la seconda forma, e di conseguenza non ho osservato problemi.

Anche così suggerirei di passare al primo modulo perché mostra chiaramente la relazione tra le librerie piuttosto che affidarsi al linker che si comporta in un modo particolare.

Detto questo, vorrei suggerire almeno considerando se esiste la possibilità di refactoring del codice per estrarre i pezzi comuni in librerie aggiuntive.

+5

Grazie, Mark. Anche se trovo divertente vedere che metà dei commenti alla mia domanda dicono "Risolvi il tuo codice base!" e l'altra metà dice "Perché stai manomettendo una base di codice funzionante?" :-) – Nemo

+0

Il primo modulo introdurrebbe un costo delle prestazioni poiché il linker tenta di trovare i simboli ripetuti su tutte le librerie elencate. vedere questo: http://stackoverflow.com/a/409470/70198 –

+0

Anche il primo modulo funziona solo per GNU ld e quindi non è una soluzione portatile. – user1225999

1

Dato che si tratta di un'applicazione legacy, scommetto che la struttura delle librerie è ereditata da un accordo che probabilmente non ha più importanza, come ad esempio essere utilizzato per costruire un altro prodotto che non si fa più.

Anche se rimangono ancora motivi strutturali per la struttura della libreria ereditata, quasi certamente, sarebbe ancora accettabile creare un'altra libreria dall'accordo legacy. Basta mettere tutti i moduli delle 20 librerie in una nuova libreria, liballofthem.a. Quindi ogni singola applicazione è semplicemente g++ -o myApp -lallofthem ...

Problemi correlati