← Back to team overview

ubuntu-phone team mailing list archive

Re: Cross-compile with CMake from SDK Apps to Unity8/Mir

 

On 16 December 2013 14:06, Alberto Mardegan
<alberto.mardegan@xxxxxxxxxxxxx> wrote:
> On 12/16/2013 01:56 PM, Dimitri John Ledkov wrote:
>> 1) Simply because qmake encodes and assumes the same "host"
>> configration options as were used when qmake & qmake modules were
>> created. To properly support multiarch, all qmake modules instlalation
>> path will need to transition from non-multiarch, to multiarch
>> locations.
>
> I'm not expert in cross-compilation (in Nokia we were using scratchbox,
> which was settings up everything for the developer), so I didn't
> completely understand what you wrote. I'll try to rephrase with my
> words, to double-check if I got it right:
>
> When qmake is built (alongside with Qt), it's built for a specific build
> host/target pair. In order to support cross-compilation of Qt
> applications, one need to have a qmake binary which was built with the
> proper build target (and of course, with the proper build host). This
> means that if one intends to build his Qt application for more
> architectures, one needs to be able to have several qmake binaries
> installed in parallel, one for each target architecture.
>

Right, that is the upstream way to do it. This is precise what we want
to avoid. We do not want to build 25 copies of Qt nor qmake (native +
crosses to other 4 arches, given that in ubuntu at the moment we have
5 architectures). That is a maximum. In practice one would only choose
to build a "useful" subset e.g. from i386/amd64 to armhf & arm64.
While being extremely flexible & convenient for upstream, this is a
maintenance nightmare for a distribution. And looking at, e.g. Debian,
it blows out of proportion there with ~12 supported architectures in
Debian.

In practice however, all other build-tools can separate out the native
binary from the target configuration files. E.g. cmake:amd64 binary
package ships /usr/bin/cmake (amd64 binary) which can look up modules
from /usr/lib/$(DEB_HOST_MULTIARCH)/cmake/, and fallback to the
generic arch-aware/agnostic modules in /usr/share/cmake/*.

There is no technical limitation, why a qmake binary cannot be adapted
to read all configuration & qmake modules from a configurable location
at runtime, instead of hard-coded one at compile time. Afterall cmake,
autoconf configure scripts, waf and many other build-systems can.
Ideologically / historically that was not the case for qmake but there
are little technical limitation why it should be able to gain such a
feature. It already can read / adapt at runtime based on qt-config
configuration files.

> So, the point 1 you write above is about installing these qmake binaries as
> /usr/lib/$(DEB_HOST_MULTIARCH)/qt5/bin/qmake
>
> Right?
>

Yes and no =) as per multiarch spec, acrh-specific paths are reserved
for that architecture only. So, only amd64 package can ship files in
/usr/lib/x86_64-linux-gnu and only the armhf package can ship files in
/usr/lib/arm-linux-gnueabihf. Thus shipping executable binaries in
those paths is a bit miss-normer, as althought they are co-installable
on other architectures, they will rarely be possible to execute.

>> 2) After that, qmake needs to also learn to dynamically fallback from
>> multi-arch location, to non-multiarch location (in case some modules
>> still ship modules in the older location) as otherwise some
>> configurations will fail. This might prove to be tricky since qmake
>> assumes relative paths by default for everything.
>
> Can't we assume that we'll make sure that all the Qt packages that we
> need for Ubuntu development will be property installed in the multi-arch
> location? Or do I miss some hidden complication here?
>

We can. And that's my opinion as well. But it will make a painful
transition period, were there will be some time when nothing compiles
with qmake. So I thought to start shipping qmake modules in both
locations (current and mulit-arch one), and then once all modules are
available in multi-arch location switch qmake to read from the
multi-arch location to avoid any period of time where qt* packages are
not buildable with qmake.


>> 3) After that, it needs to learn to choose non-matching architecture
>> locations when performing cross-compilation. (e.g. amd64 qmake should
>> be able to look up modules from arm-linux-gnueabihf location and not
>> have a fizzy fit about different modules and options selected, e.g.
>> when doing amd64 -> armhf compilation it should be using armhf
>> defaults and compile GLESv2 instead of demanding GL, and also not make
>> assumptions that e.g. "build" machine is not armhf/missing GLESv2.
>> something based on environment variables / qtconfig should work, or
>> e.g. creating wrapper scripts to provide e.g.
>> "arm-linux-gnueabihf-qmake" which calls normal host qmake, but with
>> right environment / options to make it act correctly for
>> cross-compilation.
>
> I'm a bit lost here. Is this about having well-written mkspecs
> configuration files for each architecture?
> I would expect that if I'm on an amd64 machine and call
> /usr/lib/arm-linux-gnueabihf/qt5/bin/qmake

no. As per above, that qmake is an armhf binary and not amd64 one.
If both amd64 and armhf packages ship that file at that path and it's
the two are not identical, then multiarch assumptions break and dpkg
will prevent from co-installing the two packages from different
architectures. The goal of multi-arch is to reuse without any
modifications binaries/libraries, compiled on one architecture, on
another.

> it should read the right mkspec file for building amd64->armhf and
> therefor link to the proper Qt libraries which were build for working on
> armhf (with GLES)?

yes, but all/any qmake binaries should be able to do that. as in an
amd64 qmake binary should be able to read native, or cross mkspecs
files to compile natively or from native -> cross-arch.

Unlike autoconf, there really is no need to perform canadian cross
compilations, e.g. amd64 qmake reading and setting up armhf -> powerpc
compilation.

> Note that I'm concerned about building applications only; I do
> understand that for building Qt itself things might be more complicated.
>

Same here. While it would be fun to be able to cross-compile qt
packages in the archive, it will be non-trivial and no practical gain
what's-so-ever.


>> I'm looking into the 1) point, to get qt packages co-installable from
>> multiple achitectures, such that one can cross-compile using CMake on
>> the host machine without using chroots.
>
> Right, so if I didn't misunderstand you, this work is about fixing any
> broken mkspec and packaging Qt in Debian with multiarch support?
>

No. This is about moving:
/usr/share/qt5/mkspecs -> /usr/lib/$(DEB_HOST_MULTIARCH)/qt5/mkspecs

in all native packages.

Because, if fact, those files are _not_ the same across all
architectures, and thus are not co-installable.
And then modify qmake to pick the location of "mkspecs" at runtime, as
it needs to pick any of the supported architectures ( a native one, or
a cross one)

> [...]
>> Are you implying there are canonical projects not using CMake yet?
>
> Well, in Online Accounts we are using qmake, and for some parts of the
> stack (shared with Sailfish OS, Tizen and soon KDE) we are using qmake
> or the autotools. I believe that switching to cmake would be welcome by
> at least the KDE front, so I don't think it's impossible to happen.
>
> I'm just personally much happier with qmake, and since Qt developers are
> typically using that or QBS, I think it's worth having a look at
> supporting these build systems as well (of course, it all depends on how
> much effort that means). :-)
>

Sure. Unfortunately, even if it gains a better runtime detection of
mkspecs, it's still of little use for a generic distribution/developer
that does typically use _other_ components that are not Qt based as
well.

CMake is a generic build systems, that can compile anything. We need
something that will support C, C++, QML, Qt, non-Qt, go, gtk/gobject,
java, python.... and qmake will not gain support for all the things
any time soon. CMake is fast, portable and most-importantly
technology-agnostic extensible build-system. I honestly hate _all_
build systems, they all have their own miss features, but between the
two CMake is a better forward looking choice for a diverse
distribution / app-development platform.

I haven't looked into QBS yet. If it has similar cross-compilation
deficiencies, and technological restrictions (great for C++/Qt & QML
and nothing else), then again I'll be still inclined to support CMake
only.

Regards,

Dimitri.


Follow ups

References