QML cross-platform plugin



  • Hi everyone!

    I'm developing a QML plugin. This plugin must work on desktop, iOS and Android. I have a strange problem with QtCreator when I change target for build from iOS to Desktop and the Desktop to iOS my test application can't find plugin for iOS but all build fine. I don't change any settings for Qt or application which using plugin. Only change target for build and now I can't build iOS application because it's can't find plugin. What I can do to fix this problem. Application pro file looks like:

    TEMPLATE = app
    
    QT += qml quick widgets
    
    SOURCES += main.cpp
    
    RESOURCES += qml.qrc
    
    macx {
        ICON = icon.icns
        QMAKE_INFO_PLIST = Info.plist
    } else:ios {
        QMAKE_INFO_PLIST = Info_ios.plist
    
        assets_catalogs.files = $$files($$PWD/*.xcassets)
        QMAKE_BUNDLE_DATA += assets_catalogs
    
        app_launch_images.files = $$PWD/LaunchScreen.xib $$files($$PWD/*.png)
        QMAKE_BUNDLE_DATA += app_launch_images
    }
    
    # Additional import path used to resolve QML modules in Qt Creator's code model
    QML_IMPORT_PATH =
    
    # Default rules for deployment.
    include(deployment.pri)
    

    Pro file for plugin looks like:

    TEMPLATE = lib
    TARGET = Nestlean
    VERSION = 1.0.0
    
    QT += qml quick network widgets
    CONFIG += qt plugin c++11 crypto objective_c
    
    ios {
        CONFIG += static
    }
    
    
    QMAKE_CXXFLAGS_WARN_ON += -Wno-unknown-pragmas
    
    
    DESTDIR = com/consultica/nestlean
    OBJECTS_DIR = tmp/objects   #— на усмотрение, обычно в папку tmp засовываю автоматически сгенерированные Qt файлы
    MOC_DIR = tmp/mocs          #— аналогично
    
    
    TARGET = $$qtLibraryTarget($$TARGET)
    uri = com.consultica.nestlean
    QMAKE_MOC_OPTIONS += -Muri=com.consultica.nestlean
    
    
    # Input
    SOURCES += \
        nestlean_plugin.cpp \
        nestlean.cpp \
        Helpers/Settings/nestleansettings.cpp \
        Requests/nestleanrequestmanager.cpp \
        Requests/nestleanrequest.cpp \
        Objects/User/nestleanuser.cpp \
        Objects/Application/nestleanapplication.cpp \
        Objects/Build/nestleanbuild.cpp \
        Objects/nestleandevicetestinfo.cpp \
        Objects/User/nestleanpeopleitem.cpp \
        Objects/Report/nestleanreport.cpp \
        Objects/Screen/nestleanscreen.cpp \
        Objects/Crash/nestleancrash.cpp \
        Objects/Crash/nestleancrashevent.cpp \
        Objects/Crash/nestleancrashinfolist.cpp \
        Objects/Crash/nestleancrashanatomy.cpp \
        Objects/Crash/nestleancrashhistory.cpp \
        Objects/Screen/nestleanscreenlist.cpp \
        Objects/nestleanuploadbuildview.cpp
    
    HEADERS += \
        nestlean_plugin.h \
        nestlean.h \
        Helpers/Settings/nestleansettings.h \
        Requests/nestleanrequestmanager.h \
        Requests/nestleanrequest.h \
        Objects/User/nestleanuser.h \
        Objects/Application/nestleanapplication.h \
        Objects/Build/nestleanbuild.h \
        Objects/nestleandevicetestinfo.h \
        Objects/User/nestleanpeopleitem.h \
        Objects/Report/nestleanreport.h \
        Objects/Screen/nestleanscreen.h \
        Objects/Crash/nestleancrash.h \
        Objects/Crash/nestleancrashevent.h \
        Objects/Crash/nestleancrashinfolist.h \
        Objects/Crash/nestleancrashanatomy.h \
        Objects/Crash/nestleancrashhistory.h \
        Objects/Screen/nestleanscreenlist.h \
        Helpers/shavhelpermanager.h \
        Objects/nestleanuploadbuildview.h
    
    ios|android {
        DISTFILES = \
            nestlean.json
    
        !equals(_PRO_FILE_PWD_, $$OUT_PWD) {
            copy_qmldir.target = $$OUT_PWD/$$DESTDIR/qmldir_mobile
            copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir_mobile
            copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\"
    
            sourceQmlTypePath = $$_PRO_FILE_PWD_/nestlean.qmltypes
            targetQmlTypePath = $$OUT_PWD/$$DESTDIR/nestlean.qmltypes
            copy_qmldir.commands += && $(COPY_FILE) \"$$replace(sourceQmlTypePath, /, $$QMAKE_DIR_SEP)\" \"$$replace(targetQmlTypePath, /, $$QMAKE_DIR_SEP)\"
    
            QMAKE_EXTRA_TARGETS += copy_qmldir
            PRE_TARGETDEPS += $$copy_qmldir.target
        }
    
        qmldir.files = qmldir_mobile
    } else {
        DISTFILES = qmldir \
            nestlean.json
    
        !equals(_PRO_FILE_PWD_, $$OUT_PWD) {
            copy_qmldir.target = $$OUT_PWD/$$DESTDIR/qmldir
            copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir
            copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\"
    
            sourceQmlTypePath = $$_PRO_FILE_PWD_/nestlean.qmltypes
            targetQmlTypePath = $$OUT_PWD/$$DESTDIR/nestlean.qmltypes
            copy_qmldir.commands += && $(COPY_FILE) \"$$replace(sourceQmlTypePath, /, $$QMAKE_DIR_SEP)\" \"$$replace(targetQmlTypePath, /, $$QMAKE_DIR_SEP)\"
    
            QMAKE_EXTRA_TARGETS += copy_qmldir
            PRE_TARGETDEPS += $$copy_qmldir.target
        }
    
        qmldir.files = qmldir
    }
    
    
    unix {
        installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /)
        qmldir.path = $$installPath
        target.path = $$installPath
        INSTALLS += target qmldir
    }
    
    macx {
        message("OSX")
        QMAKE_LFLAGS += -F$$PWD
        LIBS += -lz -framework Foundation -framework CoreFoundation
        DEFINES += Q_WS_MAC QT_MAC_USE_COCOA
        RESOURCES += \
            resources.qrc
    } else:ios {
        message("iOS")
        LIBS += -framework Foundation -framework CoreFoundation -framework UIKit
        DEFINES += Q_WS_MAC QT_MAC_USE_COCOA
    
        OBJECTIVE_HEADERS += \
            Helpers/shavhelpermanager.h
    
        OBJECTIVE_SOURCES += \
            Helpers/shavhelpermanager.mm
    
        RESOURCES += \
            mobile/resources_mobile.qrc
    } else:android {
        message("ANDROID")
        RESOURCES += \
            mobile/resources_mobile.qrc
    } else {
        message("OTHER")
        RESOURCES += \
            resources.qrc
    }
    
    DISTFILES += \
        qmldir_mobile
    

    QML file where I use plugin in application looks like

    import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtQuick.Window 2.2
    import QtQuick.Dialogs 1.2
    import com.consultica.nestlean 1.0
    
    
    
    ApplicationWindow {
        id: rootApp
        title: qsTr("Nestlean Client")
        width: nestView.minimalWidth
        minimumWidth: nestView.minimalWidth
        height: nestView.minimalHeight
        minimumHeight: nestView.minimalHeight
        visible: true
        menuBar: (Qt.platform.os !== "ios" && Qt.platform.os !== "android") ? menu : null
    
        MenuBar {
            id: menu
            Menu {
                title: qsTr("&File")
    
                MenuItem {
                    text: qsTr("E&xit")
                    onTriggered: Qt.quit();
                }
            }
        }
    
        NestleanView {
            id: nestView
            anchors {fill: parent}
        }
    }
    

    Thanks for the any help!



  • You have to register the static plugin in the C++ code (for instance in the main method). I cannot remember the exact command but someone posted it here in the forum recently.



  • Thanks for the replay! I'll check this!



  • Be aware that for iOS at least there's a little more verbosity involved with the static plugins than the docs would suggest; see https://bugreports.qt.io/browse/QTBUG-47827

    There's a minimal plugin example (demonstrating the issue above, and the workround) at https://bitbucket.org/timday/qt-example-plugin/


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.