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

Deploy 32 and 64 bit plugins in the same QML directory?



  • Hi everyone, I just got a question:
    Can Qt load 32 or 64 bit plug-in automatically depending on current environment when importing via QML script?
    e.g. Just like what Qt now can do to auto load release(xxxplugin.DLL) or debug(xxxplugind.DLL) build plug-in when importing.

    I think I could add extra import paths for those plug-ins of different platforms, but this work around might be not very "portable" under some circumstances.

    So I just wonder is Qt already have this ability or does anyone have a better solution?

    Thank you for any help.


  • Moderators

    @GPBeta
    There is no specific naming scheme like you mentioned for release and debug libs.
    So you would have to name them like specified in teh qmldir file. And thus 32- and 64bit libs would be named the same



  • @raven-worx Really? But I believe that Qt does already have the ability to load the different QML plugin depending on the debug or release build.

    I had a look at the msvc2015_64/qml/QtQuick.2 folder which is shipped with any pre-build packages for Windows, there're both qtquick2plugin.dll and qtquick2plugind.dll inside the folder, but the qmldir file only refer to a plug-in named qtquick2plugin.

    So I think it would be great if Qt will have such ability:

    • For 32 bit
      • Release Build: Try to load fooplugin32.dll, then fooplugin.dll
      • Debug Build: Try to load fooplugin32d.dll, then fooplugind.dll
    • For 64 bit
      • Release Build: Try to load fooplugin64.dll, then fooplugin.dll
      • Debug Build: Try to load fooplugin64d.dll, then fooplugind.dll

    And I think this feature could be useful when deploying 3rd-party QML modules.


  • Moderators

    Hi @GPBeta, Qt does not have the ability to choose the bitness of a DLL.

    Can you describe a use-case where you'd need such a feature? I cannot think of a good reason to deploy both 32-bit and 64-bit binaries at the same time. Normally, people just choose one or the other.


  • Moderators

    @GPBeta said in Deploy 32 and 64 bit plugins in the same QML directory?:

    @raven-worx Really? But I believe that Qt does already have the ability to load the different QML plugin depending on the debug or release build.

    yes as i said, for release/debug it is possible as you stated.
    But the 32- and 64bit binaries are in separate QML paths.



  • @JKSH said in Deploy 32 and 64 bit plugins in the same QML directory?:

    Hi @GPBeta, Qt does not have the ability to choose the bitness of a DLL.

    Can you describe a use-case where you'd need such a feature? I cannot think of a good reason to deploy both 32-bit and 64-bit binaries at the same time. Normally, people just choose one or the other.

    Hi, here's my story:

    We're developing a plug-ins/packages based application which supports both 32 and 64 bit Windows, and the installer deploys 32 or 64 bit binaries depending on the device's OS.

    Since QML scripts are completely platform-independent, I think that's a very good choice to use QML scripts in our project.

    Things go well until I realize that some of the QML scripts need to import some other native plug-ins. This is completely not a problem if the plug-ins are deployed by the installer, we can store that plug-ins in a central import path.

    Now the problem is that our application supports 3rd-party packages which may contains native QML plug-ins.

    3rd-party package developers might be able to release separated 32 and 64 bit packages for end users to download, however, some of the user may be confused what platform their devices are running on. What's worse, trying to install bit-incompatible packages may lead to some unexpected behaviors.

    A better idea is to release only one package for all platforms, the application has the responsibility to choose which native plug-in to load. This goal could be easy to achieve with script-only packages and maximize the reuse of QML scripts as well as other resources, but packages containing native plug-ins break this dream.


  • Moderators

    @GPBeta said in Deploy 32 and 64 bit plugins in the same QML directory?:

    Since QML scripts are completely platform-independent, I think that's a very good choice to use QML scripts in our project.

    QML scripts yes. But we are talking about binaries/plugins.

    Now the problem is that our application supports 3rd-party packages which may contains native QML plug-ins.

    In your code you can put your custom plugins in a separate QML import path (wherever you want). In this path only your 64bit binaries are deplyoed.
    Then you can use the platform macros (e.g. like Q_OS_WIN64 - what ever platform you developing on) and add an QML import path pointing to your 64bit QML path. See this for adding an import path.



  • @raven-worx Yes, this work around is just what I said at the beginning.
    It's not very nice because 3rd-party packages that contains plugins have to create at least 3 paths(qmldir) for importing: one for QML scripts, one for 32 bit environment and one for 64 bit.

    And this solution also make private "directory" import very difficult:

    // we might need to dynamic generate this import statement
    import "path/to/module-with-32-or-64-bit-plugin"
    

  • Moderators

    @GPBeta
    i still dont get it.
    Why would you deploy 32 and 64bit at the same time?!
    Your system uses either one or the other anyways



  • @raven-worx Yes, it is.
    But the problem is the end user may download and install some 3rd-party packages.
    Some of the packages contains native plugins, so the 3rd-party publishers need to supply both 32 and 64 bit packages.
    But some of the users don't know weather the device is running 32 or 64 bit OS.


  • Moderators

    @GPBeta said in Deploy 32 and 64 bit plugins in the same QML directory?:

    the installer deploys 32 or 64 bit binaries depending on the device's OS.

    That's good.

    Things go well until I realize that some of the QML scripts need to import some other native plug-ins. This is completely not a problem if the plug-ins are deployed by the installer, we can store that plug-ins in a central import path.

    OK.

    Now the problem is that our application supports 3rd-party packages which may contains native QML plug-ins.

    3rd-party package developers might be able to release separated 32 and 64 bit packages for end users to download, however, some of the user may be confused what platform their devices are running on. What's worse, trying to install bit-incompatible packages may lead to some unexpected behaviors.

    Could the 3rd-party plugin installer also auto-detect the user's bitness, just like the application installer?

    Alternative question: Does your application (and its plugins) benefit from having a 64-bit version? A 64-bit OS can run 32-bit apps.



  • @JKSH said in Deploy 32 and 64 bit plugins in the same QML directory?:

    Could the 3rd-party plugin installer also auto-detect the user's bitness, just like the application installer?

    Since our application is package based, we want to make packages more portable and easily to manage (something like Node.js or npm), everything inside a package are stored in a single folder, no further deployment/configuration are required.

    Alternative question: Does your application (and its plugins) benefit from having a 64-bit version? A 64-bit OS can run 32-bit apps.

    Our application has some features which need to access external 32 or 64 bit processes and there're also some API restrictions, so that dropping 32 bit build or 64 bit build are not considered currently.

    Since I have confirmed that Qt does not have such ability currently, I think this question could be marked as resolved.
    I'm not sure whether this use case will be popular or not in the future, but thank you very much for the suggestions from all the moderators in this forum.



  • UPDATE:
    Maybe using QQmlAbstractUrlInterceptor is a good idea to automatically import platform specified component which does not require to modify the Qt source. For example:

    class QmlImportUrlInterceptor : public QQmlAbstractUrlInterceptor {
    public:
    
        virtual QUrl intercept(const QUrl &url, DataType type) override
        {
            if (type != UrlString && !url.isEmpty() && url.isValid()) {
                QString str = url.toString(QUrl::None);
    #if defined(Q_OS_WIN64)
                return str.replace(QStringLiteral("$(PLATFORM)"), QStringLiteral("win64"));
    #else
                return str.replace(QStringLiteral("$(PLATFORM)"), QStringLiteral("win32"));
    #endif // WIN64 || _WIN64
            }
    
            return url;
        }
    
    };
    

    Usage in qml files:

    import "$(PLATFORM)_impl" as Impl
    
    Impl.NativeComponent {
    }
    

    However, there's a bug with QQmlImport, so that intercepting qml local file will never work :( see QTBUG-73843


Log in to reply