IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

gestion de dépendences


Sujet :

C++

  1. #1
    Membre averti Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Points : 341
    Points
    341
    Par défaut gestion de dépendences
    Hello !

    Je m'essaie à la gestion de dépendances, et ce n'est pas glorieux.

    J'ai un projet lib_A qui nécessite deux librairies header-only lib_B (que je maintiens) et sqlite3pp trouvables sur github, et puis aussi Boost, GDAL et Sqlite3. J'essaie de faire des CMakeLists pour lib_A et lib_B qui gèrent à peu près ça correctement. Mais je ne sais pas ce qu'une solution "correcte" est censée faire :/ Est-ce posssible de faire en sorte que l'utilisateur aie seulement à écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    git clone lib_A
    cd lib_A
    mkdir build
    cmake ..
    make install
    make test
    ... et que ça se charge tout seul de trouver les dépendances, identifie les bonnes versions, les installe si besoin (si oui où?), lance les tests etc ? Je n'ai d'ailleurs toujours pas compris si les tests étaient censés faire partie de l'installation. Et je n'ai pas compris ce qu'installer une librairie headeronly signifiait concrètement (la rendre findpackage compatible? La déplacer à une localisation standard ?).

    Pour l'instant je bricole et c'est pas très beau à voir.

    Pour pouvoir utiliser find_package(lib_B), j'ai suivi ce tuto https://dominikberner.ch/cmake-interface-lib/. Mais quand j'écris cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/your/installation/path, je suis censé choisir quoi ? /usr/local ? Et les includes de lib_B sont censés arriver où ? dans usr/local/include/lib_B ? Et pourquoi ça a créé un usr/local/share/LIB_B ?

    A ce point, si lib_B est installée, je peux la trouver dans le CMakeLists de lib_A. Mais si elle n'est pas installée, je ne sais pas comment procéder. J'ai l'impression que la solution devrait ressembler à ce que j'essaie de faire pour gérer la dépendance à sqlit3pp: j'ai essayé de suivre ce tutoriel https://foonathan.net/2016/07/cmake-...ency-handling/ qui utilise les git submodules mais pour l'instant ça marche pas lol. Et en même temps d'autres décrient l'utilisation des submodules.

    Que me conseillez-vous ? Le copy-pasting ça pourrait marcher pour sqlite3pp qui est toute petite, mais pas pour lib_B qui est pas vraiment stable.

    Si vous aviez aussi un textbook sur le cmake modern ou les build systems ou la gestion de dépendances à me conseiller ... j'ai l'impression de découvrir un tout autre aspect de la programmation, et pour l'instant je trouve ça très flou, je n'en suis même pas au point où j'arrive à formuler mes questions clairement

    En vous passant le bonjour des contrées glaciales du Michigan ...
    Le débutant, lui, ignore qu'il ignore à ce point, il est fier de ses premiers succès, bien plus qu'il n'est conscient de l'étendue de ce qu'il ne sait pas, dès qu'il progresse en revanche, dès que s'accroît ce qu'il sait, il commence à saisir tout ce qui manque encore à son savoir. Qui sait peu ignore aussi très peu. [Roger Pol-Droit]
    Github
    Mon tout premier projet: une bibliothèque de simulation de génétique des populations

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    Le plus facile est encore de gérer tes deux bibliothèques dans la même arborescence CMake, sous une forme qui serait proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <root_directory>
    |-> lib
    |    |->lib_a
    |    |    |->include   #contient les fichiers d'en-tête pour lib_a
    |    |    |->src        #contient les fichier .cpp pour lib_a
    |    |->lib_b
    |    |     |->include #pareil mais pour lib_b  
    |    |     |-> src
    A partir de là, tu aurais un CMakeLists.txt dans les dossiers
    1. root_direcory
    2. lib
    3. lib_a
    4. lib_b

    et il prendraient respectivement la forme de
    <root_directory>/CMakeLists.txt
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    project(NomDuProjetGlobal VERSION LANGUAGES CXX)
    # toute la configuration globale (dépendances externes, 
    # version du standard C++ à respecter,
    # ...)
     
    add_subdirectory(lib)   #va automatiquement chercher le fichier lib/CMakeLists.txt
    # si tu as d'autres répertoires "de premier niveau" (ex:
    # doc
    # tests
    # examples
    # ...)
    # tu les ajoutes également avec add_subdirectory
    # (ils devront aussi contenir leur CMakeLists.txt)

    Au niveau du dossier lib, il suffira ajouter les dossier lib_a et lib_b au fichier CMakeLists.txt qui prendra du coup la forme de
    <root_directory>/lib/CMakeLists.txt
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    add_subdirectory(lib_a)
    add_subdirectory(lib_b)
    Selon ton exemple, lib_a dépend de lib_b, tu pourra donc avoir quelque chose de proche de
    <root_directory>/lib/lib_a/CMakeLists.txt
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #chaque bibliothèque représente un projet différent
    project(lib_a VERSION 1.0.0.0 LANGUAGES CXX)
    # par facilité, je te conseillerais de créer une liste
    # contenant les fichier d'en-tete et une autre contenant
    # les fichier d'implémentation, sous la forme de
    set(HEADERS include/en-tete_1.hpp
                inclulde/en-tete_2.hpp
                # ...
                )
    set(SRCS src/implementation_1.cpp
             src/implementation_2.cpp
             # ...
             )
    # on récupère le nom du projet comme nom de cible, c'est le plus facile
    set(TARGET_NAME ${PROJECT_NAME})
    # par facilité, on défini le dossier dans lequel se trouve les fichiers d'en-tête
    set(INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
    # on cree une bibliothèque objet pour ne pas devoir compiler 
    # deux fois nos fichiers si on veut une version statique et une version
    # dynamique
    add_libary(${TARGET_NAME}_obj OBJECT "")
    # certains anciens compilateur ont besoin de cette information
    set_target_properties(${TARGET_NAME}_obj
      PROPERTIES
        POSITION_INDEPENDENT_CODE 1
    )
    # on défini les source de cette cible: les fichiers d'en-tête
    # sont publiques, les fichier d'implémentation sont privés
    target_sources(${TARGET_NAME}_obj
        PUBLIC ${HEADERS}
        PRIVATE ${SRCS})
    # on ajoute le dossier include à la liste des dossiers
    # dans lesquels chercher les en-tête
    target_include_directories(${TARGET_NAME}_obj ${INC_DIR})
     
    # si on veut une version statique de la bibliothèque:
    if(LIB_A_BUILD_STATIC)
        add_library(${TARGET_NAME}-static
            STATIC
            $<TARGET_OBJECTS:${TARGET_NAME}_obj>
        )
        set_target_properties(${TARGET_NAME}-static
            PROPERTIES
            OUTPUT_NAME "${TARGET_NAME}"
        )
        #on indique la dépendance avec lib_b
        target_link_libraries(lib_b)
    endif()
    # si on veut une version dynamique de la bibliothèque
    if(LIB_A_BUILD_SHARED
        add_library(${TARGET_NAME}-shared
            SHARED
                $<TARGET_OBJECTS:${TARGET_NAME}_obj >
        )
        set_target_properties(${TARGET_NAME}-shared
        PROPERTIES
            OUTPUT_NAME "${TARGET_NAME}"
        )
     
        #on indique la dépendance avec lib_b
        target_link_libraries(lib_b)
    endif()
    (note que j'ai donné une version très allégée, mais qui fonctionne de ce CMakeLists.txt ... tu peux le modifier à ta guise )

    Et comme tu semble dire que lib_b est une bibliothèque header-only, on va la définir comme suit
    <root_directory>/lib/lib_a/CMakeLists.txt
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # la base sera sensiblement la même que pour lib_a
    # je ne copie pas le commentaires déjà donnés
    project(lib_a VERSION 1.0.0.0 LANGUAGES CXX)
    set(HEADERS include/header_1.hpp
               include/header_2.hpp
               # ...
    )
     
    set(TARGET_NAME ${PROJECT_NAME})
    set(INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
    add_library(${TARGET_NAME} INTERFACE)
    # pour ajouter le dossier include à la liste des dossiers utilisés
    # lors de la recherche des fichier d'en-tête (au moment de la
    # compilation de lib_a, entre autres)
    target_include_directories(${TARGET_NAME } INTERFACE ${INC_DIR})
    #pour que le script de CMake sache quoi faire et quand le faire
    target_include_directories(${TARGET_NAME } INTERFACE
        $<BUILD_INTERFACE: ${INC_DIR}>
        $<INSTALL_INTERFACE: ${TGNAME}>
    )

    Maintenant, tu n'es absolument pas obligé de suivre ce conseil, et tu peux donc tout à fait gérer tes deux projets de manière séparée...

    Je vais donc répondre à tes questions dans l'ordre
    Pour pouvoir utiliser find_package(lib_B), j'ai suivi ce tuto https://dominikberner.ch/cmake-interface-lib/. Mais quand j'écris cmake .. -DCMAKE_INSTALL_PREFIXATH=/your/installation/path, je suis censé choisir quoi ? /usr/local ? Et les includes de lib_B sont censés arriver où ? dans usr/local/include/lib_B ? Et pourquoi ça a créé un usr/local/share/LIB_B ?
    Pas frocément...

    /usr/locak/lib_B, ca serait parfait sous linux, parce que c'est en accord avec les conventions en usage avec ce système d'exploitation.

    Mais, si tu es sous windows, ce que je te conseillerais, c'est de créer un dossier en racine de disque dur (par exemple : C:\mylibs ) dans lequel tu placerais l'ensemble des bibliothèques que tu as toi-même installée, et qui reprendrait l'arborescence "classique" proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    c:\mylibs
    |->bin         # les dlls, s'il y en a
    |->include   # Tous les fichiers d'en-tête des bibliothèques installées par tes soins
    |    |->lib1   # les fichier d'en-tête de chaque bibliothèque étant
    |    |->lib2   # dans  un dossier séparé
    |    |-> #...
    |->lib          # bibliothèques compilées ( *.lib / .a, selon le compilateur)
    |                 # "en vrac" (pas de séparation en fonction de la bilbiothèque)
    |->share     # les documents "partagés" (s'il y en a) comme
    |    |->cmake # tous les fichiers nécessaires à cmake, en vrac
    |    |->doc   # la documentation
    |    |    |->lib1 # triée par bibliothèque
    à moins d'inverser carrément l'ordre dans lequel les dossiers apparaissent, et d'avoir une arborescence plus proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    c:\mylibs   # lui ne change pas
    |->lib1   # chaque bibliothèque a son propre dossier contenant
    |    |->bin # les exécutables (.exe / .dll) s'il y en a
    |    |->doc # la documentaton (si elle existe)
    |    |->include # les fichier d'en-tête
    |    |->lib  # la bibliothèque compilée (.lib / .a selon le compilateur) si elle existe
    |->lib2 # tout pareil à lib1
    |    |->bin 
    |    |->doc 
    |    |->include 
    |    |->lib  
    |-> #...
    La grosse difficulté consistant à faire savoir à CMake où se trouve lib_b dans ton arborescence lorsqu'il voudra chercher la dépendance au travers de find_package pour compiler lib_a

    L'idéal serait sans doute de demander à la personne qui essaye de compiler lib_a de fournir une variable (mettons LIB_B_DIR) qui le lui indique sous forme d'une option proche de -DLIB_B_DIR=C:\mylibs (ou sous la forme de c]-DLIB_B_DIR=C:\mylibs\lib_b[/c] si tu a choisi la deuxième arborescence proposée)

    A ce point, si lib_B est installée, je peux la trouver dans le CMakeLists de lib_A. Mais si elle n'est pas installée, je ne sais pas comment procéder. J'ai l'impression que la solution devrait ressembler à ce que j'essaie de faire pour gérer la dépendance à sqlit3pp: j'ai essayé de suivre ce tutoriel https://foonathan.net/2016/07/cmake-...ency-handling/ qui utilise les git submodules mais pour l'instant ça marche pas lol. Et en même temps d'autres décrient l'utilisation des submodules.

    Que me conseillez-vous ?
    Je te conseillerais le "superbuild pattern". Pour faire simple, tu ajoute un dossier 3rdparty (ou tout autre nom de ton choix) dans lequel tu demandera à CMake de récupérer (au travers de git, dans ton cas) la dernière version de la bibliothèque dont tu as besoin, de la configurer et de la compiler (au besoin) de manière à pouvoir définir les dépendances adéquate.

    Le copy-pasting ça pourrait marcher pour sqlite3pp qui est toute petite, mais pas pour lib_B qui est pas vraiment stable.
    Non, décidément, même avec une bibliothèque stable, ce ne serait pas la solution
    Si vous aviez aussi un textbook sur le cmake modern ou les build systems ou la gestion de dépendances à me conseiller ... j'ai l'impression de découvrir un tout autre aspect de la programmation, et pour l'instant je trouve ça très flou, je n'en suis même pas au point où j'arrive à formuler mes questions clairement
    J'ai mieux que cela : ==>un dépôt git<== qui fournit tout plein d'exemples et qui est associé à un bouquin (payant, et en anglais, malheureusement).

    Mais rien que les exemples présentés sur ce dépôt sont vraiment clairs et compréhensibles. Les codes que je t'ai fournis en sont d'ailleurs largement inspirés

    Je n'ai fait que feuilleter quelques pages du bouquin dont la version papier est relativement chère (de l'ordre de 50€ et plus), mais en format kindle, il n'est qu'à 28€ et quelques. Je ne me risquerai donc pas à en donner un avis éclairé, d'autant plus que les avis que l'on trouve (entre autres sur amazon) sont très variés.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre averti Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Points : 341
    Points
    341
    Par défaut
    Wooooooh koala01 tes réponses sont toujours aussi bluffantes !

    Ok, bon grâce à toi je sais quoi chercher maintenant !

    Quelques petites questions parce que j'ai du mal à comprendre les abstractions de cmake:

    • c'est quoi une target ? De ce que je comprends ça semble désigner une bibliothèque ? A peu près tout et n'importe quoi (everything is a target) ?
    • c'est quoi une property ? De ce que je comprends c'est toutes les options définies au moment de l'installation de la bibliothèque.
    • est-ce que exporter une lib, c'est équivalent à la rendre find_package compatible?
    • installer une lib, ça veut dire quoi concrètement ? compiler, lancer les tests, déplacer des fichiers, écrire des fichiers pour que cmake puisse trouver la lib par findpackage ?
    • que fais le fichier libConfigure.cmake.in ?
    • j'ai du mal à faire la différence entre dépendance publique et privée. Je comprends qu'une dépendance privée c'est par exemple boost si j'ai besoin de boost:ublas dans mes algos, mais alors je ne comprends pas la dépendance publique.


    Aussi, quelle est la différence entre écrire:

    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    FIND_PACKAGE(Boost COMPONENTS unit_test_framework system filesystem REQUIRED)
    IF (Boost_FOUND)
        INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
        ADD_DEFINITIONS(-DBOOST_UBLAS_NDEBUG)
    ENDIF()

    et :
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    find_package(Boost REQUIRED)
    add_library(boost INTERFACE IMPORTED)
    set_property(TARGET boost PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})

    J'ai aussi écrit ça:

    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    # Include Gdal
    FIND_PACKAGE(GDAL)
    IF (GDAL_FOUND)
        INCLUDE_DIRECTORIES(${GDAL_INCLUDE_DIR})
    ENDIF()

    ça marche, c'est cool, mais j'ai lu quelque part cmake définit une fonction FindGDAL, je suis censé l'utiliser ?
    Merci!
    Le débutant, lui, ignore qu'il ignore à ce point, il est fier de ses premiers succès, bien plus qu'il n'est conscient de l'étendue de ce qu'il ne sait pas, dès qu'il progresse en revanche, dès que s'accroît ce qu'il sait, il commence à saisir tout ce qui manque encore à son savoir. Qui sait peu ignore aussi très peu. [Roger Pol-Droit]
    Github
    Mon tout premier projet: une bibliothèque de simulation de génétique des populations

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par Seabirds Voir le message
    Wooooooh koala01 tes réponses sont toujours aussi bluffantes !
    De rien, un tel enthousiasme dans les remerciements fait toujours plaisir

    Ok, bon grâce à toi je sais quoi chercher maintenant !

    Quelques petites questions parce que j'ai du mal à comprendre les abstractions de cmake:
    • c'est quoi une target ? De ce que je comprends ça semble désigner une bibliothèque ? A peu près tout et n'importe quoi (everything is a target) ?
    Je ne t'apprendrai surement rien en te disant que "target" en anglais se traduit par "cible" en français

    Et donc, un target correspond effectivement à tout ce qui peut être effectué (au niveau du projet général) depuis la commande cmake --build . --target <target name> (remplace <target name> par help pour avoir une liste de toutes les cibles possible pour ton projet).

    En gros, cela signifie:
    • la compilation des parties qui le nécessite
    • l'installation
    • les tests
    • et sans doute bien d'autre chose encore

    Chaque fois que tu définis une nouvelle bibliothèque (avec la commande add_library, tu ajoute effectivement une nouvelle cible à ton projet général. Mais pas seulement: Quand tu ajoute une application (add_binary()), quand tu précise une procédure d'installation (install(XXX)) ou même quand tu prévois le packaging (mais je ne suis pas trop sur), tu ajoute également de nouvelles cibles.

    On es donc beaucoup plus proche du "tout et n'importe quoi" en définitive
    • c'est quoi une property ? De ce que je comprends c'est toutes les options définies au moment de l'installation de la bibliothèque.
    Cela va même beaucoup plus loin, car c'est plus proche de "tout ce qui permet d'adapter le comportement des différents scripts" pour "n'importe quelle cible".

    [LIST][*]est-ce que exporter une lib, c'est équivalent à la rendre find_package compatible?[/LIB]
    sur ce point, je vais plutôt te ramener vers la documentation officielle:

    Pour ce que j'en comprend, c'est le moyen de faire connaitre une bibliothèque externe, générée en même temps que ton projet, de toutes les cibles qui pourraient en dépendre (voir de placer cette bibliothèque dans un espace de nom
    • installer une lib, ça veut dire quoi concrètement ? compiler, lancer les tests, déplacer des fichiers, écrire des fichiers pour que cmake puisse trouver la lib par findpackage ?
    Installer une bibliohèque, cela revient ni plus ni moins à copier l'ensemble des fichiers générés dans le dossier dans lequel l'utilisateur souhaite pouvoir y accéder

    Cela n'a rien à voir avec le build (qui représente la compilation) ni avec l'exécution des tests; même si l'installation ne peut pas avoir lieu avant le build

    • que fais le fichier libConfigure.cmake.in ?
    L'extension .in est l'extension (que je présume récupérée des autotools) généralement utilisée pour représenter un fichier modèle, qui attend "un certain nombre" de valeurs qui ne pourront être définie qu'à la configuration.
    Elle est souvent associée au nom du fichier qui sera créé, extension comprise, et utilisée avec la commande configure_file

    Dans le cas présent, il est fort vraisemblable qu'elle produira, quelque part dans le dossier représenter par CMAKE_CURRENT_BIN_DIR un fichier nommé LibConfigure.cmake qui sera utilisé pour la suite des différents processus

    Notes au passage que tu n'es absolument pas tenu à respecter cette extension .in, si ce n'est, bien sur, par les conventions et habitudes de chacuns

    Pour te donner une idée de ce que l'on peut faire, voici quelques utilisation perso:
    pour configurer doxygen sur base de choix fournis par la personne qui veut compiler un projet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    DOXYFILE_ENCODING      = UTF-8
     
    PROJECT_NAME           = @PROJECT_NAME@
     
    PROJECT_NUMBER         = @PROJECT_VERSION@
     
     
    PROJECT_BRIEF          = @PROJECT_BRIEF@
     
    PROJECT_LOGO           = @PROJECT_LOGO@
     
    OUTPUT_DIRECTORY       = @outdir@
     
    CREATE_SUBDIRS         = NO
     
    ALLOW_UNICODE_NAMES    = NO
     
    OUTPUT_LANGUAGE        = English
     
    BRIEF_MEMBER_DESC      = YES
     
    REPEAT_BRIEF           = YES
     
    ABBREVIATE_BRIEF       = "The $name class" \
                             "The $name widget" \
                             "The $name file" \
                             is \
                             provides \
                             specifies \
                             contains \
                             represents \
                             a \
                             an \
                             the
     
     
    ALWAYS_DETAILED_SEC    = YES
     
    INLINE_INHERITED_MEMB  = YES
     
    FULL_PATH_NAMES        = NO
     
    STRIP_FROM_PATH        =
     
    STRIP_FROM_INC_PATH    =
     
    SHORT_NAMES            = NO
     
    JAVADOC_AUTOBRIEF      = NO
     
    QT_AUTOBRIEF           = NO
     
    MULTILINE_CPP_IS_BRIEF = NO
     
    INHERIT_DOCS           = YES
     
    SEPARATE_MEMBER_PAGES  = NO
     
    TAB_SIZE               = 4
     
    ALIASES                =
     
    TCL_SUBST              =
     
    OPTIMIZE_OUTPUT_FOR_C  = NO
     
    OPTIMIZE_OUTPUT_JAVA   = NO
     
    OPTIMIZE_FOR_FORTRAN   = NO
     
    OPTIMIZE_OUTPUT_VHDL   = NO
     
    EXTENSION_MAPPING      =
     
    MARKDOWN_SUPPORT       = YES
     
    TOC_INCLUDE_HEADINGS   = 6
     
    AUTOLINK_SUPPORT       = YES
     
    BUILTIN_STL_SUPPORT    = YES
     
    CPP_CLI_SUPPORT        = NO
     
    SIP_SUPPORT            = NO
     
    IDL_PROPERTY_SUPPORT   = YES
    DISTRIBUTE_GROUP_DOC   = NO
     
    GROUP_NESTED_COMPOUNDS = YES
     
    SUBGROUPING            = YES
     
    INLINE_GROUPED_CLASSES = YES
     
    INLINE_SIMPLE_STRUCTS  = YES
     
    TYPEDEF_HIDES_STRUCT   = YES
     
    LOOKUP_CACHE_SIZE      = 0
     
    EXTRACT_ALL            = YES
     
    EXTRACT_PRIVATE        = YES
     
    EXTRACT_PACKAGE        = YES
     
    EXTRACT_STATIC         = YES
     
    EXTRACT_LOCAL_CLASSES  = YES
     
    EXTRACT_LOCAL_METHODS  = YES
     
    EXTRACT_ANON_NSPACES   = YES
     
    HIDE_UNDOC_MEMBERS     = NO
     
    HIDE_UNDOC_CLASSES     = NO
     
    HIDE_FRIEND_COMPOUNDS  = NO
     
    HIDE_IN_BODY_DOCS      = NO
     
    INTERNAL_DOCS          = @DOXYGEN_INTERNAL@
     
    CASE_SENSE_NAMES       = YES
     
    HIDE_SCOPE_NAMES       = @DOXYGEN_HIDE_SCOPES@
     
    HIDE_COMPOUND_REFERENCE= NO
     
    SHOW_INCLUDE_FILES     = YES
     
    SHOW_GROUPED_MEMB_INC  = YES
     
    FORCE_LOCAL_INCLUDES   = NO
     
    INLINE_INFO            = YES
     
    SORT_MEMBER_DOCS       = YES
     
    SORT_BRIEF_DOCS        = YES
     
    SORT_MEMBERS_CTORS_1ST = YES
     
    SORT_GROUP_NAMES       = YES
     
    SORT_BY_SCOPE_NAME     = NO
     
    STRICT_PROTO_MATCHING  = NO
     
    # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
    # list. This list is created by putting \todo commands in the documentation.
    # The default value is: YES.
     
    GENERATE_TODOLIST      = @DOXYGEN_TODO@
     
    GENERATE_TESTLIST      = @DOXYGEN_TESTS@
     
    GENERATE_BUGLIST       = YES
     
    GENERATE_DEPRECATEDLIST= YES
     
    ENABLED_SECTIONS       =
     
    MAX_INITIALIZER_LINES  = 30
     
    SHOW_USED_FILES        = YES
     
    SHOW_FILES             = YES
     
    SHOW_NAMESPACES        = YES
     
    FILE_VERSION_FILTER    =
     
    LAYOUT_FILE            =
     
    CITE_BIB_FILES         =
     
    QUIET                  = NO
     
    WARNINGS               = @DOXYGEN_WARNINGS@
     
    WARN_IF_UNDOCUMENTED   = YES
     
    WARN_IF_DOC_ERROR      = YES
     
    WARN_NO_PARAMDOC       = YES
     
    WARN_AS_ERROR          = NO
     
    WARN_FORMAT            = "$file:$line: $text"
     
    WARN_LOGFILE           =
     
    INPUT                  = @CMAKE_CURRENT_SOURCE_DIR@/..
    INPUT_ENCODING         = UTF-8
     
    FILE_PATTERNS          = *.c \
                             *.cc \
                             *.cxx \
                             *.cpp \
                             *.c++ \
                             *.java \
                             *.ii \
                             *.ixx \
                             *.ipp \
                             *.i++ \
                             *.inl \
                             *.idl \
                             *.ddl \
                             *.odl \
                             *.h \
                             *.hh \
                             *.hxx \
                             *.hpp \
                             *.h++ \
                             *.cs \
                             *.d \
                             *.php \
                             *.php4 \
                             *.php5 \
                             *.phtml \
                             *.inc \
                             *.m \
                             *.markdown \
                             *.md \
                             *.mm \
                             *.dox \
                             *.py \
                             *.pyw \
                             *.f90 \
                             *.f95 \
                             *.f03 \
                             *.f08 \
                             *.f \
                             *.for \
                             *.tcl \
                             *.vhd \
                             *.vhdl \
                             *.ucf \
                             *.qsf
     
    RECURSIVE              = YES
     
    EXCLUDE                = @CMAKE_CURRENT_SOURCE_DIR@/../3rdParty
     
    EXCLUDE_SYMLINKS       = NO
     
    EXCLUDE_PATTERNS       =
     
    EXCLUDE_SYMBOLS        =
    EXAMPLE_PATH           = @CMAKE_CURRENT_SOURCE_DIR@/../examples
     
    EXAMPLE_PATTERNS       = *
     
    EXAMPLE_RECURSIVE      = YES
     
    IMAGE_PATH             =
     
    INPUT_FILTER           =
     
    FILTER_PATTERNS        =
     
    FILTER_SOURCE_FILES    = NO
     
    FILTER_SOURCE_PATTERNS =
     
    USE_MDFILE_AS_MAINPAGE =
     
    SOURCE_BROWSER         = @DOXYGEN_SOURCEBROWSER@
     
    INLINE_SOURCES         = @DOXYGEN_INLINESOURCES@
     
    STRIP_CODE_COMMENTS    = YES
     
    REFERENCED_BY_RELATION = YES
     
    REFERENCES_RELATION    = YES
     
    REFERENCES_LINK_SOURCE = YES
     
    SOURCE_TOOLTIPS        = YES
     
    USE_HTAGS              = NO
    VERBATIM_HEADERS       = YES
     
    CLANG_ASSISTED_PARSING = NO
     
    CLANG_OPTIONS          =
     
    ALPHABETICAL_INDEX     = YES
     
    COLS_IN_ALPHA_INDEX    = 5
     
    IGNORE_PREFIX          =
     
    GENERATE_HTML          = @DOXYGEN_HTML@
     
    HTML_OUTPUT            = html
     
    HTML_FILE_EXTENSION    = .xhtml
     
    HTML_HEADER            =
     
    HTML_FOOTER            =
     
    HTML_STYLESHEET        =
     
    HTML_EXTRA_STYLESHEET  =
     
    HTML_EXTRA_FILES       =
     
    HTML_COLORSTYLE_HUE    = 220
     
    HTML_COLORSTYLE_SAT    = 100
     
    HTML_COLORSTYLE_GAMMA  = 80
     
    HTML_TIMESTAMP         = YES
     
    HTML_DYNAMIC_SECTIONS  = YES
     
    HTML_INDEX_NUM_ENTRIES = 100
     
    GENERATE_DOCSET        = NO
     
    DOCSET_FEEDNAME        = "Doxygen generated docs"
     
    DOCSET_BUNDLE_ID       = org.doxygen.Project
     
    DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
     
    DOCSET_PUBLISHER_NAME  = @CPACK_PACKAGE_VENDOR@
     
    GENERATE_HTMLHELP      = @DOXYGEN_HTMLHELP@
    CHM_FILE               =
     
    HHC_LOCATION           = DOXYGEN_HCC
     
    GENERATE_CHI           = NO
     
    CHM_INDEX_ENCODING     =
     
    BINARY_TOC             = NO
     
    TOC_EXPAND             = YES
     
    GENERATE_QHP           = @DOXYGEN_QHP@
     
    QCH_FILE               =
     
    QHP_NAMESPACE          = org.doxygen.Project
     
    QHP_VIRTUAL_FOLDER     = doc
     
    QHP_CUST_FILTER_NAME   =
     
    QHP_CUST_FILTER_ATTRS  =
     
    QHP_SECT_FILTER_ATTRS  =
     
    QHG_LOCATION           = @DOXYGEN_QHELPGENERATOR@
     
    GENERATE_ECLIPSEHELP   = @DOXYGEN_HECLIPSEHELP@
     
    ECLIPSE_DOC_ID         = org.doxygen.Project
     
    DISABLE_INDEX          = NO
     
    GENERATE_TREEVIEW      = NO
    ENUM_VALUES_PER_LINE   = 4
     
    TREEVIEW_WIDTH         = 250
     
    EXT_LINKS_IN_WINDOW    = NO
     
    FORMULA_FONTSIZE       = 10
     
    FORMULA_TRANSPARENT    = YES
    USE_MATHJAX            = NO
    MATHJAX_FORMAT         = HTML-CSS
    MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
    MATHJAX_EXTENSIONS     =
    MATHJAX_CODEFILE       =
    SEARCHENGINE           = YES
    SERVER_BASED_SEARCH    = NO
    EXTERNAL_SEARCH        = NO
    SEARCHENGINE_URL       =
    SEARCHDATA_FILE        = searchdata.xml
     
    EXTERNAL_SEARCH_ID     =
    EXTRA_SEARCH_MAPPINGS  =
     
    GENERATE_LATEX         = @DOXYGEN_LATEX@
    LATEX_OUTPUT           = latex
     
    LATEX_CMD_NAME         = @DOXYGEN_LATEX_COMMAND@
     
    MAKEINDEX_CMD_NAME     = @DOXYGEN_LATEX_INDEX@
    COMPACT_LATEX          = NO
    PAPER_TYPE             = a4
     
    EXTRA_PACKAGES         =
    LATEX_HEADER           =
    LATEX_FOOTER           =
     
    LATEX_EXTRA_STYLESHEET =
     
    LATEX_EXTRA_FILES      =
     
    PDF_HYPERLINKS         = YES
    USE_PDFLATEX           = YES
     
    LATEX_BATCHMODE        = @LATEX_BATCHMODE@
    LATEX_HIDE_INDICES     = NO
     
    LATEX_SOURCE_CODE      = @DOXYGEN_INLINESOURCES@
     
    LATEX_BIB_STYLE        = plain
     
    LATEX_TIMESTAMP        = @LATEX_TIMESTAMP@
     
    GENERATE_RTF           = @DOXYGEN_RTF@
     
    RTF_OUTPUT             = rtf
     
    COMPACT_RTF            = NO
     
    RTF_HYPERLINKS         = NO
    RTF_STYLESHEET_FILE    =
    RTF_EXTENSIONS_FILE    =
     
    RTF_SOURCE_CODE        = @DOXYGEN_INLINESOURCES@
     
    GENERATE_MAN           = @DOXYGEN_MAN@
     
    MAN_OUTPUT             = man
     
    MAN_EXTENSION          = .3
     
    MAN_SUBDIR             =
     
    MAN_LINKS              = YES
     
    GENERATE_XML           = NO
     
    XML_OUTPUT             = @DOXYGEN_XML@
     
    XML_PROGRAMLISTING     = YES
     
    GENERATE_DOCBOOK       = @DOXYGEN_DOCBOOK@
     
    # The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
    # If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
    # front of it.
    # The default directory is: docbook.
    # This tag requires that the tag GENERATE_DOCBOOK is set to YES.
     
    DOCBOOK_OUTPUT         = docbook
     
    DOCBOOK_PROGRAMLISTING = YES
     
    GENERATE_AUTOGEN_DEF   = NO
     
    GENERATE_PERLMOD       = NO
     
    PERLMOD_LATEX          = NO
     
    PERLMOD_PRETTY         = YES
     
    PERLMOD_MAKEVAR_PREFIX =
     
    ENABLE_PREPROCESSING   = YES
     
    MACRO_EXPANSION        = NO
     
    EXPAND_ONLY_PREDEF     = NO
     
    SEARCH_INCLUDES        = YES
     
    INCLUDE_PATH           =
    INCLUDE_FILE_PATTERNS  =
     
    PREDEFINED             =
     
    EXPAND_AS_DEFINED      =
     
    SKIP_FUNCTION_MACROS   = YES
    TAGFILES               =
     
    GENERATE_TAGFILE       =
    ALLEXTERNALS           = NO
    EXTERNAL_GROUPS        = YES
     
    EXTERNAL_PAGES         = YES
     
    PERL_PATH              = @DOXYGEN_PERL_PATH@
     
    CLASS_DIAGRAMS         = @DOXYGEN_DIAGRAM@
    MSCGEN_PATH            = @DOXYGEN_MSCGEN@
     
    DIA_PATH               =
     
    HIDE_UNDOC_RELATIONS   = NO
     
    HAVE_DOT               = @DOXYGEN_HAVEDOT@
     
    DOT_NUM_THREADS        = 0
     
    DOT_FONTNAME           = Helvetica
     
    DOT_FONTSIZE           = 10
     
    DOT_FONTPATH           =
     
    CLASS_GRAPH            = YES
    COLLABORATION_GRAPH    = YES
    GROUP_GRAPHS           = YES
     
    UML_LOOK               = YES
     
    UML_LIMIT_NUM_FIELDS   = 10
     
    TEMPLATE_RELATIONS     = YES
     
    INCLUDE_GRAPH          = YES
     
    INCLUDED_BY_GRAPH      = YES
    CALL_GRAPH             = YES
     
    CALLER_GRAPH           = YES
     
    GRAPHICAL_HIERARCHY    = YES
     
    DIRECTORY_GRAPH        = YES
     
    DOT_IMAGE_FORMAT       = svg
    INTERACTIVE_SVG        = YES
     
    DOT_PATH               = @DOXYGEN_DOT_PATH@
     
    DOTFILE_DIRS           =
    MDCFILE_DIRS           =
     
    DIAFILE_DIRS           =
     
    PLANTUML_JAR_PATH      =
     
    PLANTUML_CFG_FILE      =
     
    PLANTUML_INCLUDE_PATH  =
     
    DOT_GRAPH_MAX_NODES    = 50
     
    MAX_DOT_GRAPH_DEPTH    = 0
     
    DOT_TRANSPARENT        = NO
     
    DOT_MULTI_TARGETS      = NO
     
    GENERATE_LEGEND        = YES
     
    DOT_CLEANUP            = YES
    l
    (remarque les noms entourés par des @) auquel nous associerons un CMakeFile.txt proche de
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    if(BUILD_DOCUMENTATION)
        option(DOXYGEN__BUILD_INTERNAL
            "Should we build the internal doxygen documentation?" FALSE)
        option(DOXYGEN_BUILD_FULLNAME
            "Should we generate fully qualified class and functions names?" TRUE)
        option(DOXYGEN_BUILD_TODOLIST
            "Should we generate a TODO list ?" TRUE)
        option(DOXYGEN_BUILD_TESTLIST
            "Should we generate a unit tests list ?" TRUE)
        option(DOXYGEN_BUILD_WARNINGS
            "Should we show warnings when generating docs ?" TRUE)
        option(DOXYGEN_BUILD_SOURCESBROWSER
            "Should we include source browsing capability?" TRUE)
        option(DOXYGEN_INLINESOURCE
            "Should we include function and classes bodies in docs?" TRUE)
        option(DOXYGEN_BUILD_HTML
            "Should we generate HTML format docs?" TRUE)
        option(DOXYGEN_BUILD_LATEX
            "Should we generate LATEX format docs?" TRUE)
        if(DOXYGEN_BUILD_LATEX)
            option(DOXYGEN_BUILD_LATEX_BATCHMODE "Should we generate LATEX format docs int batchmode?" TRUE)
            option(DOXYGEN_BUILD_LATEXT_TIMESTAMP "Should we add date and time of in latex files?" TRUE)
        endif()
        option(DOXYGEN_BUILD_RTF "Should we generate RTF format docs?" FALSE)
        option(DOXYGEN_BUILD_MAN "Should we generate MAN format docs?" FALSE)
        option(DOXYGEN_BUILD_XML "Should we generate XML format docs?" FALSE)
        option(DOXYGEN_BUILD_DOCBOOK "Should we generate docbook format docs?" FALSE)
        set(PROJECT_BRIEF "\"A modern signal / slot system\"")
        set(PROJECT_LOGO)
        if(DOXYGEN_BUILD_INTERNAL)
            set(DOXYGEN_INTERNAL "YES")
        else()
            set(DOXYGEN_INTERNAL "NO")
        endif()
        if(DOXYGEN_BUILD_FULLNAME)
            set(DOXYGEN_HIDE_SCOPES "NO")
        else()
            set(DOXYGEN_HIDE_SCOPES "YES")
        endif()
        if(DOXYGEN_BUILD_TODOLIST)
            set(DOXYGEN_TODO "YES")
        else()
            set(DOXYGEN_TODO "NO")
        endif()
        if(DOXYGEN_BUILD_TESTLIST)
            set(DOXYGEN_TESTS "YES")
        else()
            set(DOXYGEN_TESTS "NO")
        endif()
        if(DOXYGEN_BUILD_WARNINGS)
            set(DOXYGEN_WARNINGS "YES")
        else()
            set(DOXYGEN_WARNINGS "NO")
        endif()
        if(DOXYGEN_BUILD_SOURCESBROWSER)
            set(DOXYGEN_SOURCEBROWSER "YES")
        else()
            set(DOXYGEN_SOURCEBROWSER "NO")
        endif()
        if(DOXYGEN_INLINESOURCE)
            set(DOXYGEN_INLINESOURCES "YES")
        else()
            set(DOXYGEN_INLINESOURCES "NO")
        endif()
        if(DOXYGEN_BUILD_HTML)
            set(DOXYGEN_HTML "YES")
        else()
            set(DOXYGEN_HTML "NO")
        endif()
        set(DOXYGEN_HTMLHELP "NO")
        set(DOXYGEN_HCC)
        set(DOXYGEN_QHP "NO")
        set(DOXYGEN_QHELPGENERATOR)
        set(DOXYGEN_ECLIPSEHELP "NO")
        if(DOXYGEN_BUILD_LATEX)
            set(DOXYGEN_LATEX "YES")
        else()
            set(DOXYGEN_LATEX "NO")
        endif()
        set(DOXYGEN_LATEX_COMMAND "latex")
        set(DOXYGEN_LATEX_INDEX "makeindex")
        if(DOXYGEN_BUILD_LATEX_BATCHMODE)
            set(LATEX_BATCHMODE "YES")
        else()
            set(LATEX_BATCHMODE "NO")
        endif()
        if(DOXYGEN_BUILD_LATEXT_TIMESTAMP)
            set(LATEX_TIMESTAMP "YES")
        else()
            set(LATEX_TIMESTAMP "NO")
        endif()
        if(DOXYGEN_BUILD_RTF)
            set(DOXYGEN_RTF "YES")
        else()
            set(DOXYGEN_RTF "NO")
        endif()
        if(DOXYGEN_BUILD_MAN)
            set(DOXYGEN_MAN "YES")
        else()
            set(DOXYGEN_MAN "NO")
        endif()
        if(DOXYGEN_BUILD_XML)
            set(DOXYGEN_XML "YES")
        else()
            set(DOXYGEN_XML "NO")
        endif()
        if(DOXYGEN_BUILD_DOCBOOK)
            set(DOXYGEN_DOCBOOK "YES")
        else()
            set(DOXYGEN_DOCBOOK "NO")
        endif()
        set(DOXYGEN_PERL_PATH /usr/bin/perl)
        set(DOXYGEN_DYAGRAM "YES")
        set(DOXYGEN_MSCGEN)
        set(DOXYGEN_HAVEDOT "YES")
        set(DOXYGEN_DOT_PATH)
     
        if(NOT DOXYGEN_FOUND)
            message(FATAL_ERROR "Doxygen is needed to build the documentation.")
        endif()
     
        set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
        set(outdir ${CMAKE_CURRENT_BINARY_DIR}/../docs)
        set(doxyfile ${outdir}/Doxyfile)
     
        configure_file(${doxyfile_in} ${doxyfile} @ONLY)
     
        add_custom_target(doc
            COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
            WORKING_DIRECTORY ${outdir}/
            COMMENT "Generating API documentation with Doxygen")
     
        install(DIRECTORY ${outdir}/ DESTINATION share/doc)
    endif()
    Tu remarqeras que tous les noms entourés d'arobase trouvent leur équivalent dans une variable dont a valeur est définie de manière conditionnelle
    Et tu remarqueras à la ligne 126 de ce fichier la commande configure_file(${doxyfile_in} ${doxyfile} @ONLY) qui applique toute la magie du système

    Pour générer un fichier d'en-tête général (souvent nommé config.h):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #pragma once
     
    #define NUMBER_OF_LOGICAL_CORES   @_NUMBER_OF_LOGICAL_CORES@
    #define NUMBER_OF_PHYSICAL_CORES  @_NUMBER_OF_PHYSICAL_CORES@
    #define TOTAL_VIRTUAL_MEMORY      @_TOTAL_VIRTUAL_MEMORY@
    #define AVAILABLE_VIRTUAL_MEMORY  @_AVAILABLE_VIRTUAL_MEMORY@
    #define TOTAL_PHYSICAL_MEMORY     @_TOTAL_PHYSICAL_MEMORY@
    #define AVAILABLE_PHYSICAL_MEMORY @_AVAILABLE_PHYSICAL_MEMORY@
    #define IS_64BIT                  @_IS_64BIT@
    #define HAS_FPU                   @_HAS_FPU@
    #define HAS_MMX                   @_HAS_MMX@
    #define HAS_MMX_PLUS              @_HAS_MMX_PLUS@
    #define HAS_SSE                   @_HAS_SSE@
    #define HAS_SSE2                  @_HAS_SSE2@
    #define HAS_SSE_FP                @_HAS_SSE_FP@
    #define HAS_SSE_MMX               @_HAS_SSE_MMX@
    #define HAS_AMD_3DNOW             @_HAS_AMD_3DNOW@
    #define HAS_AMD_3DNOW_PLUS        @_HAS_AMD_3DNOW_PLUS@
    #define HAS_IA64                  @_HAS_IA64@
    #define OS_NAME                  "@_OS_NAME@"
    #define OS_RELEASE               "@_OS_RELEASE@"
    #define OS_VERSION               "@_OS_VERSION@"
    #define OS_PLATFORM              "@_OS_PLATFORM@"
    qui pourrait être associé à un code proche de
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    foreach(key
      IN ITEMS
        NUMBER_OF_LOGICAL_CORES
        NUMBER_OF_PHYSICAL_CORES
        TOTAL_VIRTUAL_MEMORY
        AVAILABLE_VIRTUAL_MEMORY
        TOTAL_PHYSICAL_MEMORY
        AVAILABLE_PHYSICAL_MEMORY
        IS_64BIT
        HAS_FPU
        HAS_MMX
        HAS_MMX_PLUS
        HAS_SSE
        HAS_SSE2
        HAS_SSE_FP
        HAS_SSE_MMX
        HAS_AMD_3DNOW
        HAS_AMD_3DNOW_PLUS
        HAS_IA64
        OS_NAME
        OS_RELEASE
        OS_VERSION
        OS_PLATFORM
      )
      cmake_host_system_information(RESULT _${key} QUERY ${key})
    endforeach()
     
    configure_file(templates/config.hpp.in config.hpp @ONLY)
    add_definitions(${SOLUTION_UP}_HAS_CONFIG_HPP)
    include_directories(${CMAKE_BINARY_DIR})

    Tu remarqueras encore une fois que tous les noms entourés d'arobase sont repris comme noms de variable ainsi que la ligne 28 qui prend la forme deconfigure_file(templates/config.hpp.in config.hpp @ONLY) pour faire jouer la magie; le tout sans oublier la ligne 30 qui prend la forme deinclude_directories(${CMAKE_BINARY_DIR}) qui permettra d'avoir l'option -I adéquate permettant au compilateur de trouver le fichier config.hpp

    Bien sur, je pourrais multiplier les exemples à volontés, mais tu auras sans doute compris le principe
    • j'ai du mal à faire la différence entre dépendance publique et privée. Je comprends qu'une dépendance privée c'est par exemple boost si j'ai besoin de boost:ublas dans mes algos, mais alors je ne comprends pas la dépendance publique.
    Ces deux termes s'appliquent à la visibilité des éléments de la cible en cours de traitement par rapport aux cibles qui pourraient éventuellement en dépendre.

    Si tu dis que "quelque chose" (par exemple, les fichiers d'en-tête, le dossier dans lequel ils se trouvent ou le dossier dans lequel se trouvent les fichiers d'en-tête de ses propres dépendaces) de la bibliothèque que tu développe est PUBLIC, alors, l'application qui dépend de ta bibliothèque poura y accéder.

    Si tu dis que "quelque chose" (par exemple, les fichiers d'implémentation) de la bibliothèque que tu dévelopes est PRIVATE, alors l'application qui dépend de ta bibliothèque ne saura même pas qu'il existe

    C'est "aussi simple" que cela


    Aussi, quelle est la différence entre écrire:
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    FIND_PACKAGE(Boost COMPONENTS unit_test_framework system filesystem REQUIRED)
    IF (Boost_FOUND)
        INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
        ADD_DEFINITIONS(-DBOOST_UBLAS_NDEBUG)
    ENDIF()

    et :
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    find_package(Boost REQUIRED)
    add_library(boost INTERFACE IMPORTED)
    set_property(TARGET boost PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})
    Le premier code va se contenter de tester la présence de boost (et, plus particulièrement, de boost::unit_test, boost::system et de boost::file_system), et va sans doute s'arrêter sur une erreur si l'un de ces trois composants n'est pas présent (à cause de la clause REQUIRED).

    D'ailleurs, c'est bien simple: il n'y a que si ce test réussi (boost_FOUND) que l'on va ajouter le dossier contenant les ficheirs d'en-tête de boos (Boost_INCLUDE_DIR) à l'option -I qui sera transmise au compilateur (include_directories) et que l'on ajoutera la définition préprocesseur -DBOOST_UBLAS_NDEBUG (add_definitions)

    Le deuxième code ne cherche pas après des composants bien particuliers de boost, mais la présence de boost en générale est toujours requise (la configuration devrait toujours échouer si boost est absent).

    Mais, je ne sais pas si tu as remarqué: on cherche le paquetage Boost (avec un B majuscule).

    On va donc préparer une bibliothèque importée (dont toutes les dépendances seront définies dans le bon ordre lorsque l'on indiquera qu'une de nos cibles en dépend) qui sera nommée ... boost (avec un B minuscule, cette fois) et qui expose (essentiellement) le dossier dans lequel se trouvent les fichiers d'en-tête de boost comme interface principale (comme élément à exposer à ses dépendances)

    J'ai aussi écrit ça:
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    # Include Gdal
    FIND_PACKAGE(GDAL)
    IF (GDAL_FOUND)
        INCLUDE_DIRECTORIES(${GDAL_INCLUDE_DIR})
    ENDIF()

    ça marche, c'est cool, mais j'ai lu quelque part cmake définit une fonction FindGDAL, je suis censé l'utiliser ?
    Merci!
    Sauf erreur de ma part, cela revient grosso modo au même: on pourrait dire que la fonction findXXX n'est jamais qu'un raccourcis pour find_package(XXX)Maintenant, je t'avouerai que j'utilise -- mais uniquement par habitude -- de préférence find_package et que je ne suis simplement pas assez au fait du fonctionnement interne de cmake pour savoir si le raccourcis peut poser problème (ou non) ou même s'il y a une "bonne pratique" qui émerge et qui conseille de choisir plutôt l'un que l'autre.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre averti Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Points : 341
    Points
    341
    Par défaut
    Ok, super! Bon j'ai commencé à travailler sur ces exemples et à lire plus de trucs sur le superbuild.
    Mais il y a encore pas mal de choses qui m'échappent. Là dessous c'est le graph de dépendances:

    |-> lib (github)
    |    |->lib_a (github)
    |    |    |->boost unit_test_framework system filesystem ublas
    |    |    |->gdal
    |    |->sqlite3
    |    |->sqlite3pp (github)
    |    |->boost program_options
    |    |->python3
    |    |->BPP (github)
    J'aimerai (est-ce raisonnable ) que si on installe lib_a, la présence des bonnes versions de boost et gdal soit checkée et qu'on les télécharge/installe si besoin. Cela nécessite-t'il un superbuild pour lib_a également? J'ai en fait du mal à définir quand la présence d'un superbuild est justifiée ou pas.

    Si on installe lib, en ce cas là j'imagine que si les dépendances transitives (c'est le bon mot?) ont bien été gérées, on a seulement besoin de checker la présence de la bonne version de lib_a et que ça va tout seul gérer boost et gdal si besoin. Autrement dit on n'a pas besoin, dans le cmake de lib, de mentionner les dépendances des dépendances n'est ce pas ?

    Et puis évidemment il faut du coup récupérer sqlite3, sqlite3pp, boost program_options et python3 et BPP. Faut-il ré-écrire le même code cmake pour boost (checker la présence/version de boost et download/install si besoin) juste pour récupérer program_options alors que tout ce code existe déjà pour gérer les dépendances de lib? Il y a t'il un risque de conflit quelconque ? Et aussi pour boost dois-je faire figurer quelque part que lib_a utilise boost::ublas ? J'ai lu que c'était inutile si c'était header-only.

    J'imagine que lib_a devrait ne même pas avoir conscience qu'elle est susceptible d'être utilisée dans un superbuild ?

    Bref comme vous voyez j'ai du mal à orchestrer/planififer les changement à orchestrer dans les cmakelists
    PS: j'ai finalement acheté le bouquin qui va avec, il y a toutes les explications des lignes de commandes, et ça c'est top. Je vous ferai une review si vous voulez lol
    Le débutant, lui, ignore qu'il ignore à ce point, il est fier de ses premiers succès, bien plus qu'il n'est conscient de l'étendue de ce qu'il ne sait pas, dès qu'il progresse en revanche, dès que s'accroît ce qu'il sait, il commence à saisir tout ce qui manque encore à son savoir. Qui sait peu ignore aussi très peu. [Roger Pol-Droit]
    Github
    Mon tout premier projet: une bibliothèque de simulation de génétique des populations

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par Seabirds Voir le message
    J'aimerai (est-ce raisonnable ) que si on installe lib_a, la présence des bonnes versions de boost et gdal soit checkée et qu'on les télécharge/installe si besoin. Cela nécessite-t'il un superbuild pour lib_a également? J'ai en fait du mal à définir quand la présence d'un superbuild est justifiée ou pas.
    Regarde sur le dépot git dont je t'ai donné le lien du coté des super build patterns dont c'est le principe .

    Si on installe lib, en ce cas là j'imagine que si les dépendances transitives (c'est le bon mot?) ont bien été gérées, on a seulement besoin de checker la présence de la bonne version de lib_a et que ça va tout seul gérer boost et gdal si besoin. Autrement dit on n'a pas besoin, dans le cmake de lib, de mentionner les dépendances des dépendances n'est ce pas ?
    Si tu utilises le patron super build, elles auront effectivement au moins été générées. Mais cela ne veut pas forcément dire qu'elles auront été installées (surtout si on envisage la version "développeur" des bibliothèques, avec .lib, en-tête et tout le bastringue)

    Et puis évidemment il faut du coup récupérer sqlite3, sqlite3pp, boost program_options et python3 et BPP. Faut-il ré-écrire le même code cmake pour boost (checker la présence/version de boost et download/install si besoin)
    Il est toujours possible de partir d'un code modèle adapté au travers de différents scripts, mais, étant donné la partie "variable", propre à chaque bibliothèque (adresse de téléchargement, options de configurations, et tout ce qui s'en suit), tu ne pourras pas éviter d'avoir une bonne partie qui sera spécifique pour chaque bibliothèque
    juste pour récupérer program_options alors que tout ce code existe déjà pour gérer les dépendances de lib? Il y a t'il un risque de conflit quelconque ?
    Si la bibliothèque ciblée par le super-build n'est pas présente, il n'y a aucun risque de conflit

    Si elle est présente, mais que tu décides quand même de générer la dernière version (ou une version bien précise), ce sera la version générée qui sera choisie.

    Si tu décide d'installer la cible de ton super-build, le système de version devrait éviter les problèmes

    Et aussi pour boost dois-je faire figurer quelque part que lib_a utilise boost::ublas ? J'ai lu que c'était inutile si c'était header-only.
    Les règles de minimalisme suffisant sont les mêmes pour Cmake que partout ailleurs: plutôt que de définir "de base" 50 options de compilation dont quarante ne servent qu'à des endroits bien particulier, tu pars avec les options strictement communes et tu rajoutes les options strictement nécessaires chaque fois qu'il en est besoin.

    La transitivité, suite aux diverses dépendances, fera le reste

    Mais donc, si tu utilise le superbuild pour avoir boost::ublas, il faudra bien dire à lib_a qu'elle doit aller chercher les fichiers d'en-tête au bon endroit, non

    J'imagine que lib_a devrait ne même pas avoir conscience qu'elle est susceptible d'être utilisée dans un superbuild ?
    meme pas, parce que ca, c'est une situation qui échappe au domaine de lib_a. c'est l'utilisateur qui va faire le choix du super-build
    Bref comme vous voyez j'ai du mal à orchestrer/planififer les changement à orchestrer dans les cmakelists
    PS: j'ai finalement acheté le bouquin qui va avec, il y a toutes les explications des lignes de commandes, et ça c'est top. Je vous ferai une review si vous voulez lol
    Ce serait bien gentil de ta part
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre averti Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Points : 341
    Points
    341
    Par défaut
    Merci pour tes réponses !

    Entre temps j'ai reçu le bouquin, il est plutôt pas mal du tout, et il complémente assez bien le dépôt github ! Il donne pas mal d'information de contexte, qui sont utiles pour comprendre pourquoi utiliser telle commande dans tel cas. Par contre, je comprends clairement pas tout ce qui se passe.

    J'ai récupéré des bouts de différentes recettes, notamment le Superbuild Pattern avec boost (Chap.8 recipe 2) et Installer un Superbuild (Chap. 10 recipe 4). Malgré divers bricolages je n'arrive pas à installer le superbuild.

    Je me suis concentré dans un premier temps à faire un Superbuild pour permettre d'installer/tester la librairie quetzal (header-only) avec ses dépendances (boost et gdal) si elle ne sont pas trouvées sur le système. Pour le côté "header-only", ça vient de là : https://dominikberner.ch/cmake-interface-lib/
    Je n'ai pas vraiment encore réussi à trouver comment télécharger et installer gdal dans le build via cmake, mais un baby step à la fois...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    |__ CMakeLists.txt 
    |__ external
    |          |__ upstream
    |                    |__ CMakeLists.txt
    |                    |__ boost
    |                    |        |__ CMakeLists.txt
    |                    |__ gdal
    |                             |__ CMakeLists.txt
    |__ src
            |__ CMakeLists.txt
            |__ cmake
            |         |__ quetzal_coreConfig.cmake.in
            |__ include
            |           |__ quetzal
            |                     |__  headers et sous dossiers
            |__ test
                    |__  CMakeLists.txt
    The root CMakelists:

    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
     
    project(
      "quetzal"
      VERSION 0.1
      LANGUAGES CXX
      DESCRIPTION "A header only c++ library for spatially explicit coalescence simulation."
      HOMEPAGE_URL "https://github.com/becheler/quetzal")
     
    # <<< General set up >>>
     
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_EXTENSIONS OFF)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
     
    message(STATUS "Project will be installed to ${CMAKE_INSTALL_PREFIX}")
     
    if(NOT CMAKE_BUILD_TYPE)
      set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
    endif()
     
    message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}")
     
    include(GNUInstallDirs)
     
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
     
    # Offer the user the choice of overriding the installation directories
    set(INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries")
    set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for executables")
    set(INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for header files")
    if(WIN32 AND NOT CYGWIN)
      set(DEF_INSTALL_CMAKEDIR CMake)
    else()
      set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME})
    endif()
    set(INSTALL_CMAKEDIR ${DEF_INSTALL_CMAKEDIR} CACHE PATH "Installation directory for CMake files")
     
    # Report to user
    foreach(p LIB BIN INCLUDE CMAKE)
      file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path )
      message(STATUS "Installing ${p} components to ${_path}")
      unset(_path)
    endforeach()
     
    set_property(DIRECTORY PROPERTY EP_BASE ${CMAKE_BINARY_DIR}/subprojects)
     
    set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage)
    message(STATUS "${PROJECT_NAME} staged install: ${STAGED_INSTALL_PREFIX}")
     
    ### Boost
    list(APPEND BOOST_COMPONENTS_REQUIRED unit_test_framework filesystem)
    set(Boost_MINIMUM_REQUIRED 1.61)
     
    ### GDAL
    set(GDAL_MINIMUM_REQUIRED 2.2)
     
    ### External project
    add_subdirectory(external/upstream)
     
    include(ExternalProject)
    ExternalProject_Add(${PROJECT_NAME}_core
      DEPENDS
        boost_external
      SOURCE_DIR
        ${CMAKE_CURRENT_LIST_DIR}/src
      CMAKE_ARGS
        -DCMAKE_INSTALL_PREFIX= ${STAGED_INSTALL_PREFIX}
        -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
        -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
        -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
        -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS}
        -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED}
      CMAKE_CACHE_ARGS
        -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS}
        -DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH}
        -DCMAKE_INCLUDE_PATH:PATH=${BOOST_INCLUDEDIR}
        -DCMAKE_LIBRARY_PATH:PATH=${BOOST_LIBRARYDIR}
      BUILD_ALWAYS
        1
      )
     
    enable_testing()
     
    install(
      DIRECTORY
        ${STAGED_INSTALL_PREFIX}/
      DESTINATION
        .
      USE_SOURCE_PERMISSIONS
      )

    The external/upstream:
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    add_subdirectory(boost)
    add_subdirectory(gdal)

    external/upstream/boost :

    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    find_package(Boost ${Boost_MINIMUM_REQUIRED} QUIET COMPONENTS "${BOOST_COMPONENTS_REQUIRED}")
     
    if(Boost_FOUND)
      message(STATUS "Found Boost version ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
      add_library(boost_external INTERFACE)
    else()
      message(STATUS "Boost ${Boost_MINIMUM_REQUIRED} could not be located, Building Boost 1.61.0 instead.")
     
      if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
        if(APPLE)
          set(_toolset "darwin")
        else()
          set(_toolset "gcc")
        endif()
      elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
        set(_toolset "clang")
      elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
        if(APPLE)
          set(_toolset "intel-darwin")
        else()
          set(_toolset "intel-linux")
        endif()
      endif()
     
      # Non-empty list. Compiled libraries needed
      if(NOT "${BOOST_COMPONENTS_REQUIRED}" STREQUAL "")
        # Replace unit_test_framework (used by CMake's find_package) with test (understood by Boost build toolchain)
        string(REPLACE "unit_test_framework" "test" _b2_needed_components "${BOOST_COMPONENTS_REQUIRED}")
        # Generate argument for BUILD_BYPRODUCTS
        set(_build_byproducts)
        set(_b2_select_libraries)
        foreach(_lib IN LISTS _b2_needed_components)
          list(APPEND _build_byproducts ${STAGED_INSTALL_PREFIX}/boost/lib/libboost_${_lib}${CMAKE_SHARED_LIBRARY_SUFFIX})
          list(APPEND _b2_select_libraries --with-${_lib})
        endforeach()
        # Transform the ;-separated list to a ,-separated list (digested by the Boost build toolchain!)
        string(REPLACE ";" "," _b2_needed_components "${_b2_needed_components}")
        set(_bootstrap_select_libraries "--with-libraries=${_b2_needed_components}")
        string(REPLACE ";" ", " printout "${BOOST_COMPONENTS_REQUIRED}")
        message(STATUS "  Libraries to be built: ${printout}")
      endif()
     
      include(ExternalProject)
      ExternalProject_Add(boost_external
        URL
          https://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.zip
        URL_HASH
          SHA256=02d420e6908016d4ac74dfc712eec7d9616a7fc0da78b0a1b5b937536b2e01e8
        DOWNLOAD_NO_PROGRESS
          1
        UPDATE_COMMAND
          ""
        CONFIGURE_COMMAND
          <SOURCE_DIR>/bootstrap.sh
          --with-toolset=${_toolset}
          --prefix=${STAGED_INSTALL_PREFIX}/boost
          ${_bootstrap_select_libraries}
        BUILD_COMMAND
          <SOURCE_DIR>/b2 -q
               link=shared
               threading=multi
               variant=release
               toolset=${_toolset}
               ${_b2_select_libraries}
        LOG_BUILD
          1
        BUILD_IN_SOURCE
          1
        INSTALL_COMMAND
          <SOURCE_DIR>/b2 -q install
               link=shared
               threading=multi
               variant=release
               toolset=${_toolset}
               ${_b2_select_libraries}
        LOG_INSTALL
          1
        BUILD_BYPRODUCTS
          "${_build_byproducts}"
        )
     
      set(
        BOOST_ROOT ${STAGED_INSTALL_PREFIX}/boost
        CACHE PATH "Path to internally built Boost installation root"
        FORCE
        )
      set(
        BOOST_INCLUDEDIR ${BOOST_ROOT}/include
        CACHE PATH "Path to internally built Boost include directories"
        FORCE
        )
      set(
        BOOST_LIBRARYDIR ${BOOST_ROOT}/lib
        CACHE PATH "Path to internally built Boost library directories"
        FORCE
        )
     
      # Unset internal variables
      unset(_toolset)
      unset(_b2_needed_components)
      unset(_build_byproducts)
      unset(_b2_select_libraries)
      unset(_boostrap_select_libraries)
    endif()

    external/upstream/gdal (I will find later how to download it if not found):
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    find_package(GDAL ${GDAL_MINIMUM_REQUIRED})
     
    if(GDAL_FOUND)
      message(STATUS "Found GDAL version ${GDAL_VERSION}")
      add_library(gdal_external INTERFACE)
    endif()

    The src/CMakelists:

    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
     
    project(
      "quetzal_core"
      VERSION 0.1
      LANGUAGES CXX
      DESCRIPTION "A header only c++ library for spatially explicit coalescence simulation."
      HOMEPAGE_URL "https://github.com/becheler/quetzal")
     
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_EXTENSIONS OFF)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
     
    message(STATUS "Project will be installed to ${CMAKE_INSTALL_PREFIX}")
     
    include(GNUInstallDirs)
     
    add_library(${PROJECT_NAME} INTERFACE)
    # add alias so the project can be uses with add_subdirectory
    add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
     
    # Include Boost as an imported target
    find_package(Boost 1.61 REQUIRED COMPONENTS unit_test_framework filesystem)
     
    # Include Gdal
    find_package(GDAL REQUIRED)
    IF (GDAL_FOUND)
        INCLUDE_DIRECTORIES(${GDAL_INCLUDE_DIR})
    ENDIF()
     
    # Adding the install interface generator expression makes sure that the include
    # files are installed to the proper location (provided by GNUInstallDirs)
    target_include_directories(
      ${PROJECT_NAME}
      INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
                $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
     
    # If we have compiler requirements for this library, list them here
    target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17)
     
    # Targets that we develop here
    enable_testing()
    add_subdirectory(test)
     
    # 'make install' to the correct locations provided by GNUInstallDirs.
    install(TARGETS ${PROJECT_NAME}
            EXPORT ${PROJECT_NAME}_Targets
            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
            RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
     
    # This is for Windows
    install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
     
    # This makes the project importable from the install directory
    include(CMakePackageConfigHelpers)
    write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
                                     VERSION ${PROJECT_VERSION}
                                     COMPATIBILITY SameMajorVersion)
     
    configure_package_config_file(
      "${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
      "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
      INSTALL_DESTINATION
      ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
     
    install(EXPORT ${PROJECT_NAME}_Targets
            FILE ${PROJECT_NAME}Targets.cmake
            NAMESPACE ${PROJECT_NAME}::
            DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
     
    install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
                  "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
            DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
     
    # The header files are copied to the installation folder
    install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/quetzal DESTINATION include)

    The src/test/CMakeLists :
    Code CMakeLists : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    cmake_minimum_required(VERSION 3.12)
     
    set(CMAKE_CXX_STANDARD 17)
    add_compile_options(-Wall -pedantic-errors -Wextra -DNDEBUG)
     
    ### INTEGRATION TESTS
     
    add_executable(model_1 integration_test/model_1/main.cpp)
     
    target_link_libraries(model_1 LINK_PUBLIC ${GDAL_LIBRARY} )
     
    target_include_directories(model_1
      PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
      $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>)
     
    add_test(SpatialExpansion model_1 ${CMAKE_CURRENT_SOURCE_DIR}/data/europe_temp.tif)
     
    ### UNIT TEST
     
    # Keep test files in a separate source directory called test
    file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} unit_test/*.cpp)
     
    #Run through each source
    foreach(testSrc ${TEST_SRCS})
            #Extract the filename without an extension (NAME_WE)
            get_filename_component(testName ${testSrc} NAME_WE)
     
            #Add compile target
            add_executable(${testName} ${testSrc})
     
            #link to Boost libraries AND your targets and dependencies
            target_link_libraries(${testName}
                                    ${Boost_LIBRARIES}
                                    ${Boost_FILESYSTEM_LIBRARY}
                                    ${Boost_SYSTEM_LIBRARY}
                                    ${GDAL_LIBRARY})
     
            #I like to move testing binaries into a testBin directory
            set_target_properties(${testName} PROPERTIES
                RUNTIME_OUTPUT_DIRECTORY  ${CMAKE_CURRENT_SOURCE_DIR}/build/testBin)
     
            target_include_directories(
              ${testName} PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
                                      $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>)
     
            #Finally add it to test execution -
            #Notice the WORKING_DIRECTORY and COMMAND
            add_test(NAME ${testName}
                     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build/testBin
                     COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build/testBin/${testName} )
    endforeach(testSrc)

    and the src/cmake/quetzal_coreConfig.cmake.in :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @PACKAGE_INIT@
     
    include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
    check_required_components("@PROJECT_NAME@")
    Running cmake and make:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/home/becheler/dev/libs
    -- Project will be installed to /home/becheler/dev/libs
    -- Build type set to Release
    -- Installing LIB components to /home/becheler/dev/libs/lib
    -- Installing BIN components to /home/becheler/dev/libs/bin
    -- Installing INCLUDE components to /home/becheler/dev/libs/include
    -- Installing CMAKE components to /home/becheler/dev/libs/share/cmake/quetzal
    -- quetzal staged install: /home/becheler/dev/quetzal/build/stage
    -- Found Boost version 1.65.1
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/becheler/dev/quetzal/build
    becheler@becheler-HP-ZBook-15u-G2:~/dev/quetzal/build$ make
    [ 12%] Performing build step for 'quetzal_core'
    [ 14%] Built target coalescence_test
    [ 28%] Built target geography_test
    [ 42%] Built target random_test
    [ 57%] Built target model_1
    [ 71%] Built target demography_test
    [ 85%] Built target expressive_test
    [100%] Built target matrix_operation_test
    [ 25%] Performing install step for 'quetzal_core'
    [ 14%] Built target coalescence_test
    [ 28%] Built target geography_test
    [ 42%] Built target random_test
    [ 57%] Built target model_1
    [ 71%] Built target demography_test
    [ 85%] Built target expressive_test
    [100%] Built target matrix_operation_test
    Install the project...
    -- Install configuration: "Release"
    -- Installing: /include
    CMake Error at cmake_install.cmake:41 (file):
      file INSTALL cannot make directory "/include": Permission denied.
     
     
    Makefile:128: recipe for target 'install' failed
    make[3]: *** [install] Error 1
    CMakeFiles/quetzal_core.dir/build.make:73: recipe for target 'subprojects/Stamp/quetzal_core/quetzal_core-install' failed
    make[2]: *** [subprojects/Stamp/quetzal_core/quetzal_core-install] Error 2
    CMakeFiles/Makefile2:113: recipe for target 'CMakeFiles/quetzal_core.dir/all' failed
    make[1]: *** [CMakeFiles/quetzal_core.dir/all] Error 2
    Makefile:140: recipe for target 'all' failed
    make: *** [all] Error 2
    Je pense que quelque chose essaie de s'installer dans usr/lib et demande le root access. Donc j'ai du mal m'y prendre quelque part pour spécifier les INSTALL_DIR, mais je ne vois pas où ?

    Je pense que j'ai du mal à mélanger les différents aspects des recettes que j'ai trouvé (header-only, superbuild, installation), et comme je ne comprends pas encore tous les tenants et aboutissants des différentes commandes ...
    Le débutant, lui, ignore qu'il ignore à ce point, il est fier de ses premiers succès, bien plus qu'il n'est conscient de l'étendue de ce qu'il ne sait pas, dès qu'il progresse en revanche, dès que s'accroît ce qu'il sait, il commence à saisir tout ce qui manque encore à son savoir. Qui sait peu ignore aussi très peu. [Roger Pol-Droit]
    Github
    Mon tout premier projet: une bibliothèque de simulation de génétique des populations

Discussions similaires

  1. gestion des dépendences maven
    Par javadevelopper dans le forum Maven
    Réponses: 1
    Dernier message: 21/01/2010, 12h16
  2. Réponses: 2
    Dernier message: 31/08/2002, 21h37
  3. Réponses: 4
    Dernier message: 04/07/2002, 12h31
  4. c: gestion des exceptions
    Par vince_lille dans le forum C
    Réponses: 7
    Dernier message: 05/06/2002, 14h11
  5. gestion d'un joystick ...
    Par Anonymous dans le forum DirectX
    Réponses: 1
    Dernier message: 23/05/2002, 12h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo