Optimisation de CMake pour les bibliothèques statiques

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.


:


  • staticA
  • staticB
  • staticC

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.

Source: https://habr.com/ru/post/undefined/


All Articles