2012-12-01 15 views
7

C++ - il progetto, ad esempio, foo viene gestito da cmake. Si desidera creare una libreria libfoo.a (con tutte le classi/metodi/funzioni create nell'intero albero dei sorgenti) per rendere possibile la creazione di programmi che potrebbero essere collegati alla libreria con -lfoo.crea una libreria statica da intero progetto con cmake

ok, consideriamo ora un esempio di giocattolo, e il prolbem sarà chiaro. La directory foo (root del progetto) contiene le directory a e b. Due CmakeLists.txt sono creati:

# a/CMakeLists.txt 
add_library(A <a_sources>) 
# b/CMakeLists.txt 
add_library(B <b_sources>) 

E uno CMakeLists.txt per la directory root:

add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> 
target_link_libraries(foo A B) 

E 'stata una sorpresa per me: dopo aver costruito libfoo.a contiene solo i metodi da foo_sources, e a_sources, b_sources sono esclusi. Questo va bene nel caso in cui gli eseguibili siano costruiti con lo stesso progetto: mentre si creano "eseguibili" cmake "indovina" che a e b devono essere collegati se sono collegati a foo. Ma nel caso dell'eseguibile viene creato il progetto "esterno" per utilizzare la libreria foo occorre un collegamento con -lfoo -la -lb, ora si immagina un progetto con molte sottodirectory - come gestirlo? quindi la domanda è "come creare una libreria, aggregando metodi dell'intero progetto con mezzi di cmake?"

Googling mi ha portato a un'opportunità relativamente recente incorporata (visualizzata in 2.8.8) OBJECT library. Un bell'esempio di utilizzo è mostrato here. Ora il problema sopra può essere risolto con questo:

# a/CMakeLists.txt 
add_library(A OBJECT <a_sources>) 
# b/CMakeLists.txt 
add_library(B OBJECT <b_sources>) 
# foo/CMakeLists.txt 
add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>) 

il problema sembra essere risolto, sfortunatamente, non del tutto.

se la catena di dipendenze è più lunga di 2, ad esempio, foo dipende da A, che dipende da B, il problema rimane ancora. Questo perché,

Le librerie di oggetti possono contenere solo origini (e intestazioni) che compilano i file oggetto.

e

librerie di oggetti non possono essere importati, esportati, installate o collegate.

(citazioni sono tratte dalla stessa link)

Ho provato diverse combinazioni di target_link_library(), add_library(), add_library(... OBJECT ..) cercando di collegare A e B-foo senza successo (errore durante cmake-processo.)

Devo perdere qualcosa di semplice, per favore aiutatemi, grazie! Non sono sicuro che sia importante: il progetto viene mantenuto su Linux.

risposta

3

Penso che ti stai aggrovigliando nel termine "dipende da".Se stai creando una libreria denominata foo e ha due parti, A e B, non importa se A dipende da B; la biblioteca dovrebbe contenere entrambi. Il codice CMake che hai mostrato creerà correttamente foo.

0

Sì, supporto risposta @Pete Becker @. Ma va anche detto che quelle librerie a $<TARGET_OBJECTS:A> e $<TARGET_OBJECTS:B> non sono affatto librerie, ma piuttosto un elenco interno di moduli oggetto. Non vi sono dipendenze tra la compilazione di moduli oggetto (eccetto le fonti generate automaticamente) in modo che possano essere eseguite in qualsiasi ordine e in parallelo.

Immagino che il termine più corretto per la tua intenzione sia quello di riunire più TARGET_OBJECTS nella libreria di oggetti singoli. È davvero brutto che tu non possa scrivere add_library(B OBJECT b.cpp $<TARGET_OBJECTS:A>). Ma è sempre possibile implementare questo da soli:

add_library(A OBJECT a.cpp) 
set(A_OBJECTS $<TARGET_OBJECTS:A>) 

add_library(B OBJECT b.cpp) 
set(B_OBJECTS $<TARGET_OBJECTS:B> ${A_OBJECTS}) 

add_library(foo ${B_OBJECTS}) 

cioè basta creare variabili speciali _OBJECTS da usare ogni volta che si desidera includere tali librerie di oggetti nella libreria, eseguibile o come parte di altri libreria di oggetti con quella _OBJECTS sapore.

Problemi correlati