From e5b70ed0137df3b72f279a039cbdae1a20784473 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Wed, 4 Nov 2015 00:19:58 +0100 Subject: [PATCH] CPackDEB: added config file optional Source field --- .../cpack-deb-config-file-source-field.rst | 6 ++ Modules/CPackDeb.cmake | 37 ++++++++- Source/CPack/cmCPackDebGenerator.cxx | 7 ++ Tests/CMakeLists.txt | 1 + ...yLibCPackConfig-components-source.cmake.in | 33 ++++++++ ...nCPackVerifyResult-components-source.cmake | 75 +++++++++++++++++++ 6 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 Help/release/dev/cpack-deb-config-file-source-field.rst create mode 100644 Tests/CPackComponentsDEB/MyLibCPackConfig-components-source.cmake.in create mode 100644 Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake diff --git a/Help/release/dev/cpack-deb-config-file-source-field.rst b/Help/release/dev/cpack-deb-config-file-source-field.rst new file mode 100644 index 000000000..bbc2aa6ab --- /dev/null +++ b/Help/release/dev/cpack-deb-config-file-source-field.rst @@ -0,0 +1,6 @@ +cpack-deb-config-file-source-field +---------------------------------- + +* The :module:`CPackDeb` module learned to set optional config + file ``Source`` field - monolithic and per-component variable. + See :variable:`CPACK_DEBIAN_PACKAGE_SOURCE`. diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake index 7bd2f504c..875a5345f 100644 --- a/Modules/CPackDeb.cmake +++ b/Modules/CPackDeb.cmake @@ -354,7 +354,28 @@ # set by Debian policy # https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners # - +# .. variable:: CPACK_DEBIAN_PACKAGE_SOURCE +# CPACK_DEBIAN__PACKAGE_SOURCE +# +# Sets the ``Source`` field of the binary Debian package. +# When the binary package name is not the same as the source package name +# (in particular when several components/binaries are generated from one +# source) the source from which the binary has been generated should be +# indicated with the field ``Source``. +# +# * Mandatory : NO +# * Default : +# +# - An empty string for non-component based installations +# - :variable:`CPACK_DEBIAN_PACKAGE_SOURCE` for component-based +# installations. +# +# See https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Source +# +# .. note:: +# +# This value is not interpreted. It is possible to pass an optional +# revision number of the referenced source package as well. #============================================================================= # Copyright 2007-2009 Kitware, Inc. @@ -554,6 +575,15 @@ function(cpack_deb_prepare_package_vars) ) endif() + # Source: (optional) + # in case several packages are constructed from a unique source + # (multipackaging), the source may be indicated as well. + # The source might contain a version if the generated package + # version is different from the source version + if(NOT CPACK_DEBIAN_PACKAGE_SOURCE) + set(CPACK_DEBIAN_PACKAGE_SOURCE "") + endif() + # have a look at get_property(result GLOBAL PROPERTY ENABLED_FEATURES), # this returns the successful find_package() calls, maybe this can help # Depends: @@ -563,7 +593,7 @@ function(cpack_deb_prepare_package_vars) # if per-component dependency, overrides the global CPACK_DEBIAN_PACKAGE_${dependency_type_} # automatic dependency discovery will be performed afterwards. if(CPACK_DEB_PACKAGE_COMPONENT) - foreach(dependency_type_ DEPENDS RECOMMENDS SUGGESTS PREDEPENDS ENHANCES BREAKS CONFLICTS PROVIDES REPLACES) + foreach(dependency_type_ DEPENDS RECOMMENDS SUGGESTS PREDEPENDS ENHANCES BREAKS CONFLICTS PROVIDES REPLACES SOURCE) set(_component_var "CPACK_DEBIAN_${_local_component_name}_PACKAGE_${dependency_type_}") # if set, overrides the global dependency @@ -681,6 +711,7 @@ function(cpack_deb_prepare_package_vars) message("CPackDeb:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = '${CPACK_PACKAGE_INSTALL_DIRECTORY}'") message("CPackDeb:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = '${CPACK_TEMPORARY_PACKAGE_FILE_NAME}'") message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION = '${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}'") + message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_SOURCE = '${CPACK_DEBIAN_PACKAGE_SOURCE}'") endif() # For debian source packages: @@ -719,6 +750,8 @@ function(cpack_deb_prepare_package_vars) 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_WDIR "${WDIR}" PARENT_SCOPE) endfunction() diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 04efb71aa..13c8d8f6c 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -339,6 +339,9 @@ int cmCPackDebGenerator::createDeb() this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES"); const char* debian_pkg_replaces = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_REPLACES"); + const char* debian_pkg_source = + this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE"); + { // the scope is needed for cmGeneratedFileStream cmGeneratedFileStream out(ctlfilename.c_str()); @@ -347,6 +350,10 @@ int cmCPackDebGenerator::createDeb() out << "Section: " << debian_pkg_section << "\n"; out << "Priority: " << debian_pkg_priority << "\n"; out << "Architecture: " << debian_pkg_arch << "\n"; + if(debian_pkg_source && *debian_pkg_source) + { + out << "Source: " << debian_pkg_source << "\n"; + } if(debian_pkg_dep && *debian_pkg_dep) { out << "Depends: " << debian_pkg_dep << "\n"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index ae61bca5e..d42a32285 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1033,6 +1033,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release set(DEB_CONFIGURATIONS_TO_TEST "components-lintian-dpkgdeb-checks" "components-description1" "components-description2" + "components-source" "components-shlibdeps1" "components-depend1" "components-depend2") diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-components-source.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-source.cmake.in new file mode 100644 index 000000000..352f10b99 --- /dev/null +++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-source.cmake.in @@ -0,0 +1,33 @@ +# +# Activate component packaging +# + +if(CPACK_GENERATOR MATCHES "DEB") + set(CPACK_DEB_COMPONENT_INSTALL "ON") +endif() + +# +# Choose grouping way +# +set(CPACK_COMPONENTS_IGNORE_GROUPS 1) + +# setting dependencies +set(CPACK_DEBIAN_PACKAGE_DEPENDS "depend-default") +set(CPACK_DEBIAN_HEADERS_PACKAGE_DEPENDS "depend-headers") + +# this time we set shlibdeps to on +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) +set(CPACK_DEBIAN_HEADERS_PACKAGE_SHLIBDEPS OFF) +set(CPACK_DEBIAN_LIBRARIES_PACKAGE_SHLIBDEPS OFF) + +# we also set the dependencies of APPLICATION component to empty, and let +# shlibdeps do the job for this component. Otherwise the default will +# override +set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_DEPENDS "") + +# this sets the generated packages source to the desired one, in case +# several packages are generated from a unique source (the case with +# multicomponents packaging). + +set(CPACK_DEBIAN_PACKAGE_SOURCE "test-source") +set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_SOURCE "test-other-source") diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake new file mode 100644 index 000000000..51fa3ad81 --- /dev/null +++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake @@ -0,0 +1,75 @@ +if(NOT CPackComponentsDEB_SOURCE_DIR) + message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set") +endif() + +include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake) + + +# expected results +set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb") +set(expected_count 3) + +set(config_verbose -V) +set(actual_output) +run_cpack(actual_output + CPack_output + CPack_error + EXPECTED_FILE_MASK "${expected_file_mask}" + CONFIG_ARGS ${config_args} + CONFIG_VERBOSE ${config_verbose}) + + +if(NOT actual_output) + message(STATUS "expected_count='${expected_count}'") + message(STATUS "expected_file_mask='${expected_file_mask}'") + message(STATUS "actual_output_files='${actual_output}'") + message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}") +endif() + +list(LENGTH actual_output actual_count) +if(NOT actual_count EQUAL expected_count) + message(STATUS "actual_count='${actual_count}'") + message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})") +endif() + + +# dpkg-deb checks for the summary of the packages +find_program(DPKGDEB_EXECUTABLE dpkg-deb) +if(DPKGDEB_EXECUTABLE) + set(dpkgdeb_output_errors_all "") + foreach(_f IN LISTS actual_output) + + # extracts the metadata from the package + run_dpkgdeb(dpkg_output + FILENAME "${_f}" + ) + + dpkgdeb_return_specific_metaentry(dpkg_package_name + DPKGDEB_OUTPUT "${dpkg_output}" + METAENTRY "Package:") + + dpkgdeb_return_specific_metaentry(dpkg_package_source + DPKGDEB_OUTPUT "${dpkg_output}" + METAENTRY "Source:") + + message(STATUS "package='${_f}', source='${dpkg_package_source}'") + + if(NOT ("${dpkg_package_name}" STREQUAL "mylib-applications")) + if(NOT ("${dpkg_package_source}" STREQUAL "test-source")) + set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}" + "dpkg-deb: ${_f}: Incorrect source for package '${dpkg_package_name}': '${dpkg_package_source}' instead of 'test-source'\n") + endif() + else() + if(NOT ("${dpkg_package_source}" STREQUAL "test-other-source")) + set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}" + "dpkg-deb: ${_f}: Incorrect source for package '${dpkg_package_name}': '${dpkg_package_source}' instead of 'test-other-source'\n") + endif() + endif() + endforeach() + + if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "") + message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}") + endif() +else() + message("dpkg-deb executable not found - skipping dpkg-deb test") +endif()