QTP0004 | Qt Qml | Qt 6.11.2
Description: Extra directories with QML files in a QML module need extra qmldir files.

- Qt 6.11
- Qt Qml
- CMake Integration for QML
- CMake Policies for QML
- QTP0004
- Qt 6.11.2 Reference Documentation

QTP0001 ◦ QTP0005

# QTP0004

Extra directories with QML files in a QML module need extra qmldir files.

This policy was introduced in Qt 6.8. It causes the build system to generate an extra qmldir file for each additional directory that contains QML files in a QML module.

Enabling this policy ensures that the implicit import of each of the QML components in your module is the same as the module itself. This means that all the components can see each other without explicitly importing the module.

The `OLD` behavior of this policy is that a qmldir file is only generated for the root directory of a module.

The `NEW` behavior of this policy is that for each directory with QML files in a module a separate qmldir file is generated. Each generated qmldir contains a `prefer` directive that redirects the implicit import to the module's canonical resource location.

## Background

The QML engine always performs an implicit import of the directory a QML file resides in. For files in the module root directory, this implicit import resolves to the module itself, so all sibling components are visible. However, when QML files are placed in subdirectories, the implicit import resolves to that subdirectory instead. Components in the subdirectory then cannot see other components in the same module without adding an explicit `import` statement. This is a frequent source of errors.

With the `NEW` behavior, the build system generates a qmldir file in each subdirectory containing a `prefer` directive pointing to the module's canonical resource location. This makes the implicit import of every QML file in the module equivalent to importing the module itself, so all components can find each other regardless of their directory.

## Example

Consider a module with QML files split across multiple subdirectories:

     qt_add_qml_module(mymodule
         URI MyModule
         QML_FILES
             Main.qml
             controls/MyButton.qml
             views/MyView.qml
     )

A common need is for `views/MyView.qml` to use `MyButton` from the `controls` subdirectory. With the `OLD` behavior this fails silently: `views/MyView.qml` implicitly imports the `views` subdirectory, so `MyButton` is not found unless you add `import MyModule` explicitly.

With the `NEW` behavior, an extra qmldir is generated in both the `controls` and `views` subdirectories. Each redirects the implicit import to the module's canonical resource location, so `views/MyView.qml` can use `MyButton` and any other type in the module without an explicit import.

You can set the policy explicitly in your project before calling `qt_add_qml_module()`:

     qt_policy(SET QTP0004 NEW)

Alternatively, call qt_standard_project_setup() with a `REQUIRES` version of 6.8 or later.

Qt 6.8 issues warnings if you do not explicitly set the policy.

Note: The `OLD` behavior of a policy is deprecated, and may be removed in the future.

See also qt_policy, qt_standard_project_setup(), qt_cmake_policies, and qt_add_qml_module.

QTP0001 ◦ QTP0005