2010-05-30 7 views
36

J'essaie d'utiliser add_custom_command pour générer un fichier pendant la construction. La commande n'a jamais semblé être exécutée, ainsi j'ai fait ce fichier de test.CMake add_custom_command n'est pas exécuté

cmake_minimum_required(VERSION 2.6) 

add_custom_command(
    OUTPUT hello.txt 
    COMMAND touch hello.txt 
    DEPENDS hello.txt 
) 

J'ai essayé en cours d'exécution:

cmake . 
make 

Et hello.txt n'a pas été générée. Qu'est ce que j'ai mal fait?

+0

add_custom_target [pourrait] (http://stackoverflow.com/a/15973676/704244) être une alternative à add_custom_command –

Répondre

23

Ajoutez ce qui suit:

add_custom_target(run ALL 
    DEPENDS hello.txt) 

Si vous êtes familier avec makefiles, cela signifie:

all: run 
run: hello.txt 
+0

Cela ne fonctionne pas, pour moi, CMake 3.6.1, OSX. Je l'ai fait ce qui suit dans mon CMakeLists.txt 'add_custom_command ( SORTIE hello.txt touche COMMAND ARGS Hello.txt DÉPEND hello.txt )' et 'a ajouté add_custom_target (Rassemblez tous les hello.txt DÉPEND ) ' – linello

+0

' add_custom_target' est exécuté à chaque fois, utilisez 'add_custom_command' comme préconisé par Rian au lieu de –

+0

@linello Supprimez les DEPENDS de votre appel' add_custom_command() ', cela crée une dépendance circulaire. Seul le 'add_custom_target()' devrait avoir l'argument DEPENDS ici. Cela fonctionne pour moi sur OS X quand vous corrigez cela (testé avec CMake 3.8.0). –

40

La solution add_custom_target(run ALL ... fonctionnera pour les cas simples lorsque vous avez une seule cible que vous êtes bâtiment, mais se décompose lorsque vous avez plusieurs cibles de niveau supérieur, par exemple application et tests.

J'ai rencontré ce même problème lorsque j'essayais de regrouper certains fichiers de données de test dans un fichier objet afin que mes tests unitaires ne dépendent d'aucun élément externe. Je l'ai résolu en utilisant add_custom_command et une magie de dépendance supplémentaire avec set_property.

add_custom_command(
    OUTPUT testData.cpp 
    COMMAND reswrap 
    ARGS testData.src > testData.cpp 
    DEPENDS testData.src 
) 
set_property(SOURCE unit-tests.cpp APPEND PROPERTY OBJECT_DEPENDS testData.cpp) 

add_executable(app main.cpp) 
add_executable(tests unit-tests.cpp) 

Alors maintenant testData.cpp sera généré avant est compilé unité tests.cpp, et tout le temps testData.src changements. Si la commande que vous appelez est vraiment lente, vous obtenez le bonus supplémentaire que lorsque vous construisez juste la cible de l'application, vous n'aurez pas à attendre pour cette commande (dont seul l'exécutable de tests a besoin) pour terminer.

Ce n'est pas montré ci-dessus, mais une application soigneuse de ${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories() maintiendra votre arborescence source propre des fichiers générés.

+4

Ce moment gênant où la meilleure réponse n'est pas celle avec une icône de contrôle vert :) Merci Rian! –

+2

'add_dependencies' ne devrait-il pas être en mesure de faire le travail de la ligne 'set_property (...'? – dom0

+0

Il y a tellement d'autres bonnes choses à propos de cmake, une des principales choses que j'aime vraiment, c'est les Generators (Makefiles, fichiers ninja, Visual Studio, Eclipse, etc ...) Le langage de CMake n'est pas aussi évolué que celui de n'importe quel langage de programmation de haut niveau, mais c'est très facile une fois que vous l'avez compris en quelques heures. Réfléchissez à ceci: Pourquoi y a-t-il autant de gens qui utilisent cmake au lieu d'autotools? C'est plus facile à apprendre et cela procure beaucoup plus d'avantages –