Skip to content

Commit

Permalink
[cpack] Add CPackConfigDEB.cmake with specific DEB variables and logic
Browse files Browse the repository at this point in the history
  • Loading branch information
hudokkow committed Jul 6, 2016
1 parent ae320bf commit aef1f75
Showing 1 changed file with 271 additions and 0 deletions.
271 changes: 271 additions & 0 deletions project/cmake/cpack/CPackConfigDEB.cmake
@@ -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)

0 comments on commit aef1f75

Please sign in to comment.