Qt for WebAssembly: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
Line 37: Line 37:


===== Qt 5.13 Platform notes (next release) =====
===== Qt 5.13 Platform notes (next release) =====
* Recommended emsdk version: 1.38.27
* Supported development host systems: Linux, MacOS, and Windows
* Supported development host systems: Linux, MacOS, and Windows
* Multithreading is now possible, and opt-in by building Qt from source and passing the "-feature-thread" flag to the configure script.   
* Multithreading is now possible, and opt-in by building Qt from source and passing the "-feature-thread" flag to the configure script.   

Revision as of 11:43, 15 February 2019

Qt for WebAssembly makes it possible to build Qt applications as WebAssembly modules in order to target Web browsers.

Qt for WebAssembly is currently in development. A second tech preview release is scheduled for release with Qt 5.12.0.

The main development tracking bug is https://bugreports.qt.io/browse/QTBUG-63917.

Getting the code

The sources can be downloaded from your Qt Account, in the Downloads section. For the latest revision of the code, you can also check it out from our git repositories directly: http://code.qt.io/cgit/qt/qt5.git/

Building Qt

Requirements: Emscripten

  • known-good versions
    • Qt 5.12: 1.38.16
    • Qt 5.13: 1.38.27

Supported host dev platforms: Linux, macOS, Windows Subsystem for Linux (5.13: "Normal" Windows is supported)

./configure -xplatform wasm-emscripten -nomake examples -prefix $PWD/qtbase

make module-qtbase module-qtdeclarative [other modules]

Building and running applications

/path/to/qmake && make

Start a web server (e.g. "python -m SimpleHTTPServer"), open e.g. localhost:8000/appname.html in a web browser. We test on Chrome, Firefox, and Safari (all desktop). Firefox (nightly) currently has the most performant wasm compiler, and is recommended for dev work.

You can also use:

/path/to/emscripten/emrun --browser=firefox appname.html

Note: If you are using Firefox, you can use CTRL+SHIFT+K to open the debug console.

Qt 5.12 Platform notes
  • Recommended emsdk version: 1.38.16
  • Supported development host systems: Linux and MacOS, and Windows Subsystem for Linux.
  • Clipboard support: The application clipboard is currently not integrated with the system clipboard.
  • The Qt for WebAssembly build has multithreading disabled. Enabling it is not possible.
Qt 5.13 Platform notes (next release)
  • Recommended emsdk version: 1.38.27
  • Supported development host systems: Linux, MacOS, and Windows
  • Multithreading is now possible, and opt-in by building Qt from source and passing the "-feature-thread" flag to the configure script.
    • Emscripten pthreads documentation: Emscripten pthread docs.
    • Enable support by building Qt from source and passing the -feature-thread argument to the configure script.
    • Binaries with thread support enabled will not load on browsers that do not support wasm threads.
    • Thread Pool Size
      • Applications should set the expected number of concurrent threads at build time. This can be done by setting QMAKE_WASM_PTHREAD_POOL_SIZE in the .pro file (maps to Emscripten PTHREAD_POOL_SIZE).
      • Applications can exceed PTHREAD_POOL_SIZE, provided they return main thread control to the browser before waiting on the new thread, for example by returning from the event handler that started the new thread. This allows the browser to start another web worker. Immediately waiting for the new thread on the main thread (using QThread::wait() or similar) will deadlock.
      • Qt sets PTHREAD_POOL_SIZE to 4 by default.
    • Heap Memory Size
      • Applications should set the heap memory size at build time, since growing the heap is not supported with pthreads enabled. This can be be done by setting QMAKE_WASM_TOTAL_MEMORY in the .pro file (maps to Emscripten TOTAL_MEMORY).
      • Browsers typically limit the initial WASM memory allocation size to 1GB.
      • Qt sets TOTAL_MEMORY to 1GB by default (for -feature-thread enabled builds)
    • QWaitCondition::wait() with a timeout different than ULONG_MAX does not wait. Will/is possibly fixed in emscripten
    • QThread::idealThreadCount() returns the number of CPU cores available (maps to navigator.hardwareConcurrency).
General Platform notes
  • Supported browsers: We develop and test mainly on desktop systems. Tested browsers include Chrome, Safari, Opera and Firefox. Some mobile testing is done on Android and iOS devices. Safari on iOS currently failing to load Qt applications with an "out of executable memory" error.
  • Supported Qt modules, in "make module-foo" form:
    • module-qtbase module-qtdeclarative module-qtquickcontrols2 module-qtwebsockets module-qtmqtt module-qtsvg module-qtcharts
    • These should build without error; other modules may work but have not been verified.
  • Debugging: Qt debug and logging output is printed on the JavaScript console, which can be accessed via browser "Developer Tools" or similar.
  • Nested event loops are not supported. Applications should not call e.g. QDialog::exec() or create a new QEventLoop object.
  • Qt renders application content to a canvas element, and does not use (other) native DOM elements. This means accessibility (screen readers) are not supported and that text inputs won't trigger virtual keyboards.
  • WebGL is required, even for applications which do not use OpenGL themselves. All relevant browsers support WebGL, but note that some browsers blacklist certain older GPUs. The Qt loader will detect this and display an error message.
  • Child OpenGL windows are not supported. The window compositor (in the Qt for Wasm platform plugin) supports raster windows only.
  • Qt will detect OpenGL support as OpenGL ES. In reality the browser will be providing WebGL. WebGL is based on ES and is very similar, but there are some incompatibilities. See WebGL and OpenGL Differences
  • Applications do not have access to system fonts. Font files must be distributed with the application, for example in Qt resources. Qt for WebAssembly itself embeds one such font.
  • High-DPI and scaling: High-DPI rendering is supported, and so is setting the overall UI visual size using the browser zoom feature. Browser font size (and type) settings have no effect on Qt applications.
  • Network access: The web sandbox limits network access to a subset of what is available for native apps.
    • QNetworkAccessManager http requests to the web page origin server, or to a server which supports CORS.
    • QWebScoket connections to any host.
    • TCP and UDP socked tunneling using over WebSockets using a websockify server [implemented by Emscripten, not tested].
      • Websockify v0.8.0 does not work with QT5.12 because it requires either binary or base64 subprotocols that are not implemented in QtWebSocket class (see createHandShakeRequest() in QWebSocketPrivate, the protocols parameter is always empty).
  • On macOS, there may be artifacts of uninitialized graphics memory on some Qt Quick Controls 2 components, such as checkboxes.
  • Link-time warnings of the form: "cannot represent a NaN literal '0x7fdae4bde910' with custom bit pattern", are expected. Expected footprint (download size): Wasm modules as produced by the compiler can be large, but compress well. {| class="wikitable" |- ! Example  !! gzip !! brotli |- | helloglwindow (QtCore + QtGui) || 2.8M || 2.1M |- | wiggly widget (QtCore + QtGui + QtWidgets) || 4.3M || 3.2M |- | SensorTag (QtCore + QtGui + QtWidgets + QtQuick + QtCharts) || 8.6M || 6.3M |} Compression is typically handled on the web server side, using standard compression features: the server compresses automatically or picks up pre-compressed versions of the files. There's generally no need to have special handling of wasm files.