[Development] moc output from non-local tool build

Thiago Macieira thiago.macieira at intel.com
Mon Sep 13 20:21:37 CEST 2021

On Monday, 13 September 2021 09:13:02 PDT Marius Kittler wrote:
> From my GNU/Linux user/distributor perspective it would be great if the host
> moc could be slightly newer than the target Qt libs. So if the distribution
> upgrades the regular Qt package the cross packages (targeting mingw-w64 and
> Android) would still be usable until they're updated as well. I don't
> expect that there would be a big delay. So it would be sufficient if moc
> would be able to generate files which can still be used with the previous
> release of Qt, so moc from Qt 6.2.0 would be able to generate files for Qt
> 6.1.3 libraries.

I was thinking the opposite: that the moc tool could be slightly older. Qt 
already needs to deal with compiled moc content that hasn't been recompiled, 
so the libraries already have backwards-compatibility in one direction. If 
there was a need to have extra compatibility, I thought extending QtCore 
compatibility with moc content that hasn't been regenerated would be the 
logical next step.

Doing your way is possible, but probably requires that moc output #ifdef 
content. Whereas my change would replace:

static constexpr unsigned char qt_pluginMetaData_QEglFSIntegrationPlugin[] = {
    'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!',
    // metadata version, Qt version, architectural requirements
    0, QT_VERSION_MAJOR, QT_VERSION_MINOR, qPluginArchRequirements(),
[...some content..]
QT_MOC_EXPORT_PLUGIN(QEglFSIntegrationPlugin, QEglFSIntegrationPlugin)

static constexpr unsigned char qt_pluginMetaDataV2_QEglFSIntegrationPlugin[] = 
[... same content ...]
QT_MOC_EXPORT_PLUGIN_V2(QEglFSIntegrationPlugin, QEglFSIntegrationPlugin, 

Your way is easier on the packagers, though, since the cross-compilations are 
usually not critical content, but the host/native Qt is. But I don't think 
it's the typical scenario for cross-compiling. People usually download the 
sources in order to cross-compile Qt with their device's toolchain and they'd 
like to use the system's Qt to help bootstrap. The system's Qt is usually 

> To me it would make sense adding a CLI flag to moc to specify the target
> version and the CMake build scripts would pass it automatically (instead of
> rejecting the newer moc completely like it is currently implemented).

That works too. It's doable for moc to remember how to emit old code, so a 
version switch would help it. By default, it would simply emit "latest".

> Of course all of this effort would be quite fruitless if other tools like
> uic would not support the same as well. Likely those tools are quite
> unproblematic. Maybe only the build system needs to be changed to accept
> newer host versions.

True, but those tools change much less frequently and integrate much less 
tightly than moc.

If we decide to go this route, we should add the version flag right now, even 
if we don't use it. That way, if a new version wants to use it, an older build 
will have passed it.

> Alternatively it would also be interesting to provide a "tools only" build
> to be able to provide host tools of the required version. However, I
> actually like not having to build tools over and over again for every
> target so a "compatible" moc sounds much better to me.

That's technically just a qtbase build. moc is the only tool that needs to 
bootstrap in a host build, all the rest link to QtCore.

Which reminds me we can probably shrink the bootstrap lib to bare bones and 
save on compilation time.

Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel DPG Cloud Engineering

More information about the Development mailing list