Проект на основе CMake с пользовательским плагином QML, загруженным во время выполнения, завершается ошибкой только с MinGW

#qt #plugins #cmake #qml #mingw

#qt #Плагины #cmake #qml #mingw

Вопрос:

Я пытаюсь поэкспериментировать с CMake и Qt 5.15.1, крошечным проектом, включающим фиктивный пользовательский плагин QML, загруженный во время выполнения.

Структура проекта

 |-- 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
  

Я тестировал на Windows с Visual Studio 2019 и MinGW 8.0 gcc 10.2.0, а также на Ubuntu с gcc 9.3.0.

Он строится без ошибок со всеми этими конфигурациями.

Во время выполнения:

  • В Visual Studio и с gcc на Ubuntu приложение запускается без каких-либо проблем и отображает пустое окно.
  • Но с MinGW он завершается сбоем во время выполнения, engine.rootObjects() пуст, и я не могу понять, почему. Чего мне не хватает?

Ответ №1:

Если вы включаете файлы qrc, вам необходимо добавить set(CMAKE_AUTORCC ВКЛ.)

Комментарии:

1. AUTORCC уже включен для целевого объекта, включая файл qrc