Jelajahi Sumber

CPack/DEB: Add Multi-Arch support

Add support for Multi-Arch in control files of Debian packages.
Valid values: same, foreign, allowed

Fixes: #21445
Robert Schuster 1 tahun lalu
induk
melakukan
55524c48a4

+ 25 - 0
Help/cpack_gen/deb.rst

@@ -654,6 +654,31 @@ List of CPack DEB generator specific variables:
    This value is not interpreted. It is possible to pass an optional
    revision number of the referenced source package as well.
 
+.. variable:: CPACK_DEBIAN_PACKAGE_MULTIARCH
+              CPACK_DEBIAN_<COMPONENT>_PACKAGE_MULTIARCH
+
+ Sets the `Multi-Arch` field of the Debian package.
+ Packages can declare in their control file how they should handle
+ situations, where packages for different architectures are being installed
+ on the same machine.
+
+ :Mandatory: No
+ :Default:
+
+   - An empty string for non-component based installations
+   - :variable:`CPACK_DEBIAN_PACKAGE_MULTIARCH` for component-based
+     installations.
+
+ .. versionadded:: 3.31
+  Per-component :variable:`!CPACK_DEBIAN_<COMPONENT>_PACKAGE_MULTIARCH` variables.
+
+ See https://wiki.debian.org/MultiArch/Hints
+
+ .. note::
+
+   This value is validated. It must be one of the following values:
+   ``same``, ``foreign``, ``allowed``.
+
 Packaging of debug information
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

+ 6 - 0
Help/release/dev/cpack-debian-multiarch.rst

@@ -0,0 +1,6 @@
+cpack-debian-multiarch
+----------------------
+
+* The :cpack_gen:`CPack DEB Generator` gained a
+  :variable:`CPACK_DEBIAN_PACKAGE_MULTIARCH` option
+  to support multi-arch packages.

+ 2 - 1
Modules/Internal/CPack/CPackDeb.cmake

@@ -567,7 +567,7 @@ function(cpack_deb_prepare_package_vars)
   # if per-component variable, overrides the global CPACK_DEBIAN_PACKAGE_${variable_type_}
   # automatic dependency discovery will be performed afterwards.
   if(CPACK_DEB_PACKAGE_COMPONENT)
-    foreach(value_type_ IN ITEMS DEPENDS RECOMMENDS SUGGESTS PREDEPENDS ENHANCES BREAKS CONFLICTS PROVIDES REPLACES SOURCE SECTION PRIORITY NAME)
+    foreach(value_type_ IN ITEMS DEPENDS RECOMMENDS SUGGESTS PREDEPENDS ENHANCES BREAKS CONFLICTS PROVIDES REPLACES MULTIARCH SOURCE SECTION PRIORITY NAME)
       set(_component_var "CPACK_DEBIAN_${_local_component_name}_PACKAGE_${value_type_}")
 
       # if set, overrides the global variable
@@ -862,6 +862,7 @@ 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_MULTIARCH "${CPACK_DEBIAN_PACKAGE_MULTIARCH}" 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

+ 15 - 0
Source/CPack/cmCPackDebGenerator.cxx

@@ -789,6 +789,21 @@ bool cmCPackDebGenerator::createDeb()
   if (cmNonempty(debian_pkg_replaces)) {
     controlValues["Replaces"] = *debian_pkg_replaces;
   }
+  cmValue debian_pkg_multiarch =
+    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MULTIARCH");
+  if (cmNonempty(debian_pkg_multiarch)) {
+    // check for valid values: same, foreign, allowed
+    if (*debian_pkg_multiarch != "same" &&
+        *debian_pkg_multiarch != "foreign" &&
+        *debian_pkg_multiarch != "allowed") {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "Error: invalid value for Multi-Arch: "
+                      << *debian_pkg_multiarch
+                      << ". Valid values are: same, foreign, allowed\n");
+      return false;
+    }
+    controlValues["Multi-Arch"] = *debian_pkg_multiarch;
+  }
 
   const std::string strGenWDIR(this->GetOption("GEN_WDIR"));
   const std::string shlibsfilename = strGenWDIR + "/shlibs";

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -1059,6 +1059,7 @@ set(cpack_tests
   DEB.DEB_DESCRIPTION
   DEB.PROJECT_META
   DEB.COMPONENT_WITH_SPECIAL_CHARS
+  DEB.MULTIARCH
 
   RPM.AUTO_SUFFIXES
   RPM.CUSTOM_BINARY_SPEC_FILE

+ 1 - 0
Tests/RunCMake/CPack/RunCMakeTest.cmake

@@ -73,3 +73,4 @@ run_cpack_test_package_target(PRE_POST_SCRIPTS "ZIP" false "MONOLITHIC;COMPONENT
 run_cpack_test_subtests(DUPLICATE_FILE "success;conflict_file;conflict_symlink" "TGZ" false "COMPONENT;GROUP")
 run_cpack_test(COMPONENT_WITH_SPECIAL_CHARS "RPM.COMPONENT_WITH_SPECIAL_CHARS;DEB.COMPONENT_WITH_SPECIAL_CHARS;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ" false "MONOLITHIC;COMPONENT;GROUP")
 run_cpack_test_package_target(COMPONENT_WITH_SPECIAL_CHARS "RPM.COMPONENT_WITH_SPECIAL_CHARS;DEB.COMPONENT_WITH_SPECIAL_CHARS;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ" false "MONOLITHIC;COMPONENT;GROUP")
+run_cpack_test_subtests(MULTIARCH "same;foreign;allowed;fail" "DEB.MULTIARCH" false "MONOLITHIC;COMPONENT")