2010-08-07 9 views
17

J'ai un projet CMake qui contient du code et quelques fichiers de données (images pour être précis).Comment gérer au mieux les fichiers de données avec CMake?

Ma structure de répertoire est comme ceci:

  • src
  • données

src contient le code source, les données des fichiers de données. CMake suggère de construire des sources, donc quand j'appelle make, j'ai le programme exécutable, mais pas les fichiers de données, donc je ne peux pas exécuter le programme.

Bien sûr, make install copiera mes fichiers de données sur l'emplacement requis et le faire fonctionner, donc je développe comme ce moment:

  1. CMake -DCMAKE_INSTALL_DIR = dist
  2. <edit source code>
  3. make install
  4. dist/myprogram.exe

Ce n'est pas grave si je travaille avec la ligne de commande et un éditeur, mais j'ai récemment décidé de passer à Eclipse CDT. La génération d'un projet Eclipse à partir de CMake fonctionne très bien, mais l'exécution manuelle de la cible d'Eclipse à l'aide de la commande n'est pas très agréable.

Comment abordez-vous ce problème? Est-ce que votre programme a des algorithmes astucieux pour essayer de trouver son répertoire de données même si ce n'est pas là que se trouve le binaire? Ou n'utilisez-vous pas les builds sources?

Répondre

16

configure_file devrait résoudre ce problème.

Je dispose d'un fichier CMakeLists.txt dans mon répertoire de données qui contient les éléments suivants:

configure_file(data_file ${CMAKE_CURRENT_BINARY_DIR}/data_file COPYONLY) 

Cette copie le fichier spécifié dans le répertoire de construction lorsque CMake est invoquée, il est disponible dans le même endroit même dans des constructions hors de la source.

configure_file ne supporte pas les répertoires mais alors que la commande file fait:

file(COPY assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 
+3

dois-je faire pour chaque fichier séparément – Arne

+2

-je utiliser 'fichier (actifs COPIE DESTINATION $ {CMAKE_CURRENT_BINARY_DIR})' – WarmWaffles

11

Et si la copie des fichiers prend trop de temps (ils sont des images ...), vous pouvez le rendre encore meilleur en créant un " "data_header.h" personnalisé avec configure_file qui contient les chemins d'accès aux données toujours dans votre répertoire source.

C'est ce que je fais: j'ai un fichier "global_build_config.h.in" dans ma source, contenant les éléments suivants:

const char* const global_testdatapath = "@[email protected]"; 

puis utilisez CONFIGURE_FILE dans CMake:

# Assume CMake knows a variable Test_Data_Path, it will be filled in automatically 
# in the generated config/Global_Build_Config.h 
configure_file(Global_Build_Config.h.in ${CMAKE_BINARY_DIR}/config/Global_Build_Config.h) 
# The config directory should be added as a include-searchpath 
include_directories(${CMAKE_BINARY_DIR}/config/) 

Je peux alors # inclure "Global_Build_Config.h" dans mes fichiers cpp et me référer au chemin fixe.

+0

vous devez savoir que cet emballage de faire du projet beaucoup plus compliqué, parce que pour une construction du paquet cmake doit être exécuté à nouveau pour ne pas mentionner le code extre cmake que vous devez écrire. – Arne

2

Votre question est un peu vieux, mais si vous êtes toujours intéressé (ou quelqu'un d'autre), j'ai un scénario similaire où je copie testdata pour une cible de test d'unité:

add_custom_command(TARGET ${UTEST_EXE_NAME} 
    POST_BUILD 
    COMMAND ${CMAKE_COMMAND} -E echo "Copying unit test data.." 
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_HOME_DIRECTORY}/utest/testdata ${CMAKE_BINARY_DIR} 
    ) 

Ainsi, le L'idée principale est d'utiliser une cible post-build, et elle est exécutée après chaque build. Pour moi, ce n'est pas beaucoup de données, et le système de fichiers le met en cache, donc je ne ressens pas du tout le processus de copie. Vous pourriez probablement améliorer cela en copiant avec copy_if_different. Dans ce cas, cependant, vous devez créer une liste de vos fichiers image et écrire une boucle, car la commande est basée sur un fichier. Avec la commande GLOB, cela ne devrait pas être difficile à faire si vous en avez besoin.

Questions connexes