Aucun d'entre nous n'aime probablement attendre longtemps la fin de l'assemblage du projet, quand chaque seconde est comme une éternité. Et c'est bien si c'est les heures de travail, et vous pouvez passer le temps avec un verre de café, en discutant de toutes les lacunes de la collecte automatique des ordures.
Parfois, certains succès peuvent être obtenus en effectuant l'optimisation CMake. La technique considérée ici est basée sur une idée simple: deux bibliothèques statiques qui utilisent mutuellement leurs fonctions peuvent être assemblées simultanément.
Un peu d'anatomie
Pour commencer, considérez les étapes de base de la création d'une bibliothèque statique:
- préprocesseur - supprime tous les commentaires des fichiers source, insère les fichiers d'en-tête et remplace les macros par des valeurs calculées.
- compilateur - convertit les fichiers traités par le préprocesseur en code assembleur.
- assembleur - traduit le code assembleur en code machine; Le résultat est enregistré sous forme de fichiers objets.
- archiveur - collectez les fichiers objets dans une seule archive.
Graphiquement, ces étapes sont illustrées dans le diagramme:
, . , . . , , .
, , CMake target_link_libraries. :
target_link_libraries(staticC PRIVATE staticB)
, — staticC
staticB
. , , , staticC
, staticB
.
, CoherentDeps, :
, staticC
staticB
, .
, , , ( , ) INTERFACE
, -meta ( , ). , -, .
target_link_libraries
.
, :
: NonCoherentDeps.
:
NonCoherentDeps
.
staticB
staticA
, staticC
staticB
, NonCoherentDeps
staticC
. :
CMake- staticA
- :
add_library(staticA-meta INTERFACE)
target_include_directories(staticA-meta INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
, :
target_link_libraries(staticA PUBLIC staticA-meta)
staticB
CMake
target_link_libraries(staticB PRIVATE staticA)
:
target_link_libraries(staticB PRIVATE staticA-meta)
staticA
staticB
, . staticB
staticA
.
:
— :
add_executable(NonCoherentDeps main.cpp)
target_link_libraries(NonCoherentDeps PRIVATE staticC staticB staticA )
, .
, staticA
, target_include_directories. NonCoherentDeps, :
target_include_directories(staticB PRIVATE "${path_to_headers_in_staticA}")
:
target_link_libraries(staticB PRIVATE staticA-meta)
, staticB
staticA
, staticC
:
target_include_directories(staticC PRIVATE "${path_to_headers_in_staticB}" "${path_to_headers_in_staticA}")
. :
target_link_libraries(staticB-meta INTERFACE staticA-meta)
staticC
:
target_link_libraries(staticC INTERFACE staticB-meta)
staticB
, , .
Dans le méta-package, vous pouvez également ajouter une dépendance sous la forme d'une commande pour générer des fichiers d'en-tête, et les propriétés sont des chemins corrects.