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.