Как я могу понять Config.cmake, ConfigVersion.cmake, Targets.cmake

#cmake

#cmake

Вопрос:

Я пытаюсь понять, что я делаю со своими файлами cmake. Извините, если мой вопрос кажется слишком очевидным или уже дан ответ в другом месте, но мне действительно трудно понять современный cmake и найти хорошие и четкие объяснения. Я написал минимальный пример :

hello.cpp:

 #include<iostream>

int hello(){
   std::cout << "Hello World!" << std::endl;
   return 0;
}
  

CMakeLists.txt

 cmake_minimum_required(VERSION 3.5)
project (hello)

SET(CMAKE_INSTALL_PREFIX "/home/guillaume/dev/C  /projects/test/cmake_hello_world/install")
set(INSTALL_LIB_DIR lib)

add_library(hello SHARED main.cpp)

set(LIBRARY_INSTALL_DIR lib)
set(INCLUDE_INSTALL_DIR include)

INSTALL(TARGETS hello
  EXPORT helloTargets
  LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
  ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR}
  INCLUDES DESTINATION ${INCLUDE_INSTALL_DIR})

include(CMakePackageConfigHelpers)
set(ConfigFileInstallDir lib/cmake/hello)
set(INCLUDE_INSTALL_DIR include CACHE PATH "install path for include files")
set(LIBRARY_INSTALL_DIR lib CACHE PATH "install path for libraries")
configure_package_config_file(helloConfig.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/helloConfig.cmake"
  INSTALL_DESTINATION "${ConfigFileInstallDir}"
  PATH_VARS INCLUDE_INSTALL_DIR LIBRARY_INSTALL_DIR
  )
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/helloConfigVersion.cmake"
  VERSION "0.0.0"
  COMPATIBILITY SameMajorVersion)

EXPORT(EXPORT helloTargets
  FILE helloTargets.cmake)

INSTALL(FILES
  "${CMAKE_CURRENT_BINARY_DIR}/helloConfig.cmake"
  "${CMAKE_CURRENT_BINARY_DIR}/helloConfigVersion.cmake"
  "${CMAKE_CURRENT_BINARY_DIR}/helloTargets.cmake"
  DESTINATION "${ConfigFileInstallDir}")
  

и helloConfig.cmake.in :

 set(helloLib_VERSION @VERSION@)

@PACKAGE_INIT@

INCLUDE("${CMAKE_CURRENT_LIST_DIR}/helloTargets.cmake")

SET_AND_CHECK(hello_LIB_DIR "@PACKAGE_LIBRARY_INSTALL_DIR@")

message(STATUS "hello library version: ${hello_VERSION}")
message(STATUS "hello library location: ${hello_LIB_DIR}")

check_required_components(hello)
  

Теперь у меня есть три файла в cmake_hello_world /install /lib /cmake /hello

  • Из configure_package_config_file, helloConfig.cmake
  • Из write_basic_package_version_file, helloConfigVersion.cmake
  • Из EXPORT(экспортировать …), helloTargets.cmake

Хорошо, я полагаю, что знаю, что helloConfig.cmake будет использоваться в будущем findpackage (привет), но каково значение двух других файлов (helloConfigVersion.cmake и helloTargets.cmake)? Когда я должен их создать?

Ответ №1:

что означают два других файла (helloConfigVersion.cmake

helloConfigVersion используется для определения или выбора версии пакета, не включая его. В основном это работает так, в псевдокоде:

 function(find_package VERSION some_version)
     # blabla
     # variable set by find_package before including
     set(PACKAGE_FIND_VERSION ${some_version})
     include(helloConfigVersion) # uses PACKAGE_FIND_VERSION
     # if PACKAGE_FIND_VERSION is compatible with the version installed
     # then the variable PACKAGE_VERSION_COMPATIBLE is set inside helloConfigVersion
     # (this would all be easier if cmake wouldn't use so many global variables...)
     if (NOT PACKAGE_VERSION_COMPATIBLE)
         message(FATAL_ERROR "Och no, the installed package version is not compatible with what you want!")
     endif()
     # all ok, the version is compatible, we can do it
     include(helloConfig.cmake)
     # blabla
endfunction()
  

Смотрите соответствующий раздел в find_package руководстве, все описано там.

и helloTargets.cmake)?

Этот файл определяет (или переключается между версиями) целевые объекты вашей библиотеки. В основном это происходит в псевдокоде:

 add_library(hello SHARED IMPORTED /usr/lib/the/path/to/libhello.so)
  

наряду с некоторыми другими материалами. find_package исходные файлы этого файла, чтобы вы могли позже использовать target_link_libraries(soemtarget hello) , как если бы он был скомпилирован как цель cmake.

В некоторых случаях *Target.cmake файл отсутствует, я думаю, это когда библиотека не экспортирует цели и выполняет только функции или выполняет много ручных операций.

Когда я должен их создать?

Если вы хотите, чтобы ваш модуль был найден с find_package , тогда всегда. Вам не удалось создать Version.cmake файл, тогда, если пользователь это сделает, find_package(hello VERSION <any verison here>) это всегда будет ошибкой.

Как я могу понять Config.cmake, ConfigVersion.cmake, Targets.cmake

Они являются всего лишь частью системы упаковки cmake.