diff options
Diffstat (limited to 'Modules/CPackDeb.cmake')
-rw-r--r-- | Modules/CPackDeb.cmake | 229 |
1 files changed, 197 insertions, 32 deletions
diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake index b41d926..d93d924 100644 --- a/Modules/CPackDeb.cmake +++ b/Modules/CPackDeb.cmake @@ -50,8 +50,21 @@ # * Mandatory : YES # * Default : :variable:`CPACK_PACKAGE_VERSION` # +# .. variable:: CPACK_DEBIAN_PACKAGE_RELEASE +# +# The Debian package release - Debian revision number. +# +# * Mandatory : YES +# * Default : 1 +# +# This is the numbering of the DEB package itself, i.e. the version of the +# packaging and not the version of the content (see +# :variable:`CPACK_DEBIAN_PACKAGE_VERSION`). One may change the default value +# if the previous packaging was buggy and/or you want to put here a fancy Linux +# distro specific numbering. # # .. variable:: CPACK_DEBIAN_PACKAGE_ARCHITECTURE +# CPACK_DEBIAN_<COMPONENT>_PACKAGE_ARCHITECTURE # # The Debian package architecture # @@ -331,6 +344,32 @@ # See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps # # +# .. variable:: CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS +# +# * Mandatory : NO +# * Default : OFF +# +# Allows to generate shlibs control file automatically. Compatibility is defined by +# CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY variable value. +# +# .. note:: +# +# Libraries are only considered if they have both library name and version +# set. This can be done by setting SOVERSION property with +# :command:`set_target_properties` command. +# +# +# .. variable:: CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY +# +# * Mandatory : NO +# * Default : "=" +# +# Defines compatibility policy for auto-generated shlibs control file. +# Possible values: "=", ">=" +# +# See https://www.debian.org/doc/debian-policy/ch-sharedlibs.html#s-sharedlibs-shlibdeps +# +# # .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA # CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_EXTRA # @@ -399,6 +438,10 @@ #============================================================================= # Copyright 2007-2009 Kitware, Inc. # Copyright 2007-2009 Mathieu Malaterre <mathieu.malaterre@gmail.com> +# Copyright 2014-2016 Alexander Smorkalov <alexander.smorkalov@itseez.com> +# Copyright 2014-2016 Roman Donchenko <roman.donchenko@itseez.com> +# Copyright 2014-2016 Roman Kharitonov <roman.kharitonov@itseez.com> +# Copyright 2014-2016 Ilya Lavrenov <ilya.lavrenov@itseez.com> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -423,6 +466,38 @@ if(NOT UNIX) message(FATAL_ERROR "CPackDeb.cmake may only be used under UNIX.") endif() +function(get_component_package_name var component) + string(TOUPPER "${component}" component_upcase) + if(CPACK_DEBIAN_${component_upcase}_PACKAGE_NAME) + string(TOLOWER "${CPACK_DEBIAN_${component_upcase}_PACKAGE_NAME}" package_name) + else() + string(TOLOWER "${CPACK_DEBIAN_PACKAGE_NAME}-${component}" package_name) + endif() + + set("${var}" "${package_name}" PARENT_SCOPE) +endfunction() + +#extract library name and version for given shared object +function(extract_so_info shared_object libname version) + if(READELF_EXECUTABLE) + execute_process(COMMAND "${READELF_EXECUTABLE}" -d "${shared_object}" + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(result EQUAL 0) + string(REGEX MATCH "\\(SONAME\\)[^\n]*\\[([^\n]+)\\.so\\.([^\n]*)\\]" soname "${output}") + set(${libname} "${CMAKE_MATCH_1}" PARENT_SCOPE) + set(${version} "${CMAKE_MATCH_2}" PARENT_SCOPE) + else() + message(WARNING "Error running readelf for \"${shared_object}\"") + endif() + else() + message(FATAL_ERROR "Readelf utility is not available.") + endif() +endfunction() + function(cpack_deb_prepare_package_vars) # CPACK_DEBIAN_PACKAGE_SHLIBDEPS # If specify OFF, only user depends are used @@ -447,6 +522,39 @@ function(cpack_deb_prepare_package_vars) endif() endif() + if(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OR CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS) + # Generating binary list - Get type of all install files + cmake_policy(PUSH) + # Tell file(GLOB_RECURSE) not to follow directory symlinks + # even if the project does not set this policy to NEW. + cmake_policy(SET CMP0009 NEW) + file(GLOB_RECURSE FILE_PATHS_ LIST_DIRECTORIES false RELATIVE "${WDIR}" "${WDIR}/*") + cmake_policy(POP) + + # get file info so that we can determine if file is executable or not + unset(CPACK_DEB_INSTALL_FILES) + foreach(FILE_ IN LISTS FILE_PATHS_) + execute_process(COMMAND file "./${FILE_}" + WORKING_DIRECTORY "${WDIR}" + OUTPUT_VARIABLE INSTALL_FILE_) + list(APPEND CPACK_DEB_INSTALL_FILES "${INSTALL_FILE_}") + endforeach() + + # Only dynamically linked ELF files are included + # Extract only file name infront of ":" + foreach(_FILE IN LISTS CPACK_DEB_INSTALL_FILES) + if(_FILE MATCHES "ELF.*dynamically linked") + string(REGEX MATCH "(^.*):" _FILE_NAME "${_FILE}") + list(APPEND CPACK_DEB_BINARY_FILES "${CMAKE_MATCH_1}") + set(CONTAINS_EXECUTABLE_FILES_ TRUE) + endif() + if(_FILE MATCHES "ELF.*shared object") + string(REGEX MATCH "(^.*):" _FILE_NAME "${_FILE}") + list(APPEND CPACK_DEB_SHARED_OBJECT_FILES "${CMAKE_MATCH_1}") + endif() + endforeach() + endif() + if(CPACK_DEBIAN_PACKAGE_SHLIBDEPS) # dpkg-shlibdeps is a Debian utility for generating dependency list find_program(SHLIBDEPS_EXECUTABLE dpkg-shlibdeps) @@ -468,33 +576,6 @@ function(cpack_deb_prepare_package_vars) message("CPackDeb Debug: dpkg-shlibdeps version is <${SHLIBDEPS_EXECUTABLE_VERSION}>") endif() - # Generating binary list - Get type of all install files - cmake_policy(PUSH) - # Tell file(GLOB_RECURSE) not to follow directory symlinks - # even if the project does not set this policy to NEW. - cmake_policy(SET CMP0009 NEW) - file(GLOB_RECURSE FILE_PATHS_ LIST_DIRECTORIES false RELATIVE "${WDIR}" "${WDIR}/*") - cmake_policy(POP) - - # get file info so that we can determine if file is executable or not - unset(CPACK_DEB_INSTALL_FILES) - foreach(FILE_ IN LISTS FILE_PATHS_) - execute_process(COMMAND file "./${FILE_}" - WORKING_DIRECTORY "${WDIR}" - OUTPUT_VARIABLE INSTALL_FILE_) - list(APPEND CPACK_DEB_INSTALL_FILES "${INSTALL_FILE_}") - endforeach() - - # Only dynamically linked ELF files are included - # Extract only file name infront of ":" - foreach(_FILE ${CPACK_DEB_INSTALL_FILES}) - if( ${_FILE} MATCHES "ELF.*dynamically linked") - string(REGEX MATCH "(^.*):" _FILE_NAME "${_FILE}") - list(APPEND CPACK_DEB_BINARY_FILES "${CMAKE_MATCH_1}") - set(CONTAINS_EXECUTABLE_FILES_ TRUE) - endif() - endforeach() - if(CONTAINS_EXECUTABLE_FILES_) message("CPackDeb: - Generating dependency list") @@ -586,7 +667,9 @@ function(cpack_deb_prepare_package_vars) endif() # Architecture: (mandatory) - if(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE) + if(CPACK_DEB_PACKAGE_COMPONENT AND CPACK_DEBIAN_${_local_component_name}_PACKAGE_ARCHITECTURE) + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_DEBIAN_${_local_component_name}_PACKAGE_ARCHITECTURE}") + elseif(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE) # There is no such thing as i686 architecture on debian, you should use i386 instead # $ dpkg --print-architecture find_program(DPKG_CMD dpkg) @@ -630,6 +713,22 @@ function(cpack_deb_prepare_package_vars) endif() endif() endforeach() + set(COMPONENT_DEPENDS "") + foreach (_PACK ${CPACK_COMPONENT_${_local_component_name}_DEPENDS}) + get_component_package_name(_PACK_NAME "${_PACK}") + if(COMPONENT_DEPENDS) + set(COMPONENT_DEPENDS "${_PACK_NAME} (= ${CPACK_DEBIAN_PACKAGE_VERSION}), ${COMPONENT_DEPENDS}") + else() + set(COMPONENT_DEPENDS "${_PACK_NAME} (= ${CPACK_DEBIAN_PACKAGE_VERSION})") + endif() + endforeach() + if(COMPONENT_DEPENDS) + if(CPACK_DEBIAN_PACKAGE_DEPENDS) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${COMPONENT_DEPENDS}, ${CPACK_DEBIAN_PACKAGE_DEPENDS}") + else() + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${COMPONENT_DEPENDS}") + endif() + endif() endif() # at this point, the CPACK_DEBIAN_PACKAGE_DEPENDS is properly set @@ -637,7 +736,7 @@ function(cpack_deb_prepare_package_vars) # Append automatically discovered dependencies . if(NOT "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}" STREQUAL "") if (CPACK_DEBIAN_PACKAGE_DEPENDS) - set (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}, ${CPACK_DEBIAN_PACKAGE_DEPENDS}") + set (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}, ${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}") else () set (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}") endif () @@ -718,14 +817,75 @@ function(cpack_deb_prepare_package_vars) set(CPACK_DEBIAN_${VAR_NAME_} "${CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}}") endif() endforeach() + get_component_package_name(CPACK_DEBIAN_PACKAGE_NAME ${_local_component_name}) + endif() - if(CPACK_DEBIAN_${_local_component_name}_PACKAGE_NAME) - string(TOLOWER "${CPACK_DEBIAN_${_local_component_name}_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME) + set(CPACK_DEBIAN_PACKAGE_SHLIBS_LIST "") + + if (NOT CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY) + set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY "=") + endif() + + find_program(READELF_EXECUTABLE NAMES readelf) + + if(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS) + if(READELF_EXECUTABLE) + foreach(_FILE IN LISTS CPACK_DEB_SHARED_OBJECT_FILES) + extract_so_info("${_FILE}" libname soversion) + if(libname AND soversion) + list(APPEND CPACK_DEBIAN_PACKAGE_SHLIBS_LIST + "${libname} ${soversion} ${CPACK_DEBIAN_PACKAGE_NAME} (${CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY} ${CPACK_PACKAGE_VERSION})") + else() + message(AUTHOR_WARNING "Shared library '${_FILE}' is missing soname or soversion. Library will not be added to DEBIAN/shlibs control file.") + endif() + endforeach() + if (CPACK_DEBIAN_PACKAGE_SHLIBS_LIST) + string(REPLACE ";" "\n" CPACK_DEBIAN_PACKAGE_SHLIBS_LIST "${CPACK_DEBIAN_PACKAGE_SHLIBS_LIST}") + endif() else() - string(TOLOWER "${CPACK_DEBIAN_PACKAGE_NAME}-${CPACK_DEB_PACKAGE_COMPONENT}" CPACK_DEBIAN_PACKAGE_NAME) + message(FATAL_ERROR "Readelf utility is not available. CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS option is not available.") + endif() + endif() + + # add ldconfig call in default postrm and postint + set(CPACK_ADD_LDCONFIG_CALL 0) + foreach(_FILE ${CPACK_DEB_SHARED_OBJECT_FILES}) + get_filename_component(_DIR ${_FILE} DIRECTORY) + # all files in CPACK_DEB_SHARED_OBJECT_FILES have dot at the beginning + if(_DIR STREQUAL "./lib" OR _DIR STREQUAL "./usr/lib") + set(CPACK_ADD_LDCONFIG_CALL 1) endif() + endforeach() + + if(CPACK_ADD_LDCONFIG_CALL) + set(CPACK_DEBIAN_GENERATE_POSTINST 1) + set(CPACK_DEBIAN_GENERATE_POSTRM 1) + foreach(f ${PACKAGE_CONTROL_EXTRA}) + get_filename_component(n "${f}" NAME) + if("${n}" STREQUAL "postinst") + set(CPACK_DEBIAN_GENERATE_POSTINST 0) + endif() + if("${n}" STREQUAL "postrm") + set(CPACK_DEBIAN_GENERATE_POSTRM 0) + endif() + endforeach() + else() + set(CPACK_DEBIAN_GENERATE_POSTINST 0) + set(CPACK_DEBIAN_GENERATE_POSTRM 0) + endif() + + if(NOT CPACK_DEBIAN_PACKAGE_RELEASE) + set(CPACK_DEBIAN_PACKAGE_RELEASE 1) endif() + # Patch package file name to be in corrent debian format: + # <foo>_<VersionNumber>-<DebianRevisionNumber>_<DebianArchitecture>.deb + set(CPACK_OUTPUT_FILE_NAME + "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}-${CPACK_DEBIAN_PACKAGE_RELEASE}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb") + set(CPACK_TEMPORARY_PACKAGE_FILE_NAME "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_OUTPUT_FILE_NAME}") + get_filename_component(BINARY_DIR "${CPACK_OUTPUT_FILE_PATH}" DIRECTORY) + set(CPACK_OUTPUT_FILE_PATH "${BINARY_DIR}/${CPACK_OUTPUT_FILE_NAME}") + # Print out some debug information if we were asked for that if(CPACK_DEBIAN_PACKAGE_DEBUG) message("CPackDeb:Debug: CPACK_TOPLEVEL_DIRECTORY = '${CPACK_TOPLEVEL_DIRECTORY}'") @@ -755,6 +915,8 @@ function(cpack_deb_prepare_package_vars) #endif() # move variables to parent scope so that they may be used to create debian package + set(GEN_CPACK_OUTPUT_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}" PARENT_SCOPE) + set(GEN_CPACK_TEMPORARY_PACKAGE_FILE_NAME "${CPACK_TEMPORARY_PACKAGE_FILE_NAME}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_NAME "${CPACK_DEBIAN_PACKAGE_NAME}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_DEBIAN_PACKAGE_VERSION}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_SECTION "${CPACK_DEBIAN_PACKAGE_SECTION}" PARENT_SCOPE) @@ -773,11 +935,14 @@ function(cpack_deb_prepare_package_vars) set(GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS "${CPACK_DEBIAN_PACKAGE_CONFLICTS}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_PROVIDES "${CPACK_DEBIAN_PACKAGE_PROVIDES}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_REPLACES "${CPACK_DEBIAN_PACKAGE_REPLACES}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_SHLIBS "${CPACK_DEBIAN_PACKAGE_SHLIBS_LIST}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION "${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_SOURCE "${CPACK_DEBIAN_PACKAGE_SOURCE}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_GENERATE_POSTINST "${CPACK_DEBIAN_GENERATE_POSTINST}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_GENERATE_POSTRM "${CPACK_DEBIAN_GENERATE_POSTRM}" PARENT_SCOPE) set(GEN_WDIR "${WDIR}" PARENT_SCOPE) endfunction() |