At the moment I build and package our software for Ubuntu 14.04 aka 'trusty' via dpkg-buildpackage. I get a .deb package that can be installed on Ubuntu 14.04 but also on other Ubuntu releases e.g. 12.04 aka 'precise'. This is dangerous as the software can be installed without error message but the program is unable to run/work correctly.

Dependencies of my package are given in the control file. However this file does not let me enter a distribution/codename of Ubuntu. The distribution may be entered as part of the *.changes but this is not reflected anywhere in the .deb file. Checking the complex dependency situation during the post-install script is complex too. Thus I want an easy way to prevent an installation of an Ubuntu package on the wrong Ubuntu release.

What is the best way to build a package that targets a single Ubuntu release only? In the best case (1) the installation should only work on the targeted Ubuntu release and (2) the .deb package contains the distribution name*, e.g. like package_1.0.0-3_trusty_amd64.deb.

(*) Otherwise the apt repository managed via repreprocannot have two packages with the same version number, each targeting a different Ubuntur release.

Thanks in advance.


The debian/control file of my package:

Source: mypackage
Priority: extra
Build-Depends: debhelper (>= 9), python (>=2.7), pyside-tools
X-Python-Version: >= 2.7
Standards-Version: 3.9.2

Package: mypackage
Architecture: amd64
Depends: ros-indigo-desktop-full|ros-hydro-desktop-full, ros-indigo-rqt|ros-hydro-rqt, ros-indigo-gps-umd|ros-hydro-gps-umd, ros-indigo-map-server|ros-hydro-map-server, imagemagick, octave (>= 3.6), libdc1394-22, sox, tree, python (>=2.7), python-psutil, python-usb, python-serial, python-gi, gir1.2-gexiv2-0.10|gir1.2-gexiv2-0.4, exfat-fuse|fuse-exfat, exfat-utils, gphotofs, python-pyproj, libusb-1.0-0 (>=2:1.0.17), libpyside1.2|libpyside1.1 (>=1.1.2), ${shlibs:Depends}, ${misc:Depends}
Description: ...

As one can see this control file was adapted such that we can run the build on multiple Ubuntu releases where the dependencies have different version numbers: libpyside1.2|libpyside1.1 (>=1.1.2). Is there a better way to handle this?

  • I added the content of the control file. Is there a better way to handle builds for multiple Ubuntu releases? – Stefan Jul 14 '14 at 8:31
  • 1
    If you want to have a single debian folder for all releases, then that would be the only way (unless you have a script that changes the dependencies for each particular version). Alternatively, you can have a debian folder (or, for this case, a debian/control file) for each separate version. – saiarcot895 Jul 14 '14 at 12:13
  • I get it. However, how can I start the build chain with different debian/directories or different control files? I have not found a command line option that allows dpkg-buildpackge to use a different directory. – Stefan Jul 14 '14 at 15:24
  • Because, your package is installed in release/environment that it will not able to work in, That means your packages control dependencies missing something.

    What I expect that you haven't put dependencies version conditions, which could used to let package to be installed on single release if the dependency version available only in that release, example gedit: gedit-common (>= 3.10), gedit-common (<< 3.11)

    Depends: libatk1.0-0 (>= 1.12.4), libc6 (>= 2.14), libcairo2 (>= 1.2.4), libenchant1c2a (>= 1.6.0), libgdk-pixbuf2.0-0 (>= 2.22.0), libgirepository-1.0-1 (>= 0.9.3), libglib2.0-0 (>= 2.38), libgtk-3-0 (>= 3.10), libgtksourceview-3.0-1 (>= 3.10.0), libpango-1.0-0 (>= 1.14.0), libpeas-1.0-0 (>= 1.1.0), libx11-6, libxml2 (>= 2.7.4), libzeitgeist-2.0-0 (>= 0.9.9), gedit-common (>= 3.10), gedit-common (<< 3.11), gsettings-desktop-schemas, python3-gi (>= 3.0), python-gi-cairo (>= 3.0), gir1.2-peas-1.0, iso-codes
    Recommends: gir1.2-gtksource-3.0, zenity, yelp
    Suggests: gedit-plugins
    Breaks: gedit-plugins (<< 2.91)

    Reference: Debian Policy Manual: Chapter 7 - Declaring relationships between packages

  • Another way using preinst script and lsb_release command:

    set -e 
    release=$(lsb_release -cs)
    if [ ! "$release" = "trusty" ]
        echo "This packages wasn't build for your release."
        echo "Package wasn't installed, See ..."
        exit 1
    exit 0

    If you want trusty to be defined while build you can make a template as preinst.in and write a makefile to do variable substitution while building source.

  • 1
    Thanks, I already thought of that but I don't really like that approach because you never know which package won't change the minor version number within an Ubuntu release. Do you know such package? Alternatively, I would be good if there is a package explicitly identifying the Ubuntu release such as ubuntu-trusty_.....deb. – Stefan Jul 14 '14 at 8:34
  • @Stefan, updated answer – user.dz Jul 15 '14 at 20:17

Within a Debian package, there's no way to say "Allow installations on 14.04 only". That has to happen at the apt repository level (which I'll get to shortly later). The semi-exception to this is that because Trusty is newer than Precise, Trusty will have some library packages renamed (which, as long as the user's not using a PPA that provides these packages, will make them uninstallable) and will have newer versions of libraries, for which dh-shlibdeps may add a version requirement. Therefore, in both of these cases, the package will be uninstallable in Precise. Note that a package built for Precise might be able to be installed in Trusty.

As for the apt repository, packages do have a separate debian version number for each release. The format you describe could work, although using ~ is more common, partly because ~ is less than all other characters, and so if the user upgrades to a newer release (e.g. from Precise to Trusty), and the package is present in the official repos (with a version number of 1.0.0-3, then the user will upgrade from 1.0.0-3~precise1 to 1.0.0-3, even if you have a 1.0.0-3~trusty1. This won't apply if you use any other character. I personally use something like 1.0.0-0ubuntu1~ppa1~precise1; the ~ppa1 part is to make it less than any official Ubuntu package that might come in the future, and the ~precise1 part is to specify the release. Other PPA maintainers may use 1.0.0-3~12.04.1 or 1.0.0-3~14.04.1, specifying the version number instead of the codename, which is guaranteed to be increasing (as long as Ubuntu version numbers don't reset).

Note that the binary packages have the same source package, so you would need to make sure your .changes file does not include the source package.

  • Thanks for your answer. Relying on certain version numbers of a certain Ubuntu release seems a bit hacky to me. - Do you know how can I control the package file name. Because dpkg-buildpackage automatically chooses the name based on the control file but I was unable to add the distro name. – Stefan Jul 14 '14 at 8:46
  • The package file names depend on the debian/control file and the debian/changelog file. The file naming convention is binaryPackageName_binaryVersion.deb. The binaryVersion part is the full version number at the top of debian/changelog. Therefore, if you have the distro name there (as part of the version itself), it should appear in the final package name. – saiarcot895 Jul 14 '14 at 11:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.