Configure Qt project with plugins



  • I'm trying to configure a project with plugins, that is the first time I'm doing that using this structure and I'm full of questions.

    First of all I'm going to dump all the code here, but before hand let me show you how the structure looks like:

    |-- myproject
        |-- myproject.pro
        |-- plugins
        |   |-- plugins.pro
        |   |-- pluginfoo
        |   |   |-- pluginfoo.cpp
        |   |   |-- pluginfoo.hpp
        |   |   |-- pluginfoo.json
        |   |   |-- pluginfoo.pro
        |-- myproject
            |-- myproject.pro
            |-- gui
            |   |-- myprojectwindow.cpp
            |   |-- myprojectwindow.hpp
            |-- src
                |-- main.cpp
                |-- plugininterface.hpp
    

    myproject.pro

    TEMPLATE = subdirs
    SUBDIRS  = myproject \
               plugins
    

    plugins.pro

    TEMPLATE = subdirs
    SUBDIRS  = pluginfoo
    

    pluginfoo.cpp

    #include "pluginfoo.hpp"
    
    PluginFoo::PluginFoo(QObject *parent) : QObject(parent)
    {
    }
    

    pluginfoo.hpp

    #ifndef PLUGINFOO_HPP
    #define PLUGINFOO_HPP
    
    #include <QtPlugin>
    #include "plugininterface.hpp"
    
    class PluginFoo : public QObject, PluginInterface
    {
        Q_OBJECT
        Q_PLUGIN_METADATA(IID PluginInterface_iid FILE "pluginfoo.json")
        Q_INTERFACES(PluginInterface)
    
    public:
        PluginFoo(QObject *parent = 0);
    };
    
    #endif // PLUGINFOO_HPP
    

    pluginfoo.json
    {}

    pluginfoo.pro

    QT          += core gui
    TARGET       = pluginfoo
    TEMPLATE     = lib
    CONFIG      += plugin
    DESTDIR      = ../../bin/plugins
    DEFINES     += QT_DEPRECATED_WARNINGS
    INCLUDEPATH += ../../myproject/src
    SOURCES     += pluginfoo.cpp
    HEADERS     += pluginfoo.hpp
    DISTFILES   += pluginfoo.json
    

    myproject.pro

    QT      += core gui widgets xml network
    TARGET   = myproject
    TEMPLATE = app
    DESTDIR  = ../bin
    DEFINES += QT_DEPRECATED_WARNINGS
    SOURCES += src/main.cpp \
               gui/myprojectwindow.cpp
    HEADERS += gui/myprojectwindow.hpp \
               src/plugininterface.hpp
    

    myprojectwindow.cpp

    #include "myprojectwindow.hpp"
    
    MyProjectWindow::MyProjectWindow(QWidget *parent) : QMainWindow(parent)
    {
    }
    
    MyProjectWindow::~MyProjectWindow()
    {
    
    }
    

    myprojectwindow.hpp

    #ifndef MYPROJECTWINDOW_HPP
    #define MYPROJECTWINDOW_HPP
    
    #include <QMainWindow>
    
    class MyProjectWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MyProjectWindow(QWidget *parent = 0);
        ~MyProjectWindow();
    };
    
    #endif // MYPROJECTWINDOW_HPP
    

    main.cpp

    #include "gui/myprojectwindow.hpp"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication application(argc, argv);
    
        MyProjectWindow window;
        window.show();
    
        return application.exec();
    }
    

    plugininterface.hpp

    #ifndef PLUGININTERFACE_HPP
    #define PLUGININTERFACE_HPP
    
    class PluginInterface
    {
    public:
        virtual ~PluginInterface() {}
    };
    
    #define PluginInterface_iid "PluginInterface/1.0"
    
    Q_DECLARE_INTERFACE(PluginInterface, PluginInterface_iid)
    
    #endif // PLUGININTERFACE_HPP
    

    Now let's go to the questions:

    1. As you can see I'm using absolute paths on DESTDIR and i'm afraid it's not the right way to do it. I was wondering, is there Qt built in variables to help me dump the plugins and the executable in the same folder for build, release and profile version? (I'm also trying to keep this multiplatform).
    2. On the examples I saw the use CONFIG += install_ok on their .pro file. What is it for?
    3. The same question as item 2, but for target.path.
    4. On pluginfoo.pro I'm using INCLUDEPATH += ../../myproject/src but I noticed that I'll have to be repeating this to every plugin I create, I tried to add this to plugins.pro but doesn't work. Is there a way to include only once and for all subdirs?
    5. Q_DECLARE_INTERFACE what is the pattern to use as iid, how to create the namespace (based on what?) and why is this used anyway?
    6. I noticed that the plugins has a json file with it, not one single example makes use of it, what it's used for?

    I think that's all for now, thank you.


  • Moderators

    The echo plugin example guides you through all you need for writing custom plugins.

    @Defohin said in Configure Qt project with plugins:

    As you can see I'm using absolute paths on DESTDIR and i'm afraid it's not the right way to do it. I was wondering, is there Qt built in variables to help me dump the plugins and the executable in the same folder for build, release and profile version? (I'm also trying to keep this multiplatform).

    use $(PWD) qmake variable to create a 'dynamic' absolute path and stay independent.

    On the examples I saw the use CONFIG += install_ok on their .pro file. What is it for?

    Good question, can't tell you either. :)
    But basically you can write anything into the CONFIG variable and reuse it later on to check if it is contained in the CONFIG and execute conditional actions.
    But whats exactly the purpose of install_ok is idk. Maybe some qmake internal trick qmake into an successful install and skip this step maybe?

    The same question as item 2, but for target.path.

    see this

    On pluginfoo.pro I'm using INCLUDEPATH += ../../myproject/src but I noticed that I'll have to be repeating this to every plugin I create, I tried to add this to plugins.pro but doesn't work. Is there a way to include only once and for all subdirs?

    not directly. The common way is to bundle all shared settings in a .pri file and include it in every file you need it. (Again use $(PWD) in the .pri file)

    Q_DECLARE_INTERFACE what is the pattern to use as iid, how to create the namespace (based on what?) and why is this used anyway?

    The IID should be unique. So using reversed uris already gives you high uniqueness, since uris need to be unique by definition. By using Q_DECLARE_INTERFACE you give Qt the chance to cast a QObject instance to it's interface type (e.g. by using qobject_cast). Note here that the interface class is not derived from QObject!

    I noticed that the plugins has a json file with it, not one single example makes use of it, what it's used for?

    The meta data in this file is written in the binary file. Now when using QPluginLoader you could read this data and use it as you need it.
    This can be very usefull if you are implementing a pluginy for your application which provide all the same feature but different functionaliyt (like image plugins with different codecs for example). So you would place all plugins in the same (sub-)directory and load them using the QPluginLoader. Then this meta data may be useful. If you just write a single plugin for your application i would say you barely need it.


  • Qt Champions 2016

    Hi
    Super good answers from @raven-worx :)
    To add to 1+2

    To copy files to runtime folder ( build) i use

    CONFIG(release, debug|release): DESTDIR = $$OUT_PWD/release
    CONFIG(debug, debug|release): DESTDIR = $$OUT_PWD/debug

    install_it.path = $$DESTDIR/data
    install_it.files = $$PWD/copy_to_install_dir/*

    INSTALLS +=
    install_it

    The INSTALLS += seems to be related to adding a custom make step in "Projects" to
    call qmake witjh "install"

    It will then copy these files in a platform independent way.
    So the above code will copy any file in
    "project-folder" + copy_to_install_dir
    to the build folder in a folder called data.
    That was i can use my data files same way as when deployed.



  • Thank you guys, helped me a lot.


Log in to reply
 

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