Building Qt Quick Ultralite application as a static library

This topic provides an instructions to build a Qt Quick Ultralite application as a static library and integrate it with an external project.

Building as a library

Qt Quick Ultralite lets you build an Qt Quick Ultralite application as a static library by using the qul_add_target CMake function. This function builds an executable target by default, unless the STATIC_LIBRARY option is added to the arguments list. See the following example:


Note: The static library setup cannot be compiled for Qt Quick Ultralite FreeRTOS platform configurations, but it can be built for a baremetal configuration and used with an external FreeRTOS setup. Although this approach works, it is not recommended as it may lead to unexpected behaviors.

If app_target_default_entrypoint is set up in the CMake project file, the qul_run.h header file is generated and copied to the libraries output directory. The header contains the qul_run() function with C-Linkage, which offers a standard entrypoint to the Qt Quick Ultralite application.

app_target_default_entrypoint(<target> QML_PROJECT <item>)

Where, target is the target created by the qul_add_target CMake function and item is the name of QmlProject file, which will contain the Qt Quick Ultralite application's configuration.

C-Linkage functions

To allow for more control over the initialization steps and scheduling of the Qt Quick Ultralite engine, the following C-Linkage functions are exposed when building an application as a static library:

  • void qul_init_hardware(void);
  • void qul_init_platform(void);
  • void qul_init_application(void);
  • QulErrorHandler *qul_set_error_handler(QulErrorHandler *handler);
  • const char *qul_error_code_to_string(enum QulError code);
  • uint64_t qul_update_engine(void);
  • void qul_app_exec(void);

The generated qul_run.cpp file will end up looking like this:

extern "C" {

Qul::Application& _qul_app() {
    static Qul::Application _qul_app;
    return _qul_app;

mainScreen& _qul_item() {
    static struct ::mainScreen _qul_item;
    return _qul_item;

void qul_init_hardware(void)

void qul_init_platform(void)

void qul_init_application(void)


uint64_t qul_update_engine(void)
    return _qul_app().update();

void qul_app_exec(void)

} // extern "C"

int qul_run(bool initializeHardware)
    if (initializeHardware) qul_init_hardware();
    return 0;

Integrating the static library with an external project

To integrate the Qt Quick Ultralite application library with an external project, link the external project against it, along with all the used Qt Quick Ultralite libraries. Some of the library versions vary depending on the Qt Quick Ultralite configuration. The following table summarizes these library versions and their corresponding Qt Quick Ultralite configuration:

Font Engine
MCU.Config.fontEngine == Static (default)MCU.Config.fontEngine == Spark
Qul::MonotypeUnicodeEngineShaperDisabledCMake property/variable1, ON, or True0, OFF, or False





PNG decoder (library needed only when using PNG files)
CMake property/variable1, ON, or True0, OFF, or False
ImageFiles.MCU.resourceCompressionQul::PNGDecoderLodePNGQul::PNGDecoderNull (default)

In addition, copy or add the Qt Quick Ultralite include path to the external project's include path. if the Qt Quick Ultralite application provides a default entrypoint, copy or add the generated qul_run.h header file path to the external project's include path.

Next, reuse the existing Qt Quick Ultralite platform abstraction code in external project, or create a new one for your target board. See Qt Quick Ultralite Platform Porting Guide for more information.

Finally, create an entrypoint function in the external project based on the Running Qt Quick Ultralite in applications guide. When default entrypoint is used, include the qul_run.h header file and call the qul_run() function at the desired location to initialize and start the Qt Quick Ultralite engine.

Note: Qul::initHardware() won't get called if qul_run() is called with initializeHardware set to false.

After calling the qul_run() function, the control jumps to Qul::Platform::exec(), which is specific to each platform abstraction. All implementations of this function for the platform abstraction examples delivered with Qt for MCUs contain an infinite while loop. This means that the rest of the non-UI code must either be moved to the corresponding Qul::Platform::exec() implementation or it must be interrupt-based.

If external project is using RTOS, Qt Quick Ultralite could be run in separate thread. In such a case user need to provide a thread-safe interface with Qt Quick Ultralite, as the embedded event system cannot be updated directly from other threads.

See also MCU.Config.fontEngine.

Available under certain Qt licenses.
Find out more.