web-dev-qa-db-fra.com

Pour la commande cmake "include", quelle est la différence entre un fichier et un module?

J'utilise des bibliothèques que je ne veux pas construire dans le cadre de chaque projet qui les utilise. Un exemple très compréhensible est LLVM, qui possède 78 bibliothèques statiques. Même avoir le code cmake pour les trouver et les importer dans chaque cmakefile est excessif.

La solution évidente semble être d'utiliser la commande "include", de factoriser les morceaux pertinents du script cmake dans les fichiers * .cmake et de configurer une variable d'environnement CMAKE_MODULE_PATH.

Sauf que ça ne marche pas. Cmake ne trouve pas le fichier que je spécifie dans la commande include.

Par hasard, j'ai même essayé de spécifier le chemin dans la variable d'environnement de plusieurs façons - une fois avec des barres obliques inverses, une fois avec des barres obliques ... - et j'ai redémarré l'invite de commande à chaque fois et vérifié que la variable d'environnement était présente et correcte.

Dans le manuel de cmake, cela implique en quelque sorte qu'un "fichier" est différent d'un "module" - seul un module reçoit le traitement automatique d'ajout-d'extension-et-recherche-du-chemin. Mais il n'y a aucune explication de la différence. J'ai deviné que l'extension manquante pourrait être suffisante (comme avec les modules standard), mais ce n'est clairement pas le cas.

La recherche dans le manuel de "module" n'est pas d'une grande aide car le mot semble surchargé. Par exemple, un module est également une bibliothèque dynamique chargée à l'aide de LoadLibrary/dl_open.

Quelqu'un peut-il expliquer quelle est la différence entre un fichier et un module dans ce contexte, et comment je crée mon propre module pour que la commande cmake include puisse le trouver et l'utiliser?

J'utilise cmake 2.8.1 sous Windows.

MODIFIER

Je suis assez confiant que le problème ici n'est pas de comprendre comment cmake est censé fonctionner. Je pense que ce que je devrais faire, c'est écrire quelque chose que find_package peut fonctionner avec.

En l'état actuel des choses, je suis encore loin de pouvoir répondre à ma propre question.

38
Steve314

Je crois qu'un "module" CMake est simplement un fichier qui peut être utilisé avec la directive find_package . Autrement dit, lorsque vous exécutez find_package(Module), il recherche un fichier dans le MODULE_PATH nommé FindModule.cmake.

Cela dit, si vous include un fichier sans l'extension, il recherchera également ce file.cmake Dans votre MODULE_PATH. Dans un projet CMake sur lequel je travaille, j'ai une structure de répertoires très similaire à ce que vous proposez.

+ root/
  + CMakeLists.txt
  + cmake/
  | + FindMatlab.cmake
  | + TestInline.cmake
  | + stdint.cmake
  + src/
  + include/

Dans CMakeLists.txt, j'ai:

set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package (Matlab) # runs FindMatlab.cmake
include(TestInline) # defines a macro:
test_inline (CONFIG_C_INLINE)
include(stdint) # simply executes flat CMake code

Votre problème est peut-être que vous essayez de définir le chemin du module à partir de l'environnement. Au lieu de cela, essayez de simplement y ajouter dans la CMakeList même dans laquelle vous essayez d'accéder aux modules/fichiers.

39
Matt B.

J'ai eu cette même question après avoir lu la documentation de la commande CMake include(). Il est dit:

Chargez et exécutez le code CMake à partir du fichier donné. [... snip for concision ...] Si un module est spécifié à la place d'un fichier, le fichier avec le nom .cmake est recherché d'abord dans CMAKE_MODULE_PATH, puis dans le répertoire du module CMake.

Cela laisse beaucoup d'interprétation quant à ce que CMake considère comme un module par rapport à un fichier, car un module CMake est un fichier sur le système de fichiers après tout. Alors quelle est la différence?

Le code source de CMake est le seul endroit où j'ai pu trouver la réponse. Fondamentalement, CMake considère l'argument de include() comme un fichier s'il ressemble à un chemin absolu. Ça signifie:

  • Sous Linux/Unix
    • L'argument commence par '/' ou '~'
  • Sous Windows
    • Le deuxième caractère de l'argument est ':' (comme dans C :)
    • L'argument commence par '\'

CMake suppose que tout ce qui ne répond pas aux critères ci-dessus est un module. Dans ce cas, il ajoute ".cmake" à l'argument et recherche le CMAKE_MODULE_PATH.

10
mshildt

Le fichier est le fichier de liste CMake, l'exemple est CMakeLists.txt. Utilisez la commande suivante pour obtenir la liste des commandes utilisées dans

cmake --help-command-list 

Le module est un fichier cmake (* .cmake) qui contient des commandes cmake.

Comme le dit Matt B., la CMAKE_MODULE_PATH n'est pas une variable d'environnement de votre Shell, mais une variable cmake.

Pour ajouter le chemin de votre module à CMAKE_MODULE_PATH

LIST(APPEND CMAKE_MODULE_PATH ${YourPath})

Ou si vous préférez que vos modules soient utilisés en premier

LIST(INSERT CMAKE_MODULE_PATH 0 ${Yourpath})
5
Ding-Yi Chen