myx/MyxCMake/lib/AddLibrary.cmake

221 lines
9.0 KiB
CMake
Raw Normal View History

2022-10-01 13:42:36 +00:00
#[=======================================================================[.rst:
myx_add_library
---------------
Вспомогательная функция для создания библиотеки::
2022-10-02 10:12:07 +00:00
myx_add_library(NAME TYPE
2022-10-02 10:33:23 +00:00
[ OUTPUT_NAME output_name ] |
[ EXPORT_FILE_NAME file_name ] |
[ EXPORT_BASE_NAME base_name ])
2022-10-01 13:42:36 +00:00
Обязательные параметры: `NAME` - имя библиотеки и `TYPE` - тип цели.
2022-10-02 10:33:23 +00:00
Параметр `OUTPUT_NAME` определяет базовое имя выходных файлов.
Параметр `EXPORT_FILE_NAME` задаёт имя заголовочного файла экспортируемых
переменных, а `EXPORT_BASE_NAME` - базовый суффикс для формирования имён переменных.
Все остальные параметры передаются в стандартную функцию `add_library()`
2022-10-01 13:42:36 +00:00
#]=======================================================================]
2022-09-29 10:34:57 +00:00
include_guard(GLOBAL)
2022-10-01 23:39:48 +00:00
include(CMakePackageConfigHelpers)
2022-09-29 10:34:57 +00:00
include(GenerateExportHeader)
2022-10-01 13:42:36 +00:00
function(myx_add_library NAME TYPE)
2022-09-29 10:34:57 +00:00
set(options)
2022-10-02 10:12:07 +00:00
set(oneValueArgs OUTPUT_NAME EXPORT_FILE_NAME EXPORT_BASE_NAME)
2022-10-01 13:42:36 +00:00
set(multiValueArgs)
2022-09-29 10:34:57 +00:00
2022-10-01 13:42:36 +00:00
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
2022-10-02 10:12:07 +00:00
if(NOT ARG_OUTPUT_NAME)
set(ARG_OUTPUT_NAME ${NAME})
endif()
2022-10-01 13:42:36 +00:00
# Вызов стандартной функции `add_library()`
add_library(${NAME} ${TYPE} ${ARG_UNPARSED_ARGUMENTS})
2022-09-29 10:34:57 +00:00
2022-10-01 23:39:48 +00:00
if(TYPE STREQUAL "INTERFACE")
# Библиотека, состоящая только из заголовочных файлов не требует сборки.
2022-10-01 13:42:36 +00:00
# Стандартные пути к заголовочным файлам
2022-09-29 14:20:02 +00:00
target_include_directories(${NAME}
2022-09-29 10:34:57 +00:00
INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
else()
2022-09-29 14:20:02 +00:00
string(TOUPPER ${NAME} PROJECT_NAME_UPPER)
2022-10-01 23:39:48 +00:00
# Опция для разрешения сборки динамической библиотеки
cmake_dependent_option(${PROJECT_NAME_UPPER}_BUILD_SHARED
"Build shared library for ${NAME}" ON "BUILD_SHARED_LIBS" OFF)
2022-09-29 12:42:22 +00:00
# Опция для разрешения сборки статической библиотеки
2022-10-01 23:39:48 +00:00
cmake_dependent_option(${PROJECT_NAME_UPPER}_BUILD_STATIC
"Build static library for ${NAME}" ON "NOT BUILD_SHARED_LIBS" OFF)
2022-09-29 12:42:22 +00:00
2022-10-01 13:42:36 +00:00
# Стандартные пути к заголовочным файлам
2022-09-29 14:20:02 +00:00
target_include_directories(${NAME}
2022-09-29 10:34:57 +00:00
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
PRIVATE
2022-10-01 13:42:36 +00:00
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>
2022-09-29 10:34:57 +00:00
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
2022-10-01 23:39:48 +00:00
# Сборка позиционно-независимых объектных файлов нужна
# для создания динамической библиотеки
2022-09-29 14:20:02 +00:00
set_target_properties(${NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
2022-09-29 10:34:57 +00:00
2022-10-02 10:12:07 +00:00
if(NOT EXPORT_BASE_NAME)
string(TOUPPER ${NAME} ARG_EXPORT_BASE_NAME)
endif()
if(NOT ARG_EXPORT_FILE_NAME)
set(ARG_EXPORT_FILE_NAME "${PROJECT_SOURCE_DIR}/include/${NAME}/${NAME}_export.hpp")
endif()
2022-09-29 14:20:02 +00:00
generate_export_header(${NAME}
2022-10-02 10:12:07 +00:00
BASE_NAME ${ARG_EXPORT_BASE_NAME}
EXPORT_MACRO_NAME "EXPORT_${ARG_EXPORT_BASE_NAME}"
DEPRECATED_MACRO_NAME "DEPRECATED_${ARG_EXPORT_BASE_NAME}"
NO_DEPRECATED_MACRO_NAME "NO_DEPRECATED_${ARG_EXPORT_BASE_NAME}"
NO_EXPORT_MACRO_NAME "NO_EXPORT_${ARG_EXPORT_BASE_NAME}"
STATIC_DEFINE "STATIC_DEFINE_${ARG_EXPORT_BASE_NAME}"
EXPORT_FILE_NAME ${ARG_EXPORT_FILE_NAME}
2022-10-01 13:42:36 +00:00
DEFINE_NO_DEPRECATED
2022-09-29 10:34:57 +00:00
)
2022-10-02 13:22:43 +00:00
set_property(TARGET ${NAME} APPEND PROPERTY INTERFACE_HEADER_FILES "${ARG_EXPORT_FILE_NAME}")
2022-09-29 11:19:40 +00:00
2022-10-01 23:39:48 +00:00
# Цель для создания динамической библиотеки из объектных файлов
2022-09-29 11:19:40 +00:00
if(${PROJECT_NAME_UPPER}_BUILD_SHARED)
2022-10-01 23:39:48 +00:00
# Для создания динамической библиотеки используются объектные файлы цели ${NAME}
2022-09-29 14:20:02 +00:00
add_library(${NAME}_shared SHARED $<TARGET_OBJECTS:${NAME}>)
# Установка дополнительных свойств для цели ${NAME}_shared
2022-09-29 11:19:40 +00:00
# VERSION: версия библиотеки
# SOVERSION: мажорная версия библиотеки
2022-10-01 23:39:48 +00:00
# LIBRARY_OUTPUT_DIRECTORY: каталог для записи результатов сборки
# OUTPUT_NAME: базовое имя выходного файла (без учёта расширения)
2022-09-29 14:20:02 +00:00
set_target_properties(${NAME}_shared
2022-09-29 11:19:40 +00:00
PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
2022-10-01 23:39:48 +00:00
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
2022-10-02 10:12:07 +00:00
OUTPUT_NAME ${ARG_OUTPUT_NAME})
2022-09-29 11:19:40 +00:00
endif()
# Цель для создания статической библиотеки из объектных файлов
if(${PROJECT_NAME_UPPER}_BUILD_STATIC)
2022-09-29 14:20:02 +00:00
# Для создания статической библиотеки используются объектные файлы цели ${NAME}
add_library(${NAME}_static STATIC $<TARGET_OBJECTS:${NAME}>)
# Установка дополнительных свойств для цели ${NAME}_static
2022-10-01 23:39:48 +00:00
# ARCHIVE_OUTPUT_DIRECTORY: каталог для записи результатов сборки
2022-09-29 11:19:40 +00:00
# OUTPUT_NAME: базовое имя выходного файла (без учёта расширения)
2022-09-29 14:20:02 +00:00
set_target_properties(${NAME}_static
2022-09-29 11:19:40 +00:00
PROPERTIES
2022-10-01 23:39:48 +00:00
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
2022-10-02 10:12:07 +00:00
OUTPUT_NAME ${ARG_OUTPUT_NAME})
2022-09-29 11:19:40 +00:00
endif()
2022-09-29 10:34:57 +00:00
endif()
2022-10-01 23:39:48 +00:00
# Если вызов был выполнен не из проекта верхнего уровня,
# то созданная цель исключается из цели `all`.
# При этом сама цель `${NAME}` может участвовать в сборке,
# если окажется в перечне зависимостей.
if(NOT PROJECT_IS_TOP_LEVEL)
set_target_properties(${NAME} PROPERTIES EXCLUDE_FROM_ALL True)
2022-10-01 23:39:48 +00:00
return()
endif()
# Правила для установки библиотек и относящихся к ним файлов.
# Если вызов был выполнен не из проекта верхнего уровня,
# то эти правила не обрабатываются.
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
configure_package_config_file(
2022-10-05 07:01:02 +00:00
${MYX_CMAKE_LIB_DIR}/library-config.cmake.in
2022-10-01 23:39:48 +00:00
${CMAKE_CURRENT_BINARY_DIR}/${NAME}Config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAME}
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
install(EXPORT ${NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAME}
COMPONENT dev
)
install(
FILES
${PROJECT_BINARY_DIR}/${NAME}ConfigVersion.cmake
${PROJECT_BINARY_DIR}/${NAME}Config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAME}
COMPONENT dev
)
2022-10-02 10:33:23 +00:00
# Формирование файла для pkg-config
2022-10-04 03:08:31 +00:00
file(WRITE "${PROJECT_BINARY_DIR}/${NAME}.pc"
2022-10-01 23:39:48 +00:00
"prefix=${CMAKE_INSTALL_PREFIX}\n"
"exec_prefix=${CMAKE_INSTALL_PREFIX}\n"
"includedir=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n")
2022-10-02 10:12:07 +00:00
2022-10-01 23:39:48 +00:00
if(NOT TYPE STREQUAL "INTERFACE")
2022-10-04 03:08:31 +00:00
file(APPEND "${PROJECT_BINARY_DIR}/${NAME}.pc"
2022-10-01 23:39:48 +00:00
"libdir=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\n")
endif()
2022-10-04 03:08:31 +00:00
file(APPEND "${PROJECT_BINARY_DIR}/${NAME}.pc"
2022-10-01 23:39:48 +00:00
"\n"
"Name: ${NAME}\n"
"Description: ${NAME} library\n"
"Version: ${PROJECT_VERSION}\n"
"\n"
"Requires:\n"
"Cflags: -I${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n")
2022-10-02 10:12:07 +00:00
2022-10-01 23:39:48 +00:00
if(NOT TYPE STREQUAL "INTERFACE")
2022-10-04 03:08:31 +00:00
file(APPEND "${PROJECT_BINARY_DIR}/${NAME}.pc"
2022-10-01 23:39:48 +00:00
"Libs: -L${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} -l${NAME}\n")
endif()
2022-10-02 10:33:23 +00:00
# Установка файла для pkg-config
2022-10-01 23:39:48 +00:00
install(
2022-10-04 03:08:31 +00:00
FILES "${PROJECT_BINARY_DIR}/${NAME}.pc"
2022-10-01 23:39:48 +00:00
COMPONENT dev
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
if(TYPE STREQUAL "OBJECT")
# Установка динамической библиотеки
if(TARGET ${NAME}_shared)
install(
TARGETS ${NAME}_shared
EXPORT ${NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT lib
)
endif()
if(TARGET ${NAME}_static)
2022-10-02 10:33:23 +00:00
# Установка статической библиотеки
2022-10-01 23:39:48 +00:00
install(
TARGETS ${NAME}_static
EXPORT ${NAME}Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT static
)
endif()
endif()
if(TYPE STREQUAL "INTERFACE")
# Установка библиотеки из заголовочных файлов
install(
TARGETS ${NAME}
EXPORT ${NAME}Targets
COMPONENT lib
)
endif()
2022-09-29 10:34:57 +00:00
endfunction()