web-dev-qa-db-fra.com

exemple de fichier de configuration simple cmake

Maintenant, j'ai une bibliothèque que j'ai créée que je veux utiliser dans un autre projet CMake c ++. Il existe dans mon ordinateur comme ça.

${MY_LIB_PATH}\include
${MY_LIB_PATH}\lib\x86\debug\lib-files
${MY_LIB_PATH}\lib\x86\release\lib-files
${MY_LIB_PATH}\lib\x64\debug\lib-files
${MY_LIB_PATH}\lib\x64\release\lib-files

À quoi ressemblerait un fichier de configuration de base permettant à CMake find_package de les connaître? Je m'attendais à ce que ce soit très simple car il ne contient tout simplement pas beaucoup d'informations à fournir. Mais cette page me fait juste mal à la tête.

Désolé, j'ai décidé de copier le code source afin que je ne sache pas vraiment quelle réponse devrait être acceptée.

4
J. Doe

N'écris pas toi-même une config; utilisez la commande export de CMake. C'est trop large pour couvrir ici la totalité, mais voici un exemple modifié de l'un de mes projets:

install(TARGETS
        your_target
    EXPORT YourPackageConfig
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
export(TARGETS
        your_target
    NAMESPACE YourPackage::
    FILE "${CMAKE_CURRENT_BINARY_DIR}/YourPackageConfig.cmake"
)
install(EXPORT
        YourPackageConfig
    DESTINATION "${CMAKE_INSTALL_DATADIR}/YourPackage/cmake"
    NAMESPACE YourPackage::
)

Cela créera le fichier de configuration pour vous, afin que d'autres projets puissent l'utiliser via find_package.

find_package(YourPackage REQUIRED)
target_link_libraries(foo YouprPackage::your_target)

Cela gère automatiquement les cibles IMPORTED et vous permet également d'intégrer des indicateurs de compilateur, des chemins d'accès, des dépendances de bibliothèque et même les fichiers faisant partie de votre interface (en gros, tout ce qui relève des propriétés INTERFACE.

4
Stephen Newell

Placez un "$ {libname} -config.cmake" à la racine de la bibliothèque.

Ajoutez ensuite une cible IMPORTÉE dans ce fichier.

Il y a un exemple pour libprotobuf.

add_library(libprotobuf STATIC IMPORTED GLOBAL)

set_target_properties(libprotobuf PROPERTIES 
    IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/prebuilt/Android/${Android_ABI}/libprotobuf.a"
    IMPORTED_LINK_INTERFACE_LIBRARIES "${ZLIB_LIBRARIES};${CMAKE_THREAD_LIBS_INIT}"
    INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/src")

Définissez la variable Env ou CMake "$ {libname} _DIR" sur "$ {MY_LIB_PATH}"

Utilise le.

find_package(${libname})
#.......
target_link_libraries(main ${libname})
1
WinCloud

Peut-être que ce ancien document pourrait être un peu plus léger. Et il y a aussi ce tutorial ou cet autre . Le dernier est peut-être le plus simple.

J'espère ne pas avoir ajouté plus de douleur :-)

Après la documentation, vous devriez obtenir un résultat similaire à celui-ci (si votre bibliothèque est mylib):

MyLib/MyLibConfig.cmake.in

# - Config file for the MyLib package
# It defines the following variables
#  MYLIB_INCLUDE_DIRS - include directories for MyLib
#  MYLIB_LIBRARIES    - libraries to link against
#  MYLIB_EXECUTABLE   - the bar executable

# Compute paths
get_filename_component(MYLIB_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(MYLIB_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")

# Our library dependencies (contains definitions for IMPORTED targets)
if(NOT TARGET mylib AND NOT MyLib_BINARY_DIR)
  include("${MYLIB_CMAKE_DIR}/MyLibTargets.cmake")
endif()

# These are IMPORTED targets created by MyLibTargets.cmake
set(MYLIB_LIBRARIES mylib)

MyLib/MyLibConfigVersion.cmake.in

set(PACKAGE_VERSION "@MYLIB_VERSION@")

# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
  set(PACKAGE_VERSION_COMPATIBLE TRUE)
  if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
    set(PACKAGE_VERSION_EXACT TRUE)
  endif()
endif()

principal MyLib/CMakeLists.txt

...

set(MYLIB_MAJOR_VERSION 0)
set(MYLIB_MINOR_VERSION 1)
set(MYLIB_PATCH_VERSION 0)
set(MYLIB_VERSION
  ${MYLIB_MAJOR_VERSION}.${MYLIB_MINOR_VERSION}.${MYLIB_PATCH_VERSION})

...

add_library(mylib SHARED mylib.c ...)

...

install(TARGETS mylib
  # IMPORTANT: Add the mylib library to the "export-set"
  EXPORT MyLibTargets
  RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin
  LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT shlib
  PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/mylib"
    COMPONENT dev)

...

# The interesting stuff goes here
# ===============================

# Add all targets to the build-tree export set
export(TARGETS mylib
  FILE "${PROJECT_BINARY_DIR}/MyLibTargets.cmake")

# Export the package for use from the build-tree
# (this registers the build-tree with a global CMake-registry)
export(PACKAGE MyLib)

# Create the MyLibConfig.cmake and MyLibConfigVersion files
file(RELATIVE_PATH REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}"
   "${INSTALL_INCLUDE_DIR}")
# ... for the build tree
set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}")
configure_file(MyLibConfig.cmake.in
  "${PROJECT_BINARY_DIR}/MyLibConfig.cmake" @ONLY)
# ... for the install tree
set(CONF_INCLUDE_DIRS "\${MYLIB_CMAKE_DIR}/${REL_INCLUDE_DIR}")
configure_file(MyLibConfig.cmake.in
  "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/MyLibConfig.cmake" @ONLY)
# ... for both
configure_file(MyLibConfigVersion.cmake.in
  "${PROJECT_BINARY_DIR}/MyLibConfigVersion.cmake" @ONLY)

# Install the MyLibConfig.cmake and MyLibConfigVersion.cmake
install(FILES
  "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/MyLibConfig.cmake"
  "${PROJECT_BINARY_DIR}/MyLibConfigVersion.cmake"
  DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)

# Install the export set for use with the install-tree
install(EXPORT MyLibTargets DESTINATION
  "${INSTALL_CMAKE_DIR}" COMPONENT dev)
0
Marco Pantaleoni