CMake add_custom_command pas en cours d'exécution
Je suis en train d'utiliser add_custom_command pour générer un fichier lors de la compilation. La commande ne semblait jamais être exécuté, alors j'ai fait ce fichier de test.
cmake_minimum_required( VERSION 2.6 )
add_custom_command(
OUTPUT hello.txt
COMMAND touch hello.txt
DEPENDS hello.txt
)
J'ai essayé de courir:
cmake .
make
Et hello.txt n'a pas été généré. Qu'ai-je fait de mal?
- add_custom_target peut une alternative à add_custom_command
Vous devez vous connecter pour publier un commentaire.
Ajouter les éléments suivants:
Si vous êtes familier avec les makefiles, cela signifie:
add_custom_command( OUTPUT hello.txt COMMAND touch ARGS hello.txt DEPENDS hello.txt )
et a ajoutéadd_custom_target(run ALL DEPENDS hello.txt )
add_custom_target
est exécuté à chaque fois, utilisezadd_custom_command
, tel que préconisé par Rian au lieuadd_custom_command()
appel, il crée une dépendance circulaire. Seul leadd_custom_target()
devrait avoir le DÉPEND argument ici. Il fonctionne pour moi sur OS X lorsque vous corrigez ce (testé avec CMake 3.8.0).La
add_custom_target(run ALL ...
la solution pour les cas simples lorsque vous n'avez qu'une seule cible que vous êtes en train de construire, mais se décompose lorsque vous avez plusieurs haut niveau des objectifs, par exemple, d'application et les tests.J'ai rencontré ce même problème quand j'étais en train d'empaqueter des données de test des fichiers dans un fichier d'objet donc mes tests unitaires ne dépendent pas des choses à l'extérieur. Je l'ai résolu en utilisant
add_custom_command
et quelques autres de la dépendance de la magie avecset_property
.Alors maintenant testData.cpp sera généré en avant unit-tests.cpp est compilé, et de tout temps testData.src changements. Si la commande que vous avez demandé est vraiment lent, vous obtenez le bonus ajouté que lorsque vous créez une application cible, vous n'aurez pas à attendre autour pour cette commande (qui seuls les tests exécutables besoins) à la fin.
Il n'est pas indiqué ci-dessus, mais attention à l'application de
${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories()
de garder votre arborescence des sources de nettoyer des fichiers générés.add_dependencies
être en mesure de faire le travail de laset_property(...
ligne?add_dependencies
, mais il devient un peu difficile. Vous ne pouvez pas ajouter directement une dépendance entreadd_custom_command
et quelque chose d'autre, vous devez d'abord créer unadd_custom_target
(qui est vide, il sert simplement à fournir une cible, vous pouvez nom plus tard). La raison en est queadd_dependencies
ne peut prendre une cible comme un argument, pas un fichier. Voir ce blog pour plus d': samthursfield.wordpress.com/2015/11/21/...Le problème avec les deux réponses est qu'ils font de la dépendance mondiale (
add_custom_target(name ALL ...)
), ou l'attribuer à un seul fichier (set_property(...)
) qui devient désagréable si vous avez beaucoup de fichiers qui ont besoin de lui comme une dépendance. Au lieu de ce que nous voulons, c'est un objectif que nous pouvons faire un dépendance d'une autre cible.La façon de le faire est d'utiliser
add_custom_command
de définir la règle, puisadd_custom_target
pour définir une nouvelle cible basée sur la règle. Ensuite, vous pouvez ajouter cette cible d'une dépendance d'une autre cible viaadd_dependencies
.Les avantages de cette approche:
some_target
n'est pas une dépendance pourALL
, ce qui signifie que vous ne construire que lorsque c'est requis par une cible spécifique. (Alors queadd_custom_target(name ALL ...)
serait de construire sans condition de toutes les cibles.)some_target
est une dépendance de la bibliothèque dans son ensemble, il va se construire avant de tous les fichiers dans la bibliothèque. Cela signifie que si il y a beaucoup de fichiers dans la bibliothèque, nous n'avons pas à faireset_property
sur chaque un seul d'entre eux.DEPENDS
àadd_custom_command
alors qu'elle reconstruit lors de ses entrées de changement. (Comparez cela à l'approche qui utiliseadd_custom_target(name ALL ...)
où la commande est exécutée sur chaque génération, indépendamment de savoir s'il doit ou non).Pour plus d'informations sur pourquoi les choses fonctionnent de cette manière, consultez cet article de blog: https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/