myx/MyxCMake/lib/CreatePackages.cmake
2022-10-20 11:50:52 +03:00

195 lines
8.3 KiB
CMake
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)