Upstream-side: ABI version numbers
The X server defines several
ABI version numbers in the
hw/xfree86/common/xf86Module.h
header, through the
SET_ABI_VERSION(maj,min)
macro. In this document, the focus is on
ABI_VIDEODRV_VERSION
and ABI_XINPUT_VERSION
, which are
respectively about video
drivers and input
drivers.
An example of input ABI is 12.1
, 12
being the major
, 1
being
the minor
.
Like in usual shared libraries, the major is bumped when interfaces are broken. There’s no compatibility at all in that case.
The minor gets bumped when interfaces are added. In other words, if a
driver is working with x.y
, it should also work with higher minors:
x.z
; z>y
. The converse is not true, if a driver requires a given
minor (for example because it needs a new feature, like MultiTouch),
it won’t work with lower minors (which didn’t provide the needed
feature). Put another way: we have ascending compatibility with the
minors.
Conclusion: We need to keep track of both major and minor.
Thanks to pkg-config
we can query them:
$ pkg-config --variable=abi_videodrv xorg-server
9.0
$ pkg-config --variable=abi_xinput xorg-server
12.1
Debian-side: Using virtual packages
Server’s build system
When xorg-server
gets built, we use pkg-config
’s output to
determine the current major. Through substitution variables, we add
two virtual packages in the Provides
field of the server (for both
xserver-xorg-core
and xserver-xorg-core-udeb
): xorg-input-abi-$x
and xorg-video-abi-$y
, where $x
and $y
are the major part of the
version queried through pkg-config
variables.
To handle ascending compatibility for minors, we maintain in
debian/serverminver
the minimal version of xserver-xorg-core
which
is needed. When a minor is bumped, we store the server version in that
file. This way, drivers built afterwards will depend on a minimal
version of the driver, the last which saw a minor version bump. In
other words: they will “depend on the server version they were built
against, or a higher/compatible one”.
Both ABI and minimal server version are recorded in two files shipped
in xserver-xorg-dev
, to be used while building drivers:
-
/usr/share/xserver-xorg/xinputdep
-
/usr/share/xserver-xorg/videodrvdep
Example for xinputdep
:
xorg-input-abi-11, xserver-xorg-core (>= 2:1.8.99.904)
To make sure we bump the debian/serverminver
when there’s a minor
ABI change, there’s a abibumpcheck
target (on which clean
depends), which extracts input and video ABI from the upstream header,
and compares them to the previous ones stored in
debian/serverminver
, failing and diffing is something changed.
Driver’s control file
Drivers also use substitution variables in their control file, replaced at build time.
# Input driver:
Depends: ${xinpdriver:Depends}, …
Provides: ${xinpdriver:Provides}
# Video driver:
Depends: ${xviddriver:Depends}, …
Provides: ${xviddriver:Provides}
For now, ${xinpdriver:Provides}
is always replaced with
xorg-driver-input
, and ${xviddriver:Provides}
is always replaced
with xorg-driver-video
. Hopefully provided packages will not change,
but using substitution variables is cheap, and makes it easy to add
tweaks afterwards if needed.
Driver’s build system
To set those variables, we ship a dh_xsf_substvars
script in
xserver-xorg-dev
starting with 2:1.9.4
, to be run before
dh_gencontrol
. It iterates on the packages listed by
dh_listpackages
(very old debhelper
command) and does the
following work:
-
It reads variables from the files mentioned above.
-
If a package name ends with
-udeb
, it replacesxserver-xorg-core
withxserver-xorg-core-udeb
. -
If a package name ends with
-dbg
, it does nothing for this package. Debug packages usually depend strictly on the non-debug packages, which in turn have appropriate dependencies. -
If a package name starts with
xserver-xorg-input-
, it appendsxinpdriver:Depends=…
andxinpdriver:Provides=…
to this package’s substvars file. -
If a package name starts with
xserver-xorg-video-
, it appendsxviddriver:Depends=…
andxviddriver:Provides=…
to this package’s substvars file.
Why such heuristics? The idea is to avoid getting “unused substitution
variable” warning messages while building. And since there’s a clear
xserver-xorg-{input,video}-*
namespace, we can use that to specify
only input-related variables for input drivers, and only video-related
variables for video drivers.
To make it easy to compute substvars when using dh
, a dh
sequence
(xsf.pm
) is shipped. As of 2:1.9.4-1
, it inserts
dh_xsf_substvars
right before the dh_gencontrol
call. Other
repetitive tasks could also be automated this way.
Sample driver packaging
The following assumes:
-
The upstream build system is sane enough, which lets us run
autoreconf
at build time. -
It is a
video
driver. For aninput
driver, replace bothxviddriver
occurrences withxinpdriver
.
Sample debian/control file
Build-Depends:
debhelper (>= 8),
dh-autoreconf,
quilt,
xserver-xorg-dev (>= 2:1.9.4),
Depends:
${shlibs:Depends},
${misc:Depends},
${xviddriver:Depends},
Provides:
${xviddriver:Provides}
Sample debian/rules file
#!/usr/bin/make -f
# Configuration:
#override_dh_auto_configure:
# dh_auto_configure -- --with-FOO --without-BAR
# Install in debian/tmp to retain control through dh_install:
override_dh_auto_install:
dh_auto_install --destdir=debian/tmp
# Kill *.la files, and forget no-one:
override_dh_install:
find debian/tmp -name '*.la' -delete
dh_install --fail-missing
## Debug package:
#override_dh_strip:
# dh_strip --dbg-package=xserver-xorg-video-DRIVER-dbg
# That's a plugin, use appropriate warning level:
override_dh_shlibdeps:
dh_shlibdeps -- --warnings=6
%:
dh $@ --with quilt,autoreconf,xsf --builddirectory=build/
Some comments:
-
dh_auto_configure
: Commented out since there’s usually no specific option to pass when building drivers. Sometimes needed to get a related utility built. -
dh_auto_install
: It behaves differently when operating on a single package (it installs underdebian/PACKAGE
instead ofdebian/tmp
), so make it usedebian/tmp
in all cases. This way,dh_install
has to be used (see below). That also means that a binary package (e.g. a debug package) can be added without changing this part. -
dh_install
: No point in keeping the.la
files. Also, using--fail-missing
makes sure every file installed by upstream is installed in some package, or explicitly ignored. -
dh_strip
: Commented out, there’s only a few drivers shipping a debug package. -
dh_shlibdeps
: The comment really says it all. -
dh
: The order is important! We want patching to happen before autoreconfiguring (bothquilt
andautoreconf
insert commands beforedh_auto_configure
, and afterdh_clean
). Also, we build out-of-tree. Thexsf
sequence is explained in the previous part.
If one needs to build several flavours,
fbdev
’s rules file
can be used as an example.
Handling a transition
When a new major version of the server comes up, it can be updated
following its README.source
. Usually, drivers can be rebuilt using
binNMUs. Be sure xorg-server
is marked as Installed
on all
buildds, or set a dep-wait
.
On the release team side, a transition page can be asked for, to track fully rebuilt drivers. For the input 12→13 and video 10→11 transitions, the settings are:
-
Affected:
.build-depends ~ /xserver-xorg-dev/
-
Good:
.depends ~ /xorg-input-abi-13/ | .depends ~ /xorg-video-abi-11/
-
Bad:
.depends ~ /xorg-input-abi-12/ | .depends ~ /xorg-video-abi-10/
Staying tuned
Staying informed of driver-related changes can be a bit difficult in the following cases:
-
If one maintains a single driver within the X Strike Force, one might not notice the few mails about drivers in the heavy mail flow on
debian-x@
. -
If one maintains a driver outside the X Strike Force, one is probably not subscribed to the mailing list at all.
For those reasons, a mail alias is being set up to gather all maintainers interested in receiving driver-related mails.