cmake, perdu dans le concept de variables globales (et parent SCOPE ou add subdirectory alternatives)
j'ai un projet cmake dans lequel j'ai quelques modules et j'utilise Find-*.cmake pour inclure les modules partagés dans l'application.
Pour ne pas tenir compte de chaque module que j'ajoute, j'ai défini une sorte de variables globales LIB
pour le linker:
# inside a Find-*.cmake or in the CMakeLists.txt of the modules:
set(LIB ${LIB} ...)
donc dans l'une des applications finales qui utilise certains modules, je peux juste faire:
target_link_libraries(${APP_NAME} ${LIB})
Alors, j'aimerais avoir les modules compilés dans le /project_path/modules/foo/build
de sorte que si un module est vraiment gros pour compiler, il peut être établi une fois pour toutes les applications qui l'utilisent. La façon dont j'y parviens, c'est de charger les listes de Cmakélistes.txt du module de La Find -*.cmake de cette façon:
# Inside FindFoo.cmake, for loading /project_path/modules/foo/CMakeLists.txt
# and compile it in /project_path/modules/foo/build
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}
${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}/build
)
include_directories(${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}/include)
mais il s'est produit parfois qu'un module nécessite un autre module de sorte que le add_subdirectory
crée de nouvelles portées et peut charger correctement LIB
mais ne peut pas l'écrire (Lorsque j'utilise set
il est dans la portée plus profonde et ne modifie pas le supérieure de la portée). Pour contourner cela, je dois ajouter PARENT_SCOPE dans le set
).. J'ai donc essayé de l'ajouter dans un module qui, je pense, pourrait être imbriqué et caché dans certaines dépendances, mais en compilant toute l'application à laquelle j'ai soudainement fait face:
CMake Warning (dev) at /path_to_repo/cmake/FindFooX.cmake:6 (set):
Cannot set "LIB": current scope has no parent.
Call Stack (most recent call first):
CMakeLists.txt:14 (find_package)
This warning is for project developers. Use -Wno-dev to suppress it.
je crains que cela puisse changer d'une application à l'autre en ce qui concerne le module dont j'ai besoin ou en ce qui concerne l'arbre des dépendances dans les modules eux-mêmes donc je suis à la recherche d'une solution plus propre.
2 réponses
toutes les variables de CMake sont locales par défaut. Alors que vous pouvez utiliser le paramètre PARENT_SCOPE
pour augmenter la portée d'une variable locale d'une couche, cela a surtout du sens pour les valeurs de retour de fonctions .
Pour trouver des scripts d'autre part, vous voulez généralement le comportement d'une variable globale: une Fois trouver le script est appelé par quelqu'un, vous voulez que les résultats soient disponibles partout. En particulier, un deuxième appel à même de trouver script doit réutiliser les résultats du premier appel.
Dans CMake, Ceci est réalisé en stockant les variables dans le cache. Les différents appels find_*
le font déjà automatiquement, vous devriez donc préférer utiliser ceux qui s'appliquent. Pour toutes les variables personnalisées supplémentaires, set
offre également la possibilité de stocker dans le cache:
set(MY_GLOBAL_VARIABLE "Some value" CACHE STRING "Description")
notez que les variables locales peuvent cacher les variables mises en cache du même nom dans leur champ d'application.
vous pouvez "simuler" le comportement de la variable globale, en utilisant des propriétés avec une portée globale:
SET_PROPERTY(GLOBAL PROPERTY MyGlobalProperty "MyGlobalPropertyValue")
, Alors vous pouvez extraire votre propriété globale en utilisant
GET_PROPERTY(MyLocalVariable GLOBAL PROPERTY MyGlobalProperty)
Puis, MyLocalVariable contient "MyGlobalPropertyValue".
parce que PARENT_SCOPE étend les définitions de variables au seul répertoire parent (et pas à ses parents), il y a des cas où ce n'est pas suffisant, par exemple si vous avez un arbre généalogique profond...