[Qbs] Qbs and debian packaging

Wookey wookey at wookware.org
Wed Dec 20 05:54:44 CET 2017


I have a few things to package for Debian which use QBS.

So I've had to work out how to make QBS fit into debian's build
concepts and packaging mechanisms. (e.g separate build and install steps)

That has gone reasonably well (although some queries about best
practice remain), and I have
a) a package in debian (which so far as I can tell is the first one using QBS):
https://tracker.debian.org/pkg/dewalls

b) a wiki page on packaging qbs-using packages for debian-style distros:
https://wiki.debian.org/QBS

Do please tell me what's incorrect on that page (some probably is - I
claim no particular expertise). Or just fix the page.

However there are things I haven't been able to make work, and quite a
few queries about best practice. If QBS becomes widely-used, debian
packaging tools will need to support it, and if we can make that
reasonably painless for both packagers and upstreams, that is
obviously good. I have more packages to do so would like to work out
at least some documentation on that wiki pages with you (upstream).


So the remaining issues are:

1) Properly supporting multiarch paths

2) Honouring dpkg buildflags and DEB_BUILD_OPTIONS

3) Neater way to avoid $HOME usage?

4) Crossbuilding?

It might be nice to have a debian support module in QBS to make stuff
'just work'. But I don't know if this is a good plan. There may be better ways.

So, in detail:

Supporting multiarch
--------------------

Debian puts libraries in /usr/lib/<triplet>, not just /usr/lib, and
not /lib64 /lib /libx32 /libilp32 etc. (You can read all about
multiarch here: https://wiki.debian.org/Multiarch, it's quite a big subject)

QBS does not do this by default when a debian build is detected
(pehaps it could?), nor does it seem to have a 'libdir' concept that
would make this an easy override. (It has an installDir which varies
by type of tagged files AIUI).

The correct triplet is made available to builds in
$DEB_HOST_MULTIARCH, but I have not been able to work out how to read
an env var inside the qbs file (is it possible?). Nor have I been able
to pass a variable in, even though this should work.

I should be able to do this:
Project {
  name: package
  property string debHostMultiarch: ""

Group {
    fileTagsFilter: [ "dynamiclibrary", "dynamiclibrary_symlink" ]
    qbs.installDir: "/usr/lib/" + debHostMultiarch
    qbs.install: true
  }

then call 'qbs install' with something like this:
qbs install --settings-dir /tmp --install-root debian/tmp/ profile:default debHostMultiarch:$(DEB_HOST_MULTIARCH)

but I can't get this to work. Should it? What am I doing wrong? Should
I set it in the profile so it is automatically available?

Currently I have just used the fact that Qt.core.libPath is set to the
right library path, so I can use that, but it's a hack, and only works
for qt-using projects. (i.e. where module qt is loaded)

There is also the issue for upstream to detect that this is a
'debian-style' build and thus should use multiarch paths. There is
provision for detecting the OS, but not the distro. So perhaps it
should be enabled by some kind of flag? cpp.multiarchPaths perhaps?
Although I expect users would prefer it if the build system just DTRT
automagically. (Similarly debian almost never wants rpath set (except
plugins), and does want soVersions and dynamiclibray_symlinks so those
would be good defaults too)


Honouring buildflags
--------------------

Debian has standard buildflags, e.g. for security settings, like
hardening flags, and default optimisation. It also has a mechanism for
enabling debug builds or disabling checks (e.g. for crossbuilding or
when they are slow), or disabling optimisation. See 
https://www.debian.org/doc/debian-policy/#debian-rules-and-deb-build-options

There are various ways to do this in the build process: typically
some env vars are set to be used in the build, but cammands can be run instead:
e.g.: CPPFLAGS:=$(shell dpkg-buildflags --get CPPFLAGS)

https://wiki.debian.org/HardeningWalkthrough gives quite a lot of
examples for different build systems. 

I have not managed to make these work as I don't know if there is a
machanism to use env vars in qbs files. Is there? If not, how should
such info be passed in? Would we need to make equivalent qbs strings/lists?

Also I haven't worked out the 'precedence rules' for QBS. i.e if
cpp.cxxFlags is set in the qbs file, and passed in via a qbs command,
does the latter take precedence? Is there a syntax for += (i.e. add
these options to the existing list) ?

qbs tried to avoid this sticky area of setting flags, because they are
toolchain specific, which makes sense, but we need a way of setting a specific set of things. The current dpkg-buildflags is:
CFLAGS=-g -O2 -fdebug-prefix-map=/home/wookey/packages/cavewhere/dewalls/debian/dewalls-1.0.0=. -fstack-protector-strong -Wformat -Werror=format-security
CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2
CXXFLAGS=-g -O2 -fdebug-prefix-map=/home/wookey/packages/cavewhere/dewalls/debian/dewalls-1.0.0=. -fstack-protector-strong -Wformat -Werror=format-security
FCFLAGS=-g -O2 -fdebug-prefix-map=/home/wookey/packages/cavewhere/dewalls/debian/dewalls-1.0.0=. -fstack-protector-strong
FFLAGS=-g -O2 -fdebug-prefix-map=/home/wookey/packages/cavewhere/dewalls/debian/dewalls-1.0.0=. -fstack-protector-strong
GCJFLAGS=-g -O2 -fdebug-prefix-map=/home/wookey/packages/cavewhere/dewalls/debian/dewalls-1.0.0=. -fstack-protector-strong
LDFLAGS=-Wl,-z,relro
OBJCFLAGS=-g -O2 -fdebug-prefix-map=/home/wookey/packages/cavewhere/dewalls/debian/dewalls-1.0.0=. -fstack-protector-strong -Wformat -Werror=format-security
OBJCXXFLAGS=-g -O2 -fdebug-prefix-map=/home/wookey/packages/cavewhere/dewalls/debian/dewalls-1.0.0=. -fstack-protector-strong -Wformat -Werror=format-security

Does it make sense to add generic qbs names for all those things? What
happens when debian changes to a different set of options? If not, how
do we let qbs set what the package asks for (e.g. via
cpp.cLanguageVersion) whilst also honouring the required debian build
options?

we already have cpp.optimization (grr, US spellings!) and
cpp.debugInformation and the various cpp.cxxFlags etc. but no hardening
options.

So I have no real idea how best to do this. Advice welcome.


Avoiding $HOME use
------------------

Debian buildds do not have $HOME available, because per-user data
should not affect package builds. qbs defaults to storing
settings/profiles in $HOME/.config/QtProject/qbs so that simply
doesn't work. Using the --settings-dir option to make it use another
dir does the trick but is a bit clumsy as it has to be done on every
command. If there was an env var to set which would override this,
that would be rather neater. Is there such a thing? Might you consider
adding it?


Crossbuilding
-------------

Does QBS support this, or is it intended to support this? I've not
tried yet. Setting the right toolchain commands: <triplet>-gcc,
<triplet>-binutils, <triplet>-strip, etc is a good start.


config
------

I do have some other questions about the initial profile setup, but
this mail is long enough already, so lets leave that for now.


Wookey
-- 
Principal hats:  Linaro, Debian, Wookware, ARM
http://wookware.org/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/qbs/attachments/20171220/85114502/attachment.sig>


More information about the Qbs mailing list