#[=======================================================================[.rst: myx_add_interface_library ------------------------- Вспомогательная функция для создания интерфейсной библиотеки:: myx_add_interface_library(TARGET_NAME [ PACKAGES packages ] | [ LINK_LIBRARIES link_libraries ] | [ OUTPUT_NAME output_name ] | [ EXPORT_FILE_NAME file_name ] | [ EXPORT_BASE_NAME base_name ] | [ HEADERS headers ]) Обязательные параметры: `TARGET_NAME` - имя библиотеки. Параметр `OUTPUT_NAME` определяет базовое имя выходных файлов. Параметр `EXPORT_FILE_NAME` задаёт имя заголовочного файла экспортируемых переменных, а `EXPORT_BASE_NAME` - базовый суффикс для формирования имён переменных. Все остальные параметры передаются в стандартную функцию `add_library()` #]=======================================================================] include_guard(GLOBAL) include(CMakePackageConfigHelpers) include(GenerateExportHeader) if(${CMAKE_VERSION} VERSION_LESS "3.17.0") set(MYX_CMAKE_LIB_DIR_BACKPORT "${CMAKE_CURRENT_LIST_DIR}") endif() function(myx_add_interface_library TARGET_NAME) if(${CMAKE_VERSION} VERSION_LESS "3.17.0") set(CMAKE_CURRENT_FUNCTION_LIST_DIR ${MYX_CMAKE_LIB_DIR_BACKPORT}) endif() if(TARGET ${TARGET_NAME}) myx_message_fatal_error("Target ${TARGET_NAME} already exists") endif() set(options) set(oneValueArgs OUTPUT_NAME) set(multiValueArgs HEADERS LINK_LIBRARIES PACKAGES) cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT ARG_OUTPUT_NAME) set(ARG_OUTPUT_NAME ${TARGET_NAME}) endif() # Вызов стандартной функции `add_library()` if(${CMAKE_VERSION} VERSION_LESS "3.19.0") add_library(${TARGET_NAME} INTERFACE) target_sources(${TARGET_NAME} INTERFACE $) else() add_library(${TARGET_NAME} INTERFACE ${ARG_HEADERS}) endif() foreach(__iter ${ARG_PACKAGES}) target_include_directories(${TARGET_NAME} INTERFACE ${${__iter}_INCLUDE_DIRS}) target_compile_definitions(${TARGET_NAME} INTERFACE ${${__iter}_COMPILE_DEFINITIONS}) endforeach() if(ARG_LINK_LIBRARIES) target_link_libraries(${TARGET_NAME} INTERFACE ${ARG_LINK_LIBRARIES}) if(${CMAKE_VERSION} VERSION_GREATER "3.15.0") foreach(__lib ${ARG_LINK_LIBRARIES}) if(TARGET ${__lib}) install( TARGETS ${__lib} EXPORT ${TARGET_NAME}Targets COMPONENT DEV) endif() endforeach() endif() endif() # Библиотека, состоящая только из заголовочных файлов не требует сборки. # Стандартные пути к заголовочным файлам target_include_directories(${TARGET_NAME} INTERFACE $) # Если вызов был выполнен не из проекта верхнего уровня, # то созданная цель исключается из цели `all`. # При этом сама цель `${TARGET_NAME}` может участвовать в сборке, # если окажется в перечне зависимостей. if((NOT PROJECT_IS_TOP_LEVEL) AND (${CMAKE_VERSION} VERSION_GREATER "3.8.0")) set_target_properties(${TARGET_NAME} PROPERTIES EXCLUDE_FROM_ALL True) return() endif() # Правила для установки библиотек и относящихся к ним файлов. # Если вызов был выполнен не из проекта верхнего уровня, # то эти правила не обрабатываются. write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}ConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) configure_package_config_file( ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/library-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}Config.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${TARGET_NAME} NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO ) install(EXPORT ${TARGET_NAME}Targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${TARGET_NAME} COMPONENT DEV) install( FILES ${PROJECT_BINARY_DIR}/${TARGET_NAME}ConfigVersion.cmake ${PROJECT_BINARY_DIR}/${TARGET_NAME}Config.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${TARGET_NAME} COMPONENT DEV) # Формирование файла для pkg-config file(WRITE "${PROJECT_BINARY_DIR}/${TARGET_NAME}.pc" "prefix=${CMAKE_INSTALL_PREFIX}\n" "exec_prefix=${CMAKE_INSTALL_PREFIX}\n" "includedir=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n" "\n" "Name: ${TARGET_NAME}\n" "Description: ${TARGET_NAME} library\n" "Version: ${PROJECT_VERSION}\n" "\n" "Requires:\n" "Cflags: -I${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n") # Установка файла для pkg-config install( FILES "${PROJECT_BINARY_DIR}/${TARGET_NAME}.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" COMPONENT DEV) # Установка библиотеки из заголовочных файлов target_include_directories(${TARGET_NAME} SYSTEM INTERFACE $) install( TARGETS ${TARGET_NAME} EXPORT ${TARGET_NAME}Targets COMPONENT DEV) # Установка публичных заголовочных файлов if(PROJECT_IS_TOP_LEVEL AND ARG_HEADERS) myx_install_relative(${PROJECT_SOURCE_DIR} FILES ${ARG_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT DEV) endif() endfunction()