2016-03-05 12 views
6

Il CMake manual of Qt 5 utilizza find_package e dice:Ottenere gli obiettivi importati tramite `find_package`?

obiettivi importati vengono creati per ogni modulo Qt. I nomi di destinazione importati dovrebbero essere preferiti invece di utilizzare una variabile come Qt5<Module>_LIBRARIES nei comandi di CMake come target_link_libraries.

E 'speciale per Qt o fa find_package generare obiettivi importati per tutte le librerie? Il dice:

Quando il pacchetto viene trovato, le informazioni specifiche del pacchetto vengono fornite tramite variabili e destinazioni importate documentate dal pacchetto stesso.

E il manual for cmake-packages dice:

Il risultato dell'utilizzo di find_package o è una serie di obiettivi importati, o un insieme di variabili che corrispondono a costruire rilevanti informazioni.

Ma non ho visto un altro FindXXX.cmake -script in cui la documentazione dice che un importata bersaglio è creato.

risposta

6

find_package è una bestia a due teste in questi giorni:

CMake fornisce supporto diretto per due forme di pacchetti, Config-file Packages e Find-module Packages

Source

Ora, che cosa in realtà significa?

I pacchetti del modulo di ricerca sono quelli con cui probabilmente si è più familiari.Eseguono uno script di codice CMake (ad esempio this one) che esegue numerose chiamate a funzioni come find_library e find_path per capire dove individuare una libreria.

Il grande vantaggio di questo approccio è che è estremamente generico. Finché c'è qualcosa nel filesystem, possiamo trovarlo. Il grande svantaggio è che spesso fornisce poche informazioni in più rispetto alla posizione fisica di quel qualcosa. Cioè, il risultato di un'operazione di find-module è in genere solo un mucchio di percorsi del filesystem. Ciò significa che la modellazione di cose come le dipendenze transitive o più configurazioni di build è piuttosto difficile.

Questo diventa particolarmente doloroso se la cosa che si sta cercando di trovare è stesso stato creato con CMake. In tal caso, hai già un sacco di cose modellate nei tuoi script di costruzione, che ora devi ricostruire accuratamente per lo script di ricerca, in modo che diventi disponibile per i progetti downstream.

Questo è dove pacchetti di file di configurazione brillano. A differenza dei moduli di ricerca, il risultato dell'esecuzione dello script non è solo un insieme di percorsi, ma crea invece obiettivi CMake completamente funzionali. Per il progetto dipendente sembra che le dipendenze siano state costruite come parte di quello stesso progetto.

Ciò consente di trasportare molte più informazioni in un modo molto conveniente. Lo svantaggio evidente è che gli script di file di configurazione sono molto più complessi degli script di ricerca. Quindi non vuoi scriverli da solo, ma fai in modo che CMake li generi per te. O piuttosto che la dipendenza fornisca un file di configurazione come parte della sua distribuzione che puoi quindi semplicemente caricare con una chiamata find_package. E questo è esattamente ciò che fa Qt5.

Ciò significa anche che se il proprio progetto è una libreria, considerare generating a config file as part of the build process. Non è la caratteristica più semplice di CMake, ma i risultati sono piuttosto potenti.

Ecco un rapido confronto di come i due approcci tipicamente assomigliano nel codice CMake:

Find-modulo stile

find_package(foo) 
target_link_libraries(bar ${FOO_LIBRARIES}) 
target_include_directories(bar ${FOO_INCLUDE_DIR}) 
# [...] potentially lots of other stuff that has to be set manually 

stile config-file

find_package(foo) 
target_link_libraries(bar foo) 
# magic! 

tl; dr: Preferisco sempre config-fi i pacchetti se la dipendenza li fornisce. In caso contrario, utilizzare invece un comando di ricerca.

2

In realtà non esiste una "magia" con i risultati di find_package: questo comando cerca solo lo script FindXXX.cmake appropriato e lo esegue.

Se Trova set di script variabile XXX_LIBRARY, il chiamante può utilizzare questa variabile.

Se Trova script crea target importati, il chiamante può utilizzare questi target.

Se lo script Trova né impostaXXX_LIBRARY variabile né crea obiettivi importati ... bene, allora l'utilizzo dello script è in qualche modo diverso.

La documentazione per find_package descrive usuale utilizzo di script di ricerca. Ma in ogni caso è necessario consultare la documentazione sullo script di calcestruzzo (questa documentazione è normalmente contenuta nello script stesso).

Problemi correlati