Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Add qml plugins in wasm



  • Hello,

    I build my app for wasm with cmake.

    I obtain this error when I load in browser :
    qrc:/main.qml:21 module "QtQuick" is not installed

    I think what the plugin QtQuick is not in wasm file.
    How include qml plugin in wasm file ?
    Linking of lib*.a ? -> does not work
    In a resource .qrc ?
    With qmldir file and plugin.qmltypes ?



  • Did you compile Qt WebAssembly yourself, or are you using the WebAssembly binary package?



  • Yes, I compile Qt WebAssembly myself.

    I tried add qml plugin (qmldir, plugin.qmltypes, .a) in a directory 'imports' in qrc.
    In main.cpp, i added

    engine.addImportPath("qrc:/imports");
    

    I obtain this error when i load in browser :

    qrc:/main.qml:21 module "QtQuick" plugin "qtquick2plugin" not found
    

    it going :)

    The dockerfile :

    
    # Debian
    FROM debian:latest
    
    RUN apt-get update \
     && apt-get install -y build-essential \
                           default-jre \
                           git-core \
                           nodejs \
                           perl \
                           python \
                           libssl-dev
    
    SHELL ["/bin/bash", "-c"]
    
    # cmake
    RUN cd /root \
     && git clone https://gitlab.kitware.com/cmake/cmake.git cmake \
     && cd /root/cmake \
     && ./bootstrap \
     && make -j `grep -c '^processor' /proc/cpuinfo` \
     && make install
    
    # emsdk
    RUN cd /root \
     && git clone https://github.com/emscripten-core/emsdk.git emsdk \
     && cd /root/emsdk \
     && ./emsdk update-tags \
     && ./emsdk install latest \
     && ./emsdk activate latest \
     && source ./emsdk_env.sh \
     && echo "PATH=$PATH" >> ~/envrc \
     && echo "EMSDK=$EMSDK" >> ~/envrc \
     && echo "EM_CONFIG=$EM_CONFIG" >> ~/envrc \
     && echo "EMSDK_NODE=$EMSDK_NODE" >> ~/envrc \
     && echo "EMSCRIPTEN=$EMSCRIPTEN" >> ~/envrc \
     && cat ~/envrc >> /root/.bashrc
    ENV BASH_ENV ~/envrc
    
    # Qt
    COPY QtWasm/Qt5PluginTarget.cmake.in /root/
    RUN mkdir -p /root/Qt \
     && cd /root/Qt \
     && git clone https://code.qt.io/qt/qt5.git source \
     && cd /root/Qt/source \
     && git checkout 5.14.0 \
     && ./init-repository --module-subset=qtbase,qtdeclarative,qtgraphicaleffects,qtquickcontrols2,qtsvg \
     && ./configure -prefix /root/Qt/5.14.0/wasm_32 \
                    -xplatform wasm-emscripten \
                    -nomake examples \
                    -nomake tests \
                    -opensource \
                    -confirm-license \
     && cp /root/Qt5PluginTarget.cmake.in /root/Qt/source/qtbase/mkspecs/features/data/cmake \
     && make -j `grep -c '^processor' /proc/cpuinfo` \
             module-qtbase \
             module-qtdeclarative \
             module-qtgraphicaleffects \
             module-qtquickcontrols2 \
             module-qtsvg \
     && make install \
     && ls -al /root/Qt/5.14.0/wasm_32
    
    # Set environment
    SHELL ["/bin/bash", "-c"]
    RUN echo "PATH=$PATH:/root/Qt/source/qtbase/bin" >> ~/envrc
    ENV BASH_ENV ~/envrc
    RUN cat ~/envrc >> /root/.bashrc
    
    ENV PATH "$PATH:/root/Qt/source/qtbase/bin"
    
    # Test
    RUN qmake --version
    
    # DynamoCMake
    RUN mkdir -p /root/DynamoCMake
    COPY DynamoCMake/ /root/DynamoCMake/
    
    # Project
    RUN mkdir -p /root/project \
     && mkdir -p /root/project/build
    
    CMD ls -al /root/project \
     && cd /root/project \
     && ln -sf /root/DynamoCMake cmake \
     && cd /root/project/build \
     && rm -rf * \
     && emcmake cmake -DCMAKE_BUILD_TYPE=Release .. \
     && emmake make -j `grep -c '^processor' /proc/cpuinfo`
    

    And the cmake file :

    
    cmake_minimum_required (VERSION 3.11)
    
    project (LiveTests)
    
    # dynamo
    include (cmake/Dynamo.cmake)
    
    # qt
    qt_use(VERSION "latest")
    qt_use_components("Qt5Core" "Qt5Gui" "Qt5Network" "Qt5Qml" "Qt5Quick" "Qt5QuickControls2" "Qt5Widgets")
    
    # LiveTests
    files_manifest_list_by_regexp(resources ".*\\.qml" "qmldir" ".*\\.a" ".*\\.qmltypes")
    qt_build_qrc(qrcFile "LiveTests" "/" "${resources}")
    
    files_manifest_cpp_sources(cppSources)
    
    qt_build_app(
        LiveTests
        "${cppSources}"
        "${qrcFile}"
    )
    
    target_link_libraries(
        LiveTests
        "--bind"
        "-s FORCE_FILESYSTEM=1"
        "-s ASSERTIONS=1"
        "-s TOTAL_MEMORY=1GB"
        "-s ALLOW_MEMORY_GROWTH=1"
        "-s ERROR_ON_UNDEFINED_SYMBOLS=1"
        "-lidbfs.js"
        "-O3"
    )
    
    target_link_libraries(LiveTests Qt5::Core Qt5::Gui Qt5::Qml Qt5::Quick Qt5::QuickControls2 Qt5::Widgets)
    
    target_link_libraries(
        "LiveTests"
        "-lqwasm"
        "-L${QT_PLUGINS_DIR}/platforms"
    )
    
    # copy template files
    copy_files(
        "LiveTests"
        "${QT_PLUGINS_DIR}/platforms"
        "${CMAKE_CURRENT_BINARY_DIR}"
        "qtloader.js" "qtlogo.svg"
    )
    
    # configure index.html
    set(APPNAME "LiveTests")
    
    configure_file(
        "${QT_PLUGINS_DIR}/platforms/wasm_shell.html"
        "${CMAKE_CURRENT_BINARY_DIR}/index.html"
    )
    


  • Finnaly, i import qml plugin by use Q_IMPORT_PLUGIN in main.cpp

    #include <QtPlugin>
    Q_IMPORT_PLUGIN(QtQmlPlugin)
    Q_IMPORT_PLUGIN(QtQuick2Plugin)
    

    However, I have a blank page :(

    I obtain this errors :

    Rules for selecting event targets in HTML5 API are changing: instead of using document.getElementById() that only can refer to elements by their DOM ID, new event target selection mechanism uses the more flexible function document.querySelector() that can look up element names, classes, and complex CSS selectors. Build with -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 to change to the new lookup rules. See https://github.com/emscripten-core/emscripten/pull/7977 for more details.
    
    TypeError: 'name' member of PermissionDescriptor 'clipboard-read' is not a valid value for enumeration PermissionName.
    
    TypeError: 'name' member of PermissionDescriptor 'clipboard-write' is not a valid value for enumeration PermissionName.
    

    Do you have any idea of these mistakes?



  • Success :)

    To remove clipboard error, i disabled clipboard in source code :

    void QWasmClipboard::initClipboardEvents()
    {
        if (!hasClipboardApi)
            return;
    
        /*val permissions = val::global("navigator")["permissions"];
        val readPermissionsMap = val::object();
        readPermissionsMap.set("name", val("clipboard-read"));
        permissions.call<val>("query", readPermissionsMap);
    
        val writePermissionsMap = val::object();
        writePermissionsMap.set("name", val("clipboard-write"));
        permissions.call<val>("query", writePermissionsMap);*/
    
        hasClipboardApi = false;
    }
    

    Clipboard permission is not managed on my firefox (63.0.3 64bit).

    And to the blank page, i used QQuickView with resizeMode at SizeRootObjectToView :

    QQuickView* view = new QQuickView();
    view->setResizeMode(QQuickView::SizeRootObjectToView);
    view->setSource(QUrl(QStringLiteral("qrc:///main.qml")));
    view->show();
    

Log in to reply