Ubuntu – The best way to build a package that targets a single Ubuntu release only


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?

Best Answer

  • 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.