myx/MyxCMake/lib/AddObjectLibrary.cmake

200 lines
8.7 KiB
CMake
Raw Permalink Normal View History

2022-10-19 11:39:26 +00:00
#[=======================================================================[.rst:
2022-10-20 08:50:52 +00:00
myx_add_object_library
----------------------
2022-10-19 11:39:26 +00:00
Вспомогательная функция для создания объектной библиотеки::
myx_add_object_library(TARGET_NAME
[ OUTPUT_NAME output_name ] |
2023-07-27 11:27:39 +00:00
[ NO_EXPORT ] |
2022-10-19 11:39:26 +00:00
[ EXPORT_FILE_NAME file_name ] |
[ EXPORT_BASE_NAME base_name ])
Обязательные параметры: `TARGET_NAME` - имя библиотеки.
Параметр `OUTPUT_NAME` определяет базовое имя выходных файлов.
2023-07-27 11:27:39 +00:00
Если указана опция `NO_EXPORT`, то файл экспорта не генерируется.
2022-10-19 11:39:26 +00:00
Параметр `EXPORT_FILE_NAME` задаёт имя заголовочного файла экспортируемых
переменных, а `EXPORT_BASE_NAME` - базовый суффикс для формирования имён переменных.
Все остальные параметры передаются в стандартную функцию `add_library()`
#]=======================================================================]
include_guard(GLOBAL)
2024-03-18 21:16:53 +00:00
if(${CMAKE_VERSION} VERSION_LESS 3.17)
2022-10-19 11:39:26 +00:00
set(MYX_CMAKE_LIB_DIR_BACKPORT "${CMAKE_CURRENT_LIST_DIR}")
endif()
function(myx_add_object_library TARGET_NAME)
2024-03-18 21:16:53 +00:00
if(${CMAKE_VERSION} VERSION_LESS 3.17)
2022-10-19 11:39:26 +00:00
set(CMAKE_CURRENT_FUNCTION_LIST_DIR ${MYX_CMAKE_LIB_DIR_BACKPORT})
endif()
include(CMakePackageConfigHelpers)
2023-07-27 11:27:39 +00:00
set(options NO_EXPORT)
2022-10-19 11:39:26 +00:00
set(oneValueArgs OUTPUT_NAME EXPORT_FILE_NAME EXPORT_BASE_NAME)
set(multiValueArgs)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT ARG_OUTPUT_NAME)
set(ARG_OUTPUT_NAME ${TARGET_NAME})
endif()
# Вызов стандартной функции `add_library()`
2022-11-02 12:51:08 +00:00
add_library(${TARGET_NAME} OBJECT ${ARG_UNPARSED_ARGUMENTS})
2022-10-19 11:39:26 +00:00
2024-03-12 13:27:30 +00:00
string(TOUPPER ${TARGET_NAME} project_name_upper)
2022-10-19 11:39:26 +00:00
# Опция для разрешения сборки динамической библиотеки
2024-03-12 13:27:30 +00:00
cmake_dependent_option(${project_name_upper}_BUILD_SHARED
2022-10-19 11:39:26 +00:00
"Build shared library for ${TARGET_NAME}" ON "BUILD_SHARED_LIBS" OFF)
# Опция для разрешения сборки статической библиотеки
2024-03-12 13:27:30 +00:00
cmake_dependent_option(${project_name_upper}_BUILD_STATIC
2022-10-19 11:39:26 +00:00
"Build static library for ${TARGET_NAME}" ON "NOT BUILD_SHARED_LIBS" OFF)
# Стандартные пути к заголовочным файлам
target_include_directories(${TARGET_NAME}
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
# Сборка позиционно-независимых объектных файлов нужна
# для создания динамической библиотеки
set_target_properties(${TARGET_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
2023-07-27 11:27:39 +00:00
if(NOT ARG_NO_EXPORT)
include(GenerateExportHeader)
if(NOT EXPORT_BASE_NAME)
2024-03-12 13:27:30 +00:00
set(ARG_EXPORT_BASE_NAME ${project_name_upper})
2023-07-27 11:27:39 +00:00
endif()
if(NOT ARG_EXPORT_FILE_NAME)
set(ARG_EXPORT_FILE_NAME "${PROJECT_SOURCE_DIR}/include/${TARGET_NAME}/${TARGET_NAME}_export.hpp")
endif()
generate_export_header(${TARGET_NAME}
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}
DEFINE_NO_DEPRECATED
)
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY INTERFACE_HEADER_FILES "${ARG_EXPORT_FILE_NAME}")
2022-10-19 11:39:26 +00:00
endif()
# Цель для создания динамической библиотеки из объектных файлов
2024-03-12 13:27:30 +00:00
if(${project_name_upper}_BUILD_SHARED)
2022-10-19 11:39:26 +00:00
# Для создания динамической библиотеки используются объектные файлы цели ${TARGET_NAME}
add_library(${TARGET_NAME}_shared SHARED $<TARGET_OBJECTS:${TARGET_NAME}>)
# Установка дополнительных свойств для цели ${TARGET_NAME}_shared
# VERSION: версия библиотеки
# SOVERSION: мажорная версия библиотеки
# LIBRARY_OUTPUT_DIRECTORY: каталог для записи результатов сборки
# OUTPUT_NAME: базовое имя выходного файла (без учёта расширения)
set_target_properties(${TARGET_NAME}_shared PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
OUTPUT_NAME ${ARG_OUTPUT_NAME})
endif()
# Цель для создания статической библиотеки из объектных файлов
2024-03-12 13:27:30 +00:00
if(${project_name_upper}_BUILD_STATIC)
2022-10-19 11:39:26 +00:00
# Для создания статической библиотеки используются
# объектные файлы цели ${TARGET_NAME}
add_library(${TARGET_NAME}_static STATIC $<TARGET_OBJECTS:${TARGET_NAME}>)
# Установка дополнительных свойств для цели ${TARGET_NAME}_static
# ARCHIVE_OUTPUT_DIRECTORY: каталог для записи результатов сборки
# OUTPUT_NAME: базовое имя выходного файла (без учёта расширения)
set_target_properties(${TARGET_NAME}_static PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
OUTPUT_NAME ${ARG_OUTPUT_NAME})
endif()
# Если вызов был выполнен не из проекта верхнего уровня,
# то созданная цель исключается из цели `all`.
# При этом сама цель `${TARGET_NAME}` может участвовать в сборке,
# если окажется в перечне зависимостей.
if(NOT PROJECT_IS_TOP_LEVEL)
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"
"libdir=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\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"
"Libs: -L${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} -l${TARGET_NAME}\n")
# Установка файла для pkg-config
install(
FILES "${PROJECT_BINARY_DIR}/${TARGET_NAME}.pc"
COMPONENT DEV
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
# Установка динамической библиотеки
if(TARGET ${TARGET_NAME}_shared)
install(
TARGETS ${TARGET_NAME}_shared
EXPORT ${TARGET_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT LIB
)
endif()
# Установка статической библиотеки
if(TARGET ${TARGET_NAME}_static)
install(
TARGETS ${TARGET_NAME}_static
EXPORT ${TARGET_NAME}Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT STATIC
)
endif()
endfunction()