Bonjour à tous.

Je travaille actuellement sur une bibliothèque modulaire que je n'arrive pas à structurer correctement pour CMake.
Comme contraintes techniques, je dois me limiter à CMake 2.8.11 (mais si je peux éviter ce qui est déprécié par la suite, c'est mieux)

Il y a un noyau fonctionnel, nommé core, qui permet de modéliser une arborescence de divers Bidules.
Ce noyau est complété par plusieurs api de sérialisation: xml, json, et d'autres encore.

Il est possible de définir des Extensions, chacune défini par un noyau fonctionnel et des compléments aux api de sérialisations.
Le projet complet défini plusieurs extensions "de base".

Chacun des modules constitue une bibliothèque pour permettre de ne linker qu'avec les bibliothèques requises, par exemple core, xml, ext5 et ext5-xml.

J'ai actuellement des CMakelist.txt dans:
  • le dossier racine pour la configuration de l'ensemble
  • le dossier de core
  • le dossier de xml (et de chaque autre api)
  • la racine de chaque extension
  • le dossier core de chaque extension
  • le dossier xml de chaque extension (et de même pour les autres api)
  • les différentes dossiers de programmes d'exemples.

la configuration de cmake doit seulement préciser quelles api sont à compiler (avec des options comme -DBUILD_XML) et si on compile les exemples

Par contre, on souhaite avoir les commandes de compilation suivantes:
  • make all: compilation de core, des apis sélectionnées à la configuration
  • make <Ext>: compilation de l'extension <Ext>
  • make extensions: compilations de toutes les extensions
  • make install: installation de all
  • make install-<Ext>: installation de l'extension <Ext>
  • make install-extensions: installation de toutes les extensions


Pour la gestion des API, j'ai utilisé les if de CMake (if(BUILD_XML) ... endif())

Par contre, pour les extensions, je n'arrive pas à m'en sortir correctement.
Pour l'instant, j'ai ajouté OPTIONAL et EXCLUDE_FROM_ALL aux modules, mais j'ai un warning pour l'installation:
Citation Envoyé par cmake
(WARNING: Target "ext1" has EXCLUDE_FROM_ALL set and will not be built by default but an install rule has been provided for it. CMake does not define behavior for this case.)
Je n'arrive pas à comprendre comment définir et utiliser les composants, au sens de CMake.

Voici le CMakeList d'une extension:
project(lib_project_ext1 CXX)

configure_file(
  ${CMAKE_CURRENT_SOURCE_DIR}/include/ext1/config.h.in
  ${CMAKE_CURRENT_SOURCE_DIR}/include/ext1/config.h
)

add_library(project-ext1 EXCLUDE_FROM_ALL src/ext1.cpp)

target_include_directories(project-ext1
  PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  $<BUILD_INTERFACE:${lib_project_SOURCE_DIR}/core/include>
  $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
)


target_link_libraries(project-ext1 project)

set_target_properties(project-ext1
  PROPERTIES
    VERSION ${PROJECT_VERSION_STRING}
    SOVERSION ${PROJECT_VERSION_MAJOR}
)

install(TARGETS project-ext1 EXPORT project-ext1_Config
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
  OPTIONAL
  COMPONENT project-ext1
)

install(DIRECTORY include/project
  DESTINATION include
  OPTIONAL COMPONENT project-ext1
  FILES_MATCHING PATTERN "*.h"
)

install(EXPORT project-ext1_Config
  DESTINATION ${PROJECT_SHARE_PATH}/cmake
  OPTIONAL COMPONENT project-ext1
)

export(TARGETS project-ext1 project FILE project-ext1_Config.cmake)
Et le CMakelist global (en l'état actuel et avec deux extensions):
cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)

# This project has a core component: libproject.so
# It also provide some extensions, like libproject-xml.so

# temporary: only effectively supports g++ in versions starting 4.8.2.

SET(PROJECT_VERSION_MAJOR 1)
SET(PROJECT_VERSION_MINOR 0)
SET(PROJECT_VERSION_PATCH 0)

# Project options
option(BUILD_XML "enables the XML support." OFF)
option(BUILD_JSON "enables the JSON support." OFF)

option(BUILD_SAMPLES "enables the building of the samples (only those related to built components)." OFF)

# making an option allow "shared" to be the default value
option(PROJECT_BUILD_SHARED "build shared libraries instead of static ones" ON)

set(BUILD_SHARED_LIBS ${PROJECT_BUILD_SHARED})

set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "build type, one of (Release, Debug, RelWithDebInfo)")

set(BOOST_ROOT "/usr/lib" CACHE STRING "Boost library install directory")
set(XERCESC_HOME ${XERCESC_HOME} CACHE STRING "Xerces-C++ library install directory")
set(LIBXML_HOME ${LIBXML_HOME} CACHE STRING "libXML library install directory")

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(PROJECT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})

set(PROJECT_SHARE_PATH "share/project")

# Boost is required for core and all extensions.
find_package(Boost 1.59 REQUIRED)

add_subdirectory(core)
add_subdirectory(extensions/ext1/core)
add_subdirectory(extensions/ext2/core)

# note from documentation:  "Add a target with no output so it will always be built."
add_custom_target(extensions
  DEPENDS
    project-ext1
    project-ext2
)

if( BUILD_XML )
  find_package(XercesC REQUIRED)
  add_subdirectory(xml)
  add_subdirectory(extensions/ext1/xml)
  add_subdirectory(extensions/ext2/xml)

  add_dependencies( extensions
    project-ext1-xml
    project-ext2-xml
  )
endif()

if( BUILD_JSON )
  [...]
endif()
notes:
  • chaque dossier contient un appel pour la construction des exemples.
  • Si BUILD_XML est vrai, la cible project-ext1-xml est définie et dépend de project-ext1, et la cible extensions dépend de project-ext1 puis project-ext1-xml.


Je suis certainement passé à coté des composants, mais je ne parviens pas à faire en sorte que le choix des APIs soit fait à la configuration du build, mais celui des extensions soit fait à la compilation.
Et j'ai ce problème de l'installation des composants facultatifs.