CMake based project with a custom QML plugin loaded at runtime fails with MinGW only

Viewed 465

I'm trying to experiment, with CMake and Qt 5.15.1, a tiny project including a dummy custom QML plugin loaded at runtime.

Project structure

|-- CMakeLists.txt
|-- main.cpp
|-- main.qml
|-- main.qrc
|-- qmlplugins/
    |-- customqml/
        |-- CMakeLists.txt
        |-- customqml_plugin.cpp
        |-- customqml_plugin.h
        |-- customqml.cpp
        |-- customqml.h
        |-- qmldir

./CMakeLists.txt

cmake_minimum_required(VERSION 3.1)
project(test_qml_plugin LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 11)
set(CXX_STANDARD_REQUIRED ON)

find_package(Qt5 REQUIRED Gui Core Qml Quick)

add_subdirectory(qmlplugins/customqml)

add_executable(${PROJECT_NAME} main.cpp main.qrc)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Quick Qt5::Gui Qt5::Qml Qt5::Core)
add_dependencies(${PROJECT_NAME} customqml)
set_target_properties(${PROJECT_NAME} PROPERTIES AUTORCC ON)

./main.cpp

#include <QCoreApplication>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QUrl>
#include <QDir>

int main(int argc, char **argv) {
  QGuiApplication app(argc, argv);
  QQmlApplicationEngine engine;
  engine.addImportPath(QCoreApplication::applicationDirPath() + QDir::separator() + "qmlplugins");
  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
  if (engine.rootObjects().isEmpty()) return -1;
  return app.exec();
}

./main.qml

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.5

import customqml 1.0

ApplicationWindow {
  id: root
  title: qsTr("test_qml_plugin")
  width: 640
  height: 480
  visible: true

  CustomQml {}
}

./main.qrc

<RCC>
  <qresource prefix="/">
    <file>main.qml</file>
  </qresource>
</RCC>

./qmlplugins/customqml/CMakeLists.txt

set(QMLDIR_SRC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/qmldir)
set(QMLDIR_BIN_PATH ${CMAKE_CURRENT_BINARY_DIR}/qmldir)
add_custom_target(customqml-qmldir DEPENDS ${QMLDIR_SRC_PATH} ${QMLDIR_BIN_PATH})
add_custom_command(
  COMMENT "Moving updated resource-file ${QMLDIR_SRC_PATH}"
  OUTPUT ${QMLDIR_BIN_PATH}
  DEPENDS ${QMLDIR_SRC_PATH}
  COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QMLDIR_SRC_PATH} ${QMLDIR_BIN_PATH}
)

add_library(customqml MODULE customqml_plugin.cpp customqml.cpp)
target_link_libraries(customqml PRIVATE Qt5::Qml Qt5::Core)
add_dependencies(customqml customqml-qmldir)
set_target_properties(customqml PROPERTIES AUTOMOC ON)

./qmlplugins/customqml/customqml_plugin.cpp

#include "customqml_plugin.h"
#include "customqml.h"

#include <qqml.h>

void CustomqmlPlugin::registerTypes(const char *uri) {
  qmlRegisterType<FileIO>(uri, 1, 0, "CustomQml");
}

./qmlplugins/customqml/customqml_plugin.h

#pragma once

#include <QQmlExtensionPlugin>

class CustomqmlPlugin: public QQmlExtensionPlugin {
  Q_OBJECT
  Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)

public:
  void registerTypes(const char *uri) override;
};

./qmlplugins/customqml/customqml.cpp

#include "customqml.h"

CustomQml::CustomQml(QObject *parent): QObject(parent) {}

CustomQml::~CustomQml() {}

./qmlplugins/customqml/customqml.h

#pragma once

#include <QtCore>

class CustomQml: public QObject {
  Q_OBJECT
  Q_DISABLE_COPY(CustomQml)

public:
  CustomQml(QObject *parent = 0);
  ~CustomQml();
};

./qmlplugins/customqml/qmldir

module customqml
plugin customqml

I've tested on Windows with Visual Studio 2019 and MinGW 8.0 gcc 10.2.0, and also on Ubuntu with gcc 9.3.0.

It builds without errors with all these configurations.

At runtime:

  • With Visual Studio and with gcc on Ubuntu, application runs without any issue and displays an empty window.
  • But with MinGW, it fails at runtime, engine.rootObjects() is empty and I can't understand why. What I'm missing?
1 Answers

If you include qrc files you need to add set(CMAKE_AUTORCC ON)

Related