myx-cmake-example-features/cmake/myx/lib/CreatePackages.cmake

195 lines
8.3 KiB
CMake
Raw Normal View History

2022-10-20 09:53:06 +00:00
function(myx_create_packages TARGET_NAME)
if(NOT ${PROJECT_BINARY_DIR} STREQUAL ${CMAKE_BINARY_DIR})
return()
endif()
set(options)
set(oneValueArgs DEBIAN_PACKAGE_TYPE CPACK_DEBIAN_PACKAGE_SECTION CPACK_DEBIAN_PACKAGE_PRIORITY
CMAKE_INSTALL_DEFAULT_COMPONENT_NAME CPACK_PACKAGE_CONTACT CPACK_PACKAGING_INSTALL_PREFIX)
set(multiValueArgs CPACK_SOURCE_GENERATOR CPACK_GENERATOR CPACK_SOURCE_IGNORE_FILES)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Общие настройки для пакета: организация, автор, версия
if(NOT ${PROJECT_NAME}_CONTACT)
if(${PROJECT_NAME}_AUTHOR_NAME AND ${PROJECT_NAME}_AUTHOR_EMAIL)
set(CPACK_PACKAGE_CONTACT "${${PROJECT_NAME}_AUTHOR_NAME} <${${PROJECT_NAME}_AUTHOR_EMAIL}>")
else()
set(CPACK_PACKAGE_CONTACT "unknown maintainer <nonexistent@mailbox>")
myx_message_warning("\${PROJECT_NAME}_CONTACT variable is required for packaging but unset")
endif()
else()
set(CPACK_PACKAGE_CONTACT ${${PROJECT_NAME}_CONTACT})
endif()
if(NOT ${PROJECT_NAME}_VENDOR)
if(${PROJECT_NAME}_AUTHOR_NAME)
set(CPACK_PACKAGE_VENDOR "${${PROJECT_NAME}_AUTHOR_NAME}")
else()
set(CPACK_PACKAGE_VENDOR "unknown vendor")
myx_message_warning("\${PROJECT_NAME}_VENDOR variable is required for packaging but unset")
endif()
else()
set(CPACK_PACKAGE_VENDOR ${${PROJECT_NAME}_VENDOR})
endif()
string(TOLOWER ${PROJECT_NAME} PN)
set(CPACK_PACKAGE_NAME ${PN})
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
if(NOT CPACK_PACKAGING_INSTALL_PREFIX)
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
endif()
# Параметры для архива исходных текстов
if(NOT ARG_CPACK_SOURCE_GENERATOR)
set(CPACK_SOURCE_GENERATOR "TXZ")
else()
set(ARG_CPACK_SOURCE_GENERATOR ${CPACK_SOURCE_GENERATOR})
endif()
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PN}-${CPACK_PACKAGE_VERSION}")
# Типы генераторов для бинарных архивов
if(NOT ARG_CPACK_GENERATOR)
set(CPACK_GENERATOR "TXZ" "DEB")
else()
set(CPACK_GENERATOR ${ARG_CPACK_GENERATOR})
endif()
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
list(REMOVE_ITEM CPACK_GENERATOR "DEB")
endif()
# Параметры для архива собранного проекта
set(CPACK_TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR})
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(CPACK_TARGET_ARCH "amd64")
endif()
set(CPACK_PACKAGE_FILE_NAME "${PN}_${CPACK_PACKAGE_VERSION}")
# Список масок для исключения из архива исходных текстов
set(CPACK_SOURCE_IGNORE_FILES
${ARG_CPACK_SOURCE_IGNORE_FILES}
${CMAKE_BINARY_DIR}
"^${CMAKE_SOURCE_DIR}/.?build.?/"
"^${CMAKE_SOURCE_DIR}/.?output.?/"
"^${CMAKE_SOURCE_DIR}/files/var"
"^${CMAKE_SOURCE_DIR}/files/log"
"CMakeLists.txt.user.*"
".*.autosave"
".*.status"
"~$"
"\\\\.swp$")
option(MYX_COMPACT_SOURCE_PACKAGE "Make compact source package" ON)
if(MYX_COMPACT_SOURCE_PACKAGE)
# Список масок для исключения из архива исходных текстов для более компактного архива
set(CPACK_SOURCE_IGNORE_FILES
${CPACK_SOURCE_IGNORE_FILES}
"\\\\.git"
"/\\\\.git/"
"/\\\\.gitlab-ci/"
"\\\\.clang-tidy$"
"\\\\.cmake-format$"
"\\\\.gitignore$"
"\\\\.gitattributes$"
"\\\\.gitmodules$"
"\\\\.gitlab-ci.yml$")
endif()
if("TXZ" IN_LIST CPACK_GENERATOR)
set(CPACK_ARCHIVE_COMPONENT_INSTALL OFF)
set(CPACK_ARCHIVE_FILE_NAME "${PN}_${CPACK_TARGET_ARCH}_${CPACK_PACKAGE_VERSION}")
endif()
if("DEB" IN_LIST CPACK_GENERATOR)
set(CPACK_DEB_MONOLITHIC_INSTALL OFF)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
# По умолчанию пакет собирается для дистрибутива unstable
if(NOT ARG_DEBIAN_PACKAGE_TYPE)
set(DEBIAN_PACKAGE_TYPE "unstable")
endif()
if(NOT ARG_CPACK_DEBIAN_PACKAGE_SECTION)
set(CPACK_DEBIAN_PACKAGE_SECTION "misc")
endif()
if(NOT ARG_CPACK_DEBIAN_PACKAGE_PRIORITY)
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
endif()
# По умолчанию пакет для Debian делится на компоненты
if(NOT ARG_CPACK_DEB_COMPONENT_INSTALL)
set(CPACK_DEB_COMPONENT_INSTALL ON)
endif()
# Если имя компонента по умолчанию не определено, то устанавливается main
if(NOT CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME MAIN)
endif()
# В списке компонентов обязательно должны быть main, lib, dev, static и doc
#list(APPEND CPACK_COMPONENTS_ALL main lib dev static doc)
# TODO
#list(REMOVE_DUPLICATES CPACK_COMPONENTS_ALL)
set(deb_arch_suffix "${CPACK_PACKAGE_VERSION}_${CPACK_TARGET_ARCH}.deb")
# Правило формирования имени пакета и файла для компонента main
set(CPACK_DEBIAN_MAIN_PACKAGE_NAME "${PN}")
set(CPACK_DEBIAN_MAIN_FILE_NAME ${CPACK_DEBIAN_MAIN_PACKAGE_NAME}_${deb_arch_suffix})
# Правило формирования имени пакета и файла для компонента lib
set(CPACK_DEBIAN_LIB_PACKAGE_NAME "lib${PN}${PROJECT_VERSION_MAJOR}")
set(CPACK_DEBIAN_LIB_FILE_NAME ${CPACK_DEBIAN_LIB_PACKAGE_NAME}_${deb_arch_suffix})
# Правило формирования имени пакета и файла для компонента dev
set(CPACK_DEBIAN_DEV_PACKAGE_NAME "lib${PN}-dev")
set(CPACK_DEBIAN_DEV_FILE_NAME ${CPACK_DEBIAN_DEV_PACKAGE_NAME}_${deb_arch_suffix})
# Правило формирования имени пакета и файла для компонента static
set(CPACK_DEBIAN_STATIC_PACKAGE_NAME "lib${PN}${PROJECT_VERSION_MAJOR}-static-dev")
set(CPACK_DEBIAN_STATIC_FILE_NAME ${CPACK_DEBIAN_STATIC_PACKAGE_NAME}_${deb_arch_suffix})
set(CPACK_DEBIAN_STATIC_PACKAGE_DEPENDS "lib${PN}-dev")
# Правило формирования имени пакета и файла для компонента doc
set(CPACK_DEBIAN_DOC_PACKAGE_NAME "${PN}-doc")
set(CPACK_DEBIAN_DOC_FILE_NAME ${PN}-doc_${CPACK_PACKAGE_VERSION}_all.deb)
foreach(iter ${CPACK_COMPONENTS_ALL})
string(TOLOWER ${iter} _cl)
string(TOUPPER ${iter} _cu)
# Правила формирования имени пакета и файла для остальных компонентов
if((NOT ${_cu} STREQUAL MAIN) AND
(NOT ${_cu} STREQUAL LIB) AND
(NOT ${_cu} STREQUAL DEV) AND
(NOT ${_cu} STREQUAL STATIC) AND
(NOT ${_cu} STREQUAL DOC))
set(CPACK_DEBIAN_${_cu}_PACKAGE_NAME "${PN}-${_cl}")
set(CPACK_DEBIAN_${_cu}_FILE_NAME "${CPACK_DEBIAN_${_cu}_PACKAGE_NAME}_${deb_arch_suffix}")
endif()
# Если в каталоге ${CMAKE_SOURCE_DIR}/cmake/deb/${_cl} находятся сценарии сопровождающего
# postinst, preinst, postrm и prerm, то они будут добавлены к пакету.
if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/preinst")
list(APPEND CPACK_DEBIAN_${_cu}_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/preinst")
endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/postinst")
list(APPEND CPACK_DEBIAN_${_cu}_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/postinst")
endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/prerm")
list(APPEND CPACK_DEBIAN_${_cu}_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/prerm")
endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/postrm")
list(APPEND CPACK_DEBIAN_${_cu}_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/postrm")
endif()
endforeach()
if(UNIX AND NOT TARGET deb)
add_custom_target(deb WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND cpack -G DEB)
add_dependencies(deb ${TARGET_NAME})
endif()
endif()
# Подключение модуля, выполняющего сборку архивов и пакетов
include(CPack)
endfunction(myx_create_packages TARGET_NAME)