Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[cpack] Add CPackConfigDEB.cmake with specific DEB variables and logic
- Loading branch information
Showing
1 changed file
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,271 @@ | ||
# include CPackConfig.cmake with variables common to all generators | ||
include(${PROJECT_SOURCE_DIR}/cpack/CPackConfig.cmake) | ||
# include Macros.cmake to automate generation of time/date stamps, maintainer, etc. | ||
include(${PROJECT_SOURCE_DIR}/scripts/common/Macros.cmake) | ||
|
||
# set CPack generator | ||
set(CPACK_GENERATOR DEB) | ||
|
||
# set packaging by components | ||
set(CPACK_DEB_COMPONENT_INSTALL ON) | ||
|
||
# enforce Debian policy permission rules | ||
set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION ON) | ||
|
||
# packaging by components doesn't fully work with CMake/CPack <3.6.0 | ||
# CPACK_DEBIAN_<COMPONENT>_FILE_NAME is a 3.6.0 addition | ||
# warn if detected version is lower | ||
if(CMAKE_VERSION VERSION_LESS 3.6) | ||
message(WARNING "DEB Generator: Need CMake/CPack 3.6 or later to produce correctly named packages.") | ||
endif() | ||
|
||
# distro codename | ||
if(NOT DISTRO_CODENAME) | ||
find_program(LSB_RELEASE_CMD lsb_release) | ||
if(NOT LSB_RELEASE_CMD) | ||
message(WARNING "DEB Generator: Can't find lsb_release in your path. Setting DISTRO_CODENAME to unknown.") | ||
set(DISTRO_CODENAME unknown) | ||
else() | ||
execute_process(COMMAND ${LSB_RELEASE_CMD} -cs | ||
OUTPUT_VARIABLE DISTRO_CODENAME | ||
OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
endif() | ||
endif() | ||
|
||
# package name version | ||
string(TIMESTAMP PACKAGE_TIMESTAMP "%Y%m%d.%H%M" UTC) | ||
if(CMAKE_BUILD_TYPE STREQUAL Debug) | ||
set(PACKAGE_NAME_VERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}~git${PACKAGE_TIMESTAMP}-${GIT_HASH}-0${DISTRO_CODENAME}) | ||
else() | ||
set(PACKAGE_NAME_VERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}~git${PACKAGE_TIMESTAMP}-final-0${DISTRO_CODENAME}) | ||
endif() | ||
|
||
# package version | ||
if(NOT CPACK_DEBIAN_PACKAGE_VERSION) | ||
set(CPACK_DEBIAN_PACKAGE_VERSION 2:${PACKAGE_NAME_VERSION}) | ||
endif() | ||
|
||
# architecture | ||
if(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE) | ||
find_program(DPKG_CMD dpkg) | ||
if(NOT DPKG_CMD) | ||
message(WARNING "DEB Generator: Can't find dpkg in your path. Setting CPACK_DEBIAN_PACKAGE_ARCHITECTURE to i386.") | ||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386) | ||
endif() | ||
execute_process(COMMAND "${DPKG_CMD}" --print-architecture | ||
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE | ||
OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
endif() | ||
|
||
# package maintainer | ||
if(NOT CPACK_DEBIAN_PACKAGE_MAINTAINER) | ||
userstamp() | ||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${PACKAGE_MAINTAINER}) | ||
unset(PACKAGE_MAINTAINER) | ||
endif() | ||
|
||
# package description common to all packages | ||
if(NOT CPACK_DEBIAN_PACKAGE_DESCRIPTION) | ||
file(STRINGS ${PROJECT_SOURCE_DIR}/cpack/debian-metadata/package-description.txt DESC_LINES) | ||
foreach(LINE ${DESC_LINES}) | ||
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_DEBIAN_PACKAGE_DESCRIPTION} ${LINE}\n") | ||
endforeach() | ||
endif() | ||
|
||
# package homepage | ||
if(NOT CPACK_DEBIAN_PACKAGE_HOMEPAGE) | ||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://kodi.tv") | ||
endif() | ||
|
||
# generate a Debian compliant changelog | ||
set(CHANGELOG_HEADER "${CPACK_PACKAGE_NAME} (${CPACK_DEBIAN_PACKAGE_VERSION}) ${DISTRO_CODENAME}\; urgency=high") | ||
rfc2822stamp() | ||
# two spaces between maintainer and timestamp is NOT a mistake | ||
set(CHANGELOG_FOOTER " -- ${CPACK_DEBIAN_PACKAGE_MAINTAINER} ${RFC2822_TIMESTAMP}") | ||
|
||
find_package(Git) | ||
find_program(GZIP_CMD gzip) | ||
if(GIT_FOUND AND GZIP_CMD AND EXISTS ${CORE_SOURCE_DIR}/.git) | ||
execute_process(COMMAND ${GIT_EXECUTABLE} log --no-merges --pretty=format:"%n [%an]%n * %s" --since="last month" | ||
OUTPUT_VARIABLE CHANGELOG | ||
WORKING_DIRECTORY ${CORE_SOURCE_DIR} | ||
OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
string(REPLACE "\"" "" CHANGELOG ${CHANGELOG}) | ||
file(WRITE ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/changelog.Debian ${CHANGELOG_HEADER}\n${CHANGELOG}\n\n${CHANGELOG_FOOTER}) | ||
execute_process(COMMAND ${GZIP_CMD} -f -9 ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/changelog.Debian) | ||
unset(CHANGELOG_HEADER) | ||
unset(CHANGELOG_FOOTER) | ||
unset(RFC2822_TIMESTAMP) | ||
else() | ||
message(WARNING "DEB Generator: Can't find git and/or gzip in your path. DEB packages will be missing changelog.Debian.gz.") | ||
endif() | ||
|
||
# configure package metadata files | ||
file(GLOB_RECURSE debian_package_files ${PROJECT_SOURCE_DIR}/cpack/debian-metadata/packages/*.txt.in) | ||
foreach(file ${debian_package_files}) | ||
get_filename_component(package ${file} NAME_WE) | ||
configure_file(${file} | ||
${CPACK_PACKAGE_DIRECTORY}/debian-metadata/${package}.txt @ONLY) | ||
list(APPEND debian_packages ${package}) | ||
endforeach() | ||
unset(debian_package_files) | ||
|
||
# generate packages | ||
include(CMakeParseArguments) | ||
foreach(file ${debian_packages}) | ||
core_file_read_filtered(DEBIAN_METADATA ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/${file}.txt) | ||
string(REPLACE " " ";" DEBIAN_METADATA "${DEBIAN_METADATA}") | ||
cmake_parse_arguments(DEB | ||
"" | ||
"PACKAGE_NAME;PACKAGE_ARCHITECTURE;PACKAGE_SECTION;PACKAGE_PRIORITY" | ||
"PACKAGE_DEPENDS;PACKAGE_RECOMMENDS;PACKAGE_SUGGESTS;PACKAGE_BREAKS;PACKAGE_REPLACES;PACKAGE_PROVIDES;PACKAGE_DESCRIPTION_HEADER;PACKAGE_DESCRIPTION_FOOTER" | ||
${DEBIAN_METADATA}) | ||
string(REPLACE ";" " " DEB_PACKAGE_DEPENDS "${DEB_PACKAGE_DEPENDS}") | ||
string(REPLACE ";" " " DEB_PACKAGE_RECOMMENDS "${DEB_PACKAGE_RECOMMENDS}") | ||
string(REPLACE ";" " " DEB_PACKAGE_SUGGESTS "${DEB_PACKAGE_SUGGESTS}") | ||
string(REPLACE ";" " " DEB_PACKAGE_BREAKS "${DEB_PACKAGE_BREAKS}") | ||
string(REPLACE ";" " " DEB_PACKAGE_REPLACES "${DEB_PACKAGE_REPLACES}") | ||
string(REPLACE ";" " " DEB_PACKAGE_PROVIDES "${DEB_PACKAGE_PROVIDES}") | ||
string(REPLACE ";" " " DEB_PACKAGE_DESCRIPTION_HEADER "${DEB_PACKAGE_DESCRIPTION_HEADER}") | ||
string(REPLACE ";" " " DEB_PACKAGE_DESCRIPTION_FOOTER "${DEB_PACKAGE_DESCRIPTION_FOOTER}") | ||
|
||
string(TOUPPER ${file} COMPONENT) | ||
|
||
if(NOT DEB_PACKAGE_ARCHITECTURE) | ||
message(WARNING "DEB Generator: Mandatory variable CPACK_DEBIAN_${COMPONENT}_PACKAGE_ARCHITECTURE is empty. Setting to ${CPACK_SYSTEM_NAME}.") | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_ARCHITECTURE ${CPACK_SYSTEM_NAME}) | ||
else() | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_ARCHITECTURE ${DEB_PACKAGE_ARCHITECTURE}) | ||
endif() | ||
if(DEB_PACKAGE_NAME) | ||
set(CPACK_DEBIAN_${COMPONENT}_FILE_NAME ${DEB_PACKAGE_NAME}_${PACKAGE_NAME_VERSION}_${DEB_PACKAGE_ARCHITECTURE}.deb) | ||
else() | ||
message(FATAL_ERROR "DEB Generator: Mandatory variable CPACK_DEBIAN_${COMPONENT}_FILE_NAME is not set.") | ||
endif() | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_SOURCE ${CPACK_PACKAGE_NAME}) | ||
if(DEB_PACKAGE_NAME) | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_NAME ${DEB_PACKAGE_NAME}) | ||
else() | ||
message(FATAL_ERROR "DEB Generator: Mandatory variable CPACK_DEBIAN_${COMPONENT}_PACKAGE_NAME is not set.") | ||
endif() | ||
if(DEB_PACKAGE_SECTION) | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_SECTION ${DEB_PACKAGE_SECTION}) | ||
else() | ||
message(FATAL_ERROR "DEB Generator: Mandatory variable CPACK_DEBIAN_${COMPONENT}_PACKAGE_SECTION is not set.") | ||
endif() | ||
if(DEB_PACKAGE_PRIORITY) | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_PRIORITY ${DEB_PACKAGE_PRIORITY}) | ||
else() | ||
message(FATAL_ERROR "DEB Generator: Mandatory variable CPACK_DEBIAN_${COMPONENT}_PACKAGE_PRIORITY is not set.") | ||
endif() | ||
if(DEB_PACKAGE_DEPENDS) | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_DEPENDS "${DEB_PACKAGE_DEPENDS}") | ||
endif() | ||
if(DEB_PACKAGE_RECOMMENDS) | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_RECOMMENDS "${DEB_PACKAGE_RECOMMENDS}") | ||
endif() | ||
if(DEB_PACKAGE_SUGGESTS) | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_SUGGESTS "${DEB_PACKAGE_SUGGESTS}") | ||
endif() | ||
if(DEB_PACKAGE_BREAKS) | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_BREAKS "${DEB_PACKAGE_BREAKS}") | ||
endif() | ||
if(DEB_PACKAGE_REPLACES) | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_REPLACES "${DEB_PACKAGE_REPLACES}") | ||
endif() | ||
if(DEB_PACKAGE_PROVIDES) | ||
set(CPACK_DEBIAN_${COMPONENT}_PACKAGE_PROVIDES "${DEB_PACKAGE_PROVIDES}") | ||
endif() | ||
if(NOT DEB_PACKAGE_DESCRIPTION_HEADER OR NOT DEB_PACKAGE_DESCRIPTION_FOOTER) | ||
message(FATAL_ERROR "DEB Generator: Mandatory variable CPACK_COMPONENT_${COMPONENT}_DESCRIPTION is not set.") | ||
else() | ||
set(CPACK_COMPONENT_${COMPONENT}_DESCRIPTION "\ | ||
${DEB_PACKAGE_DESCRIPTION_HEADER}\n\ | ||
${CPACK_DEBIAN_PACKAGE_DESCRIPTION} \ | ||
${DEB_PACKAGE_DESCRIPTION_FOOTER}") | ||
endif() | ||
if(CPACK_DEBIAN_KODI_PACKAGE_NAME) | ||
set(CPACK_DEBIAN_KODI_PACKAGE_CONTROL_EXTRA | ||
"${PROJECT_SOURCE_DIR}/cpack/debian-metadata/postinst;${PROJECT_SOURCE_DIR}/cpack/debian-metadata/postrm") | ||
endif() | ||
install(FILES ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/changelog.Debian.gz | ||
${CPACK_PACKAGE_DIRECTORY}/debian-metadata/NEWS.Debian.gz | ||
${PROJECT_SOURCE_DIR}/cpack/debian-metadata/copyright | ||
DESTINATION share/doc/${file} | ||
COMPONENT ${file}) | ||
endforeach() | ||
unset(debian_packages) | ||
|
||
# Generate NEWS.Debian | ||
configure_file(${PROJECT_SOURCE_DIR}/cpack/debian-metadata/NEWS.Debian | ||
${CPACK_PACKAGE_DIRECTORY}/debian-metadata/NEWS.Debian @ONLY) | ||
find_program(GZIP_CMD gzip) | ||
if(GZIP_CMD) | ||
execute_process(COMMAND ${GZIP_CMD} -f -9 ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/NEWS.Debian) | ||
else() | ||
message(WARNING "DEB Generator: Can't find gzip in your path. Several DEB packages will be missing NEWS.Debian.") | ||
endif() | ||
|
||
# Generate man pages | ||
configure_file(${CORE_SOURCE_DIR}/docs/manpages/kodi.bin.1 | ||
${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi.bin.1 COPYONLY) | ||
configure_file(${CORE_SOURCE_DIR}/docs/manpages/kodi-ps3remote.1 | ||
${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-ps3remote.1 COPYONLY) | ||
configure_file(${CORE_SOURCE_DIR}/docs/manpages/kodi-send.1 | ||
${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-send.1 COPYONLY) | ||
configure_file(${CORE_SOURCE_DIR}/docs/manpages/kodi-standalone.1 | ||
${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-standalone.1 COPYONLY) | ||
configure_file(${CORE_SOURCE_DIR}/docs/manpages/kodi-wiiremote.1 | ||
${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-wiiremote.1 COPYONLY) | ||
find_program(GZIP_CMD gzip) | ||
if(GZIP_CMD) | ||
execute_process(COMMAND ${GZIP_CMD} -f -9 ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi.bin.1) | ||
execute_process(COMMAND ${GZIP_CMD} -f -9 ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-ps3remote.1) | ||
execute_process(COMMAND ${GZIP_CMD} -f -9 ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-send.1) | ||
execute_process(COMMAND ${GZIP_CMD} -f -9 ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-standalone.1) | ||
execute_process(COMMAND ${GZIP_CMD} -f -9 ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-wiiremote.1) | ||
else() | ||
message(WARNING "DEB Generator: Can't find gzip in your path. Several DEB packages will be missing man pages.") | ||
endif() | ||
install(FILES ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi.bin.1.gz | ||
${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-standalone.1.gz | ||
DESTINATION share/man/man1 | ||
COMPONENT kodi) | ||
install(FILES ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-ps3remote.1.gz | ||
DESTINATION share/man/man1 | ||
COMPONENT kodi-eventclients-ps3) | ||
install(FILES ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-send.1.gz | ||
DESTINATION share/man/man1 | ||
COMPONENT kodi-eventclients-xbmc-send) | ||
install(FILES ${CPACK_PACKAGE_DIRECTORY}/debian-metadata/kodi-wiiremote.1.gz | ||
DESTINATION share/man/man1 | ||
COMPONENT kodi-eventclients-wiiremote) | ||
|
||
### source package generation specific variables | ||
# source generator | ||
set(CPACK_SOURCE_GENERATOR TGZ) | ||
|
||
# source package name | ||
set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}_${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}~git${PACKAGE_TIMESTAMP}-${GIT_HASH}.orig) | ||
|
||
# source dir | ||
set(CMAKE_SOURCE_DIR ${CORE_SOURCE_DIR}) | ||
|
||
# ignore files for source package | ||
set(CPACK_SOURCE_IGNORE_FILES | ||
"/build/" | ||
"/debian/" | ||
"/.git/" | ||
".gitignore" | ||
"yml$" | ||
"~$") | ||
|
||
# unset variables | ||
unset(PACKAGE_TIMESTAMP) | ||
unset(DISTRO_CODENAME) | ||
|
||
# reference docs | ||
# https://cmake.org/cmake/help/latest/module/CPack.html | ||
# https://cmake.org/cmake/help/latest/module/CPackDeb.html | ||
# https://cmake.org/cmake/help/latest/module/CPackComponent.html | ||
include(CPack) |