web-dev-qa-db-fra.com

Copier le fichier du répertoire source vers le répertoire binaire à l'aide de CMake

J'essaie de créer un projet simple sur CLion. Il utilise CMake (je suis nouveau ici) pour générer des Makefiles afin de construire un projet (ou une sorte de celui-ci)

Tout ce dont j'ai besoin est de transférer un fichier non-projet (une sorte de fichier de ressources) dans un répertoire binaire chaque fois que j'exécute le code.

Ce fichier contient des données de test et une application l’ouvrent pour les lire. J'ai essayé plusieurs façons de le faire:

  • Via file(COPY ...

    file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
            DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/input.txt
    

    Vous cherchez bien mais cela ne fonctionne qu'une fois et ne pas recopier le fichier après la prochaine exécution.

  • Via add_custom_command

    • OUTPUT version

      add_custom_command(
              OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/input.txt
              COMMAND ${CMAKE_COMMAND} -E copy
                      ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
                      ${CMAKE_CURRENT_BINARY_DIR}/input.txt)
      
    • TARGET version

      add_custom_target(foo)
      add_custom_command(
              TARGET foo
              COMMAND ${CMAKE_COMMAND} copy
                      ${CMAKE_CURRENT_BINARY_DIR}/test/input.txt
                      ${CMAKE_SOURCE_DIR})
      

    Mais personne ne travaille.

Qu'est-ce que je fais mal?

70
mongolrgata

Vous pouvez envisager d'utiliser configure_file avec l'option COPYONLY:

configure_file(<input> <output> COPYONLY)

Contrairement à file(COPY ...), il crée une dépendance au niveau du fichier entre l'entrée et la sortie, à savoir:

Si le fichier d'entrée est modifié, le système de construction réexécutera CMake pour reconfigurer le fichier et générer à nouveau le système de construction.

102
tamas.kenez

les deux options sont valides et ciblent deux étapes différentes de votre construction:

  1. file(COPY ... copie le fichier à l'étape de configuration et uniquement à cette étape. Lorsque vous reconstruisez votre projet sans avoir modifié votre configuration de cmake, cette commande ne sera pas exécutée.
  2. add_custom_command est le choix par défaut lorsque vous souhaitez copier le fichier à chaque étape de la construction.

La bonne version pour votre tâche serait:

add_custom_command(
        TARGET foo POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
                ${CMAKE_SOURCE_DIR}/test/input.txt
                ${CMAKE_CURRENT_BINARY_DIR}/input.txt)

vous pouvez choisir entre PRE_BUILD, PRE_LINK, POST_BUILD mieux lisez-vous la documentation de add_custom_command

un exemple d'utilisation de la première version est disponible ici: tilisez CMake add_custom_command pour générer le code source d'une autre cible

46
jenseb

La première option que vous avez essayée ne fonctionne pas pour deux raisons.

Tout d'abord, vous avez oublié de fermer la parenthèse.

Deuxièmement, la DESTINATION devrait être un répertoire et non un nom de fichier. En supposant que vous ayez fermé la parenthèse, le fichier se retrouverait dans un dossier appelé input.txt.

Pour que cela fonctionne, il suffit de le changer pour

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
     DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
11
German Capuano

Le fichier configure_file suggéré est probablement la solution la plus simple. Toutefois, la commande de copie ne sera pas réexécutée si vous avez supprimé manuellement le fichier du répertoire de construction. Pour traiter également ce cas, les éléments suivants fonctionnent pour moi:

add_custom_target(copy-test-makefile ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/input.txt)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/input.txt
                   COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
                                                    ${CMAKE_CURRENT_BINARY_DIR}/input.txt
                   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.txt)
0
ar31

Je suggérerais TARGET_FILE_DIR si vous voulez que le fichier soit copié dans le même dossier que votre fichier .exe.

$ Répertoire du fichier principal (.exe, .so.1.2, .a).

add_custom_command(
  TARGET ${PROJECT_NAME} POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy 
    ${CMAKE_CURRENT_SOURCE_DIR}/input.txt 
    $<TARGET_FILE_DIR:${PROJECT_NAME}>)

Dans VS, ce script cmake copiera input.txt dans le même fichier que votre exe final, qu’il soit en cours de débogage ou de publication.

0
Felix Xu