2015-01-22 21 views
5

Desidero che alcune parti del mio progetto, che sono molto raramente modificate, vengano compilate staticamente e "installate" in una directory separata. È necessario perché a causa di alcune specifiche del progetto abbastanza spesso deve essere ricompilato da zero (con la rimozione dell'intera directory di build). "Installare" quelle librerie collegate staticamente in una directory separata permetterà di ridurre significativamente i tempi di costruzione.Come rendere la libreria statica importata dipendente da un'altra libreria statica importata in CMake?

Quello che avevo all'inizio. Diciamo che la LibA è cambiata molto raramente e voglio che venga installata una volta e che non venga ricostruita durante la maggior parte delle build del progetto. La LibA dipende da una libreria importata da terze parti LibC. Il progetto contiene anche LibB che cambia frequentemente e dipende dalla LibA.

CMakeLists.tst (LibB): 
    target_link_libraries("LibB" LibA_build) 

CMakeLists.tst (LibA): 
    add_library(LibA_build ...) 
    add_library(LibC STATIC IMPORTED) 
    add_dependencies(LibA_build LibC) 

In questo caso durante il collegamento LIBB avremo dipendenze LibA e LibC. E ogni volta prima di costruire la LibB ricostruiremo la LibA.

Per evitare ricostruzioni inutili che ho fatto nuovo obiettivo "LibA" (non "LibA_build). Così ora LIBB dipende "LibA".

CMakeLists.tst (LibB): 
    target_link_libraries("LibB" LibA) 

Questo nuovo obiettivo ho dichiarato come libreria importata.

CMakeLists.tst (LibA): 
    # This target is for building and installing 
    add_library(LibA_build ...) 
    SET_TARGET_PROPERTIES(LibA_build PROPERTIES OUTPUT_NAME LibA) 
    install(
    FILES /build/path/to/LibA.lib 
    DESTINATION /installed/path/to/LibA 
) 

    # This target is for linking LibA with another libraries 
    add_library(LibA STATIC IMPORTED GLOBAL) 
    set_property(TARGET LibA PROPERTY IMPORTED_LOCATION /installed/path/to/LibA) 

    add_library(LibC STATIC IMPORTED) 
    add_dependencies(LibA LibC) 

Risultato:. ora, prima costruzione di LIBB non stiamo ricostruendo LibA

Problema: biblioteca perché ora LibA divenne importata, CMake si rifiuta di vedere la dipendenza della LibA in LibC. In effetti l'istruzione di collegamento per LibB contiene dipendenza solo su LibA, ma non su LibC. In caso di buildign sotto Windows porta a errori di collegamento esterni non risolti.

Domanda: Come rendere la libreria statica importata in LibA dipendente da un'altra libreria statica importata LibC? Quindi, in caso di collegamento di istruzioni LibB per il collegamento conterrà dipendenze su entrambi - LibA e LibC.

P.S. So che questo modo non è corretto. L'ho usato solo perché non ho trovato nessun altro modo. Apprezzerei molto se mi aiutassi ad aggiungere questa dipendenza dalla libreria di importazione statica o suggerire un altro modo per raggiungere un obiettivo ricco che ho descritto all'inizio.

+0

È possibile creare un target personalizzato che "pulisce" solo per 'libA' o qualsiasi parte specifica del progetto è rotta e richiede una costruzione frequente da zero. Oppure puoi correggere la causa principale, il che sembra essere il fatto che le ricostruzioni devono essere fatte da zero. –

+0

Bene, ho più fiducia in "rm -rf *" che nella pulizia :) Comunque, grazie per il suggerimento. – Alex

+0

Il mio punto è, puoi scrivere un target personalizzato in CMake che esegue 'rm -rf' se vuoi. –

risposta

3

La funzione che stavo cercando (aggiungere dipendenza della libreria di importazione statica su altre librerie di importazione) si chiama collegamento transitivo. Viene implementato impostando la proprietà target IMPORTED_LINK_INTERFACE_LIBRARIES. Dicono che questa proprietà è stata sottratta e consiglia di utilizzare INTERFACE_LINK_LIBRARIES, ma nel mio caso (cmake versione 2.8.11.2) solo IMPORTED_LINK_INTERFACE_LIBRARIES funziona.

Così, per esempio sopra la fine del CMakeLists.tst per LibA dovrebbe essere simile a questo:

add_library(LibC STATIC IMPORTED) 
    a̶d̶d̶_̶d̶e̶p̶e̶n̶d̶e̶n̶c̶i̶e̶s̶(̶L̶i̶b̶A̶ ̶L̶i̶b̶C̶)̶ 
    set_property(TARGET LibC PROPERTY IMPORTED_LOCATION /path/to/LibC) 

    set_property(TARGET LibA PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES LibC) 

auguriamo che queste informazioni saranno utili per qualcuno.

Problemi correlati