Come up with a way to build packages for different distributions
We are wanting to find a way to have one debian/control file to rule them all, and not have different branches for different distributions for different packages. However, this may be harder than it sounds.
The easiest way to do this is to use alternative packages in the Build-Depends field, and do some if rules in debian/rules, for example:
Build-Depends: dh-python | python-central, [...].
This would make a package work for both earlier Ubuntu releases, and also for Ubuntu Trusty, where python-support and python-central have disappeared and dh_python is what you have to use.
It is important to know that the first dependency that satisfies the dependency solver will get picked, so one way to get around that is to use versioned Build-Depends, for example:
Build-Depends: dh-python (>= <correct_version) | python-central.
This might be all we need to do to deal with things, and although there is a point where having the same control file for a lot of distros just wont work (its not just the Build-Depends where you can run into problems), I would propose that we go down this path until we run into more complicated problems, and then resolve those as they come up with more complicated solutions.
I researched a few scenarios that we might run into, they started getting more complicated quickly, but if we need to Depend on a package that doesn't exist in earlier (or later) releases, and that is by adding something like this:
Depends: base-files (<< <version>) | actual-package
instead of adding the actual package as a dependency. Then we just tweak to match the version in the next release. If we need a package on an older system, but it is not available on a newer one, we can do:
base-files (>= <version>) | actual-package
and use from the release where we don't need the actual-package.
For example, this is how mysql-5.6 was backported for Ubuntu, when it didn't have systemd support:
DPKG_VENDOR ?= $(shell dpkg-vendor --query Vendor | tr [A-Z] [a-z])
DEB_DISTRIBUTION = $(shell dpkg-parsechangelog | sed -ne 's/^Distribution: //p')
ENABLE_SYSTEMD = yes
ifeq (ubuntu,$(DPKG_VENDOR))
ifeq ($(DEB_DISTRIBUTION),$(filter $(DEB_DISTRIBUTION),precise))
$(warning Disabling systemd on $(DPKG_VENDOR) $(DEB_DISTRIBUTION))
ENABLE_SYSTEMD = no
endif
endif
[...]
%:
ifeq (yes,$(ENABLE_SYSTEMD))
dh $@ --parallel --with systemd
else
dh $@ --parallel
endif
and d/control had this:
Build-Depends: [...], dh-systemd (>= 1.5) | base-files (<< 7.2ubuntu5~)
It seems in general, regenerating debian/control is prohibited, although if it is not a purely functional change, then it is tolerated by ftpmasters in Debian (for example various GNOME packages update Uploaders dynamically, and it is allowed). The Debian [reject FAQ->https://ftp-master.debian.org/REJECT-FAQ.html] suggests that changing build-depends from any default target is verbotten:
You have a cdbs package and for whatever reason turned on the play with my debian/control in a bad way option. See #311724 for a long text on that matter.
Small overview: The DEB_AUTO_UPDATE_DEBIAN_CONTROL option turned on modifies Build-Depends, which doesn't affect the build that's running. But it affects all following builds, which can be NMUs, buildd builds and worst case: security builds. You DO NOT want to have such a build getting a different result (except for the small changes intended with the build) just because there is now another thing in the build-depends.
Two solutions for this:
Think about it and set the Build-Depends yourself. That's easy and you can check them in pbuilder.
Do this only in a special target in debian/rules that is NEVER called automagically, so you can check what it does before you start the real build.
Some other possibilities, after discussion with debian developers:
13:58:53 < hmh> smcv: but you can do that in autogen.sh, as long as you don't run that on build.
13:59:42 < ansgar> Generate debian/control.new, fail build if debian/control != debian/control.new with message informing the user to rename control.new to control. Remove control.new in the next step.
13:59:48 < smcv> the kernel generates control in a special target that deliberately fails, like ansgar said
14:02:07 < hmh> smcv: but generating debian/control from autogen.sh, guarded by a test -r debian/control, is not so bad.
14:02:32 < hmh> smcv: so you can still autogen.sh in debian/rules clean, and not touch debian/control.
14:03:58 < smcv> although, a debian/autogen.sh that ends with "exec ./autogen.sh" would be ok there
14:15:53 < bunk> https://sources.debian.net/src/gcc-6/6.3.0-8/debian/control.m4/
14:29:37 < helmut> micah: you run m4 on it with suitable definitions
14:30:16 < micah> helmut: yeah, in the clean stage?
14:30:44 < helmut> micah: no. in an extra target. automatically regenerating d/control is prohibited
14:30:52 < jrtc27> most likely debian/rules debian/control
14:31:11 < helmut> just "control"
14:35:37 < bunk> micah: I don't know the details of the packages, but gcc-6 or openjdk-8 are examples you can use for inspiration.