- Qt 6.9
- Qt Qml
- Port QML modules to CMake
- Qt 6.9.3 Reference Documentation

# Port QML modules to CMake

QML modules have become more powerful and easier to use in Qt 6. The following sections describe how to port QML modules to the qt_add_qml_module CMake API.

See also Modern QML modules on how to modernize a QML module that already uses qt_add_qml_module.

## Identify issues to fix

Use qmllint to support you through the process.

Each QML module defined with qt_add_qml_module has a `_qmllint` CMake target that you can use to identify potential issues or improvements. For a QML module called `MyQmlLibrary` use `MyQmlLibrary_qmllint`, for example. To run qmllint on all QML modules, use `all_qmllint`.

The warning categories of qmllint that hint at QML module issues are:

- [import]
- [unused-imports]
- [unresolved-type]
- [unresolved-alias]
- [missing-enum-entry]
- [missing-property]
- [missing-type]

## Prepare the project for qt_add_qml_module

### Make qt_add_qml_module available in CMake

To make qt_add_qml_module available in CMake, add `Core` and `Qml` to your `find_package` call in the project's top-level `CMakeLists.txt` file:

     find_package(Qt6 REQUIRED COMPONENTS Core Qml)

### Use qt_standard_project_setup

qt_standard_project_setup sets up Qt CMake policies needed for qt_add_qml_module, among other things.

Call qt_standard_project_setup in the project's top-level `CMakeLists.txt` file before any qt_add_qml_module call:

     qt_standard_project_setup(REQUIRES 6.8)

## Use qt_add_qml_module

qt_add_qml_module is the CMake function that takes care of generating QML modules. It automatically generates `qmldir` and `qmltypes` files, and sets up tooling like qmlcachegen or qmllint.

QML modules can be added to both executable and library targets in CMake. QML modules attached to the executable target can't be used or linked by other executables, while QML modules attached to library targets can.

### Add a QML module to your executable target

In this case, the source files of the QML module are treated as part of the executable itself, rather than being compiled into a separate library. This means neither a module nor plugin library for this module is created—–the module is fully integrated into the executable. As a result, the module is tied to that specific program and cannot be reused by other executables or libraries.

To add a QML module to your executable, in your `CMakeLists.txt`:

     # pre-existing:
     qt_add_executable(MyApp main.cpp)

     # add this
     qt_add_qml_module(MyApp
         URI MyAppModule
         QML_FILES
             Main.qml # and possibly more .qml files
     )

The `Main.qml` should start with an upper case letter so that it can be instantiated by `loadFromModule` methods like QQmlApplicationEngine::loadFromModule or QQmlComponent::loadFromModule. Also, the QML module URI should be different from the target name to avoid name clashes in the build folder.

### Add a QML module to your library target

To add a QML module to your library, in your `CMakeLists.txt`:

     qt_add_qml_module(MyQmlLibrary
         URI MyQmlModule
         QML_FILES MyQmlComponent1.qml MyQmlComponent2.qml...
         SOURCES MyCppComponent1.h MyCppComponent1.cpp MyCppComponent2.h MyCppComponent2.cpp...
         RESOURCES MyResource1.png MyResource2.png...
     )

qt_add_qml_module creates a `SHARED` library via qt_add_library if the `MyQmlLibrary` target does not exist yet, like in this example.

Note: Your QML module URI should be different from the target name to avoid name clashes in the build folder.

## Use loadFromModule to load your QML files

Use `loadFromModule` to load your QML file, for example:

     engine.load(QUrl(QStringLiteral("qrc:/MyQmlModule/Main.qml")));
     // becomes
     engine.loadFromModule("MyQmlModule", "Main");

## Remove handwritten qmldir files

qt_add_qml_module automatically generates `qmldir` files. If you have singletons in your `qmldir`, declare them in your `CMakeLists.txt` before the qt_add_qml_module call with:

     set_source_files_properties(MySingleton.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)

Delete the handwritten `qmldir` after that.

## Remove qmltypes files generated by qmlplugindump

qt_add_qml_module auto-generates `qmltypes` files when all your types are using declarative type registration, which removes the need to generate `qmltypes` files by hand using tools like `qmlplugindump`.

To achieve that, remove manual calls to `qmlRegisterType` and its variants. Then, register your types declaratively by using QML_ELEMENT, for example:

     // add this header
     #include <QtQml/qqmlregistrations.h>

     class MyComponent: public QObject {
         Q_OBJECT

         // add this line to register MyComponent as 'MyComponent' in QML.
         QML_ELEMENT
         ....
     };

See Registering C++ Types with the QML Type System on how to handle more complicated registration cases like foreign type registration.

Delete the handwritten `qmltypes` files after that.

## Remove handwritten type registration plugins

qt_add_qml_module can generate a QML module plugin automatically for you. You don't need a handwritten plugin if your plugin's only task is to do type registration. Remove the plugin altogether if switching to declarative type registration did remove all the code from your plugin.

Make sure that you remove the `NO_PLUGIN`, `NO_PLUGIN_OPTIONAL`, `NO_CREATE_PLUGIN_TARGET`, and `NO_GENERATE_PLUGIN_SOURCE` arguments from qt_add_qml_module to allow automatic plugin generation.

## Remove qrc files

qt_add_qml_module automatically generates `qrc` files. To list resources in the `qrc` files, like images or sound files, add them to qt_add_qml_module's `RESOURCES` argument. You can find the Module's resources under `:/qt/qml/MyQmlLibraryModule/`.

## Replace directory imports with QML module imports

Replace directory imports with QML module imports. For example,

     import "content" // contains SomeType.qml
     // becomes
     import MyQmlModule // contains SomeType.qml

     SomeType {
         ...
     }

Note that files inside a QML module automatically import their own QML module. You can remove the self-imports.

See also Changes to Qt QML and Modern QML modules.