Friday, January 22, 2021

Qt 6 WebAssembly

ahhh well now. We all know that in Qt6, qmake was ditched for cmake for the build system of Qt itself, and we are playing catch-up in the WebAssembly platform.


First a little history of the Qt build system.

tmake was a perl script that generates Makefiles. If I recall correctly, it was originally written by Sam Magnuson. (I am sure someone who started in Trolltech before me will correct me if I am wrong). I met Sam when he was working at Trolltech's Brisbane office when I was hired as Qtopia Community Liasion. (Briefly, as he soon moved back to the US, after he sold me some furnature and gave me his cat! Still have the Ikea chair.)

qmake was tmake re-written in c++, which was started around 2000. (OMG - its 21 years old! - so old, it farts dust!)

qmake was added on, hacked up to tackle all kinds of things, which brings us to Qt 6.

cmake: The behemoth.

Knowing next to nothing about cmake made this journey a bit bumpy. Add in all the stuff that Qt implements in cmake and on top of that, the special arguments we use for WebAssembly means I am glad this patch is about finished!

Some things are not yet working, such as using cmake to build Qt WebAssembly applications, luckily qmake for app builds is still there... for now.

First off, until this change gets integrated into the git repo, you can grab it here:

You will need:

  • Emscripten version 2.0.12 (others in the 2.0.x range should also work)
  • Ninja build tool (optional but highly recommended)
  • cmake (3.19 at least, I think)

Host build

One of the differences between Qt5 and Qt6 is that you will need a host build with the same versioning, since Qt WebAssembly is a cross platform build. In the near future, you will be able to install Qt binary release and use that, but for now, you need to build your host Qt yourself (to get the same version as the git repo).

You need a host build of both QtBase and QtDeclarative if you are to use declarative in your Qt WebAssembly apps.

WebAssembly build

On all platforms, you will need to set CMAKE_TOOLCHAIN_FILE and QT_HOST_PATH. Emscripten comes with a convient cmake toolchain file, so set the CMAKE_TOOLCHAIN_FILE to where ever it is installed. QT_HOST_PATH is set to where the Qt 6 host directory is.


Just like with Qt5, you will need the Mingw toolchain installed.

On windows, we can use the mingw toolchain that gets installed with Qt binaries, so make sure mingw32-make is in your PATH. I usually do this after I run emsdk_env.bat to set up the Emscripten toolchain. To configure Qt, I use something like:

cmake -DCMAKE_GENERATOR=Ninja  -DCMAKE_TOOLCHAIN_FILE=H:\development\emsdk\upstream\emscripten\cmake\Modules\Platform\Emscripten.cmake -DFEATURE_developer_build=ON -DFEATURE_headersclean=OFF -DWARNINGS_ARE_ERRORS=OFF -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF -DQT_HOST_PATH=H:\development\platforms\desktop\qtbase H:\development\depot\qt\qt5\qtbase


You will need gcc on Linux and Xcode 10.15 or greater on Mac.

cmake -DFEATURE_developer_build=ON

There are a couple experimental features you can configure Qt for, such as
  • threads:  -DFEATURE_threads=On
I have probably forgotten something important, but this will get someone started that is interested. I have tested this build on Linux, Mac and Windows.


To configure declarative using cmake, it's fairly straight forward. In the qtbase/bin directory is a helper tool:
qt-configure-module ~/depot/qt/qt5/qtdeclarative

Application builds:

For now, you can use qmake in the old fashioned way to configure applications.

See also the Qt WebAssembly wiki: