web-dev-qa-db-fra.com

Ajout de plusieurs exécutables dans CMake

Mon code dans un projet C++ est organisé comme suit

  • J'ai plusieurs fichiers .cpp Et .h Qui contiennent mes classes
  • J'ai plusieurs fichiers .cxx Qui doivent être compilés avec les fichiers .cpp Et certaines bibliothèques externes.

Maintenant, chacun des fichiers .cxx A une méthode main(), j'ai donc besoin d'ajouter un exécutable différent pour chacun de ces fichiers portant le même nom que le fichier.

De plus, ces fichiers .cxx Peuvent ne pas être liés aux mêmes bibliothèques externes.

Je veux écrire cette version dans CMake, dans laquelle je suis un peu novice, comment dois-je procéder?

59
ssb

Ma suggestion est d'aborder cela en deux phases:

  1. Créez une bibliothèque à partir des fichiers .cpp Et .h, En utilisant add_library
  2. Parcourez tous vos fichiers .cxx Et créez un exécutable à partir de chacun, en utilisant add_executable et foreach

Construisez la bibliothèque

Cela pourrait être quelque chose d'aussi simple que

file( GLOB LIB_SOURCES lib/*.cpp )
file( GLOB LIB_HEADERS lib/*.h )
add_library( YourLib ${LIB_SOURCES} ${LIB_HEADERS} )

Construisez tous les exécutables

Parcourez simplement tous les fichiers .cpp et créez des exécutables séparés.

# If necessary, use the RELATIVE flag, otherwise each source file may be listed 
# with full pathname. RELATIVE may makes it easier to extract an executable name
# automatically.
# file( GLOB APP_SOURCES RELATIVE app/*.cxx )
file( GLOB APP_SOURCES app/*.cxx )
foreach( testsourcefile ${APP_SOURCES} )
    # I used a simple string replace, to cut off .cpp.
    string( REPLACE ".cpp" "" testname ${testsourcefile} )
    add_executable( ${testname} ${testsourcefile} )
    # Make sure YourLib is linked to each app
    target_link_libraries( ${testname} YourLib )
endforeach( testsourcefile ${APP_SOURCES} )

Quelques avertissements:

  • file( GLOB ) n'est généralement pas recommandé, car CMake ne sera pas reconstruit automatiquement si un nouveau fichier est ajouté. Je l'ai utilisé ici, car je ne connais pas vos fichiers sources.
  • Dans certaines situations, les fichiers source peuvent être trouvés avec un chemin d'accès complet. Si nécessaire, utilisez le drapeau RELATIF pour find( GLOB ... ) .
  • La définition manuelle des fichiers source nécessite une modification de CMakeLists.txt, qui déclenche une reconstruction. Voir cette question pour les (dés) avantages du globbing.
  • J'ai généré le nom du test à l'aide d'une string( REPLACE ... ). J'aurais pu utiliser get_filename_component avec le drapeau NAME_WE.

Concernant les informations "générales" de CMake, je vous conseille de lire quelques-unes des grandes questions "CMake Overview" déjà posées ici sur stackoverflow. Par exemple.:

89
André