web-dev-qa-db-fra.com

Installation de CMake (TARGETS dans les sous-répertoires)

Considérer ce qui suit CMakeLists.txt fichier:

add_subdirectory(execA)
add_subdirectory(libB)

install(TARGETS execA libB
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib)

J'obtiens l'erreur suivante:

install TARGETS given target "execA" which does not exist in this
  directory

execA et libB ont leur propre CMakeList.txt fichiers et se trouvent sous le répertoire project, ainsi que le répertoire de génération que j'exécute cmake (cmake ..):

project
  |------ CMakeList.txt (the one with the code)
  |----execA
  |      \- .cpp, .hpp and CMakelist.txt
  |----libB
  |      \- .cpp, .hpp and CMakelist.txt
  |---- lib
  |---- bin
  \---- build (where I´m commanding: $ cmake ..

Comment puis-je corriger cette erreur?

23
Mendes

Selon ce rapport de bogue , le flux de commandes install(TARGETS) accepte uniquement les cibles créées dans le même répertoire .

Vous devez donc déplacer l'appel add_library() dans le répertoire de niveau supérieur, ou diviser l'appel install(TARGETS) en appels par cible, et déplacer chacun d'eux dans le sous-répertoire correspondant.

Depuis CMake 3.13 install(TARGETS)peut fonctionner même avec des cibles créées dans d'autres répertoires.

install(TARGETS) peut installer des cibles qui ont été créées dans d'autres répertoires. Lorsque vous utilisez ces règles d'installation inter-répertoires, l'exécution de make install (ou similaire) d'un sous-répertoire ne garantit pas que les cibles des autres répertoires sont à jour.

15
Tsyvarev

Cela semble toujours être un point douloureux dans CMake 3.11.

Dans notre base de code, nous avons de nombreuses cibles définies dans des sous-répertoires et devons créer un assortiment d'installateurs avec différentes configurations et combinaisons (potentiellement chevauchantes) de cibles.

Voici ma solution:

  • Avant d'appeler add_subdirectory dans votre fichier racine CMakeLists.txt, créez une propriété GLOBAL avec les noms des cibles que vous souhaitez inclure dans votre programme d'installation.
  • Envelopper les fonctions de création de cible (add_executable, etc.) dans vos propres fonctions personnalisées. Dans ces fonctions, vérifiez si la cible est présente dans la propriété globale et appelez install en conséquence.

Cette approche vous permet de centraliser la configuration du programme d'installation.

Aussi: Pour prendre en charge la création de plusieurs programmes d'installation, nous remplissons notre liste globale avec d'autres propriétés du programme d'installation dans des fichiers .cmake distincts. Lorsque nous appelons cmake, nous transmettons le nom du fichier CMake de configuration du programme d'installation en tant qu'argument de ligne de commande. Notre fichier racine CMakeLists.txt appelle simplement include avec ce fichier.

4
Alex Goldberg

Même si cela aiderait à voir le CMakeLists.txt fichiers contenus dans les sous-répertoires, je suppose qu'ils contiennent add_executable et/ou add_library instructions pour créer vos trucs.
De plus, à cause de votre exemple, je suppose que vous utilisez le même nom de vos répertoires pour vos cibles.
Cela dit, vous devez savoir que les symboles définis dans un CMakeLists.txt le fichier d'un sous-répertoire n'est pas visible par défaut dans le contexte du CMakeLists.txt fichier dans le répertoire parent. Pour cette raison, vous devriez plutôt déplacer vos instructions install dans le CMakeLists.txt fichiers dans vos sous-répertoires.
Cela devrait résoudre le problème, si mes pensées étaient bonnes. Sinon, je vous suggère fortement de poster dans votre question également le contenu des autres fichiers mentionnés ci-dessus.

Quoi qu'il en soit, l'erreur est assez claire.
Le fichier qui contient l'instruction install pour la cible nommée X ne contient pas d'instruction de création de cible (add_executable et les autres) qui donne naissance à cette cible, il continue donc à dire que cette cible n'existe pas dans ce répertoire.

3
skypjack
0
phcerdan