title: QtPlugin Cannot Load Library
body: <p>I am using Qt 4.8.3 on Linux with GCC. I am trying to create a modular application with QtPlugin. The application describes some base functionality and then a host of plugins will provide all of the unique functionality. Each plugin uses a factory to provide multiple instances of a class and consists of the factory class and the class to be provided.</p>
  
  <p>At the moment, the application is compiling, but is not executing and I am getting errors such as <code>Cannot load library ~: (~: undefined symbol: _ZTI8Base16staticMetaObjectE)</code>. I am not sure how to fix this error. Removing all mention of Base fixes the problem, but the instances need to be derived from that class, so I don't think that will work.</p>
  
  <p>I've included the structure of the project below with the executable and a single plugin (they are all currently identical and having the same problem).</p>
  
  <p>Thank you very much for your assistance.</p>
  
  <h3>directory structure</h3>
  
  <pre><code>main_project
  +- main_project.pro
  +- app/
  | +- app.pro
  | +- main.cpp
  | +- factoryinterface.h
  | +- base.h
  | +- base.cpp
  |
  +- counter/
    +- counter.pro
    +- counter.h
    +- counterfactory.cpp
    +- counterfactory.h
    +- counter.cpp
  </code></pre>
  
  <h3>main_project.pro</h3>
  
  <pre><code>TEMPLATE = subdirs
  
  SUBDIRS += \
      app \
      counter
  </code></pre>
  
  <h3>app.pro</h3>
  
  <pre><code>QT       += core
  
  QT       -= gui
  
  DESTDIR = ../
  TARGET = app_exec
  CONFIG   += console
  CONFIG   -= app_bundle
  
  TEMPLATE = app
  
  SOURCES += main.cpp \
      base.cpp
  
  HEADERS += \
      base.h \
      factoryinterface.h
  </code></pre>
  
  <h3>factoryinterface.h</h3>
  
  <pre><code>#ifndef FACTORYINTERFACE_H
  #define FACTORYINTERFACE_H
  
  #include &lt;QtPlugin&gt;
  #include "base.h"
  
  class FactoryInterface {
  public:
      virtual ~FactoryInterface() {}
      virtual Base *get() = 0;
      virtual QString name() = 0;
  };
  
  Q_DECLARE_INTERFACE(FactoryInterface,
                      "com.example.FactoryInterface/1.0")
  
  #endif // FACTORYINTERFACE_H
  </code></pre>
  
  <h3>base.h</h3>
  
  <pre><code>#ifndef BASE_H
  #define BASE_H
  
  #include &lt;QObject&gt;
  
  #include &lt;QString&gt;
  #include &lt;QStringList&gt;
  #include &lt;QHash&gt;
  
  class Base : public QObject {
      Q_OBJECT
  public:
      Base(QObject *parent = 0);
      virtual ~Base();
  
      virtual QString name();
  
  signals:
  
  public slots:
  
  protected:
      QString name_;
  };
  
  #endif // BASE_H
  </code></pre>
  
  <h3>base.cpp</h3>
  
  <pre><code>#include "base.h"
  
  Base::Base(QObject *parent) :
      QObject(parent)
  {
  }
  
  Base::~Base()
  {
  }
  
  QString Base::name()
  {
      return name_;
  }
  </code></pre>
  
  <h3>main.cpp</h3>
  
  <pre><code>#include &lt;QtCore/QCoreApplication&gt;
  
  #include &lt;QDir&gt;
  #include &lt;QPluginLoader&gt;
  #include &lt;QDebug&gt;
  #include "factoryinterface.h"
  
  
  int main(int argc, char *argv[])
  {
      QCoreApplication a(argc, argv);
  
      QDir pluginDir(a.applicationDirPath());
      pluginDir.cd("plugins");
      foreach(QString filename, pluginDir.entryList(QDir::Files))
      {
          QPluginLoader loader(pluginDir.absoluteFilePath(filename));
          QObject *plugin = loader.instance();
  
          if (plugin)
          {
              FactoryInterface *i = qobject_cast&lt;FactoryInterface*&gt;(plugin);
  
              if (i)
              {
                  qDebug() &lt;&lt; " :" &lt;&lt; i-&gt;name();
              }
          } else {
              qDebug() &lt;&lt; loader.errorString();
          }
      }
  
      return a.exec();
  }
  </code></pre>
  
  <h3>counter.pro</h3>
  
  <pre><code>QT       -= gui
  CONFIG   += plugin
  
  TARGET = $$qtLibraryTarget(counter)
  TEMPLATE = lib
  
  DEFINES += COUNTER_LIBRARY
  
  SOURCES += counter.cpp \
      counterfactory.cpp
  
  HEADERS += counter.h \
      counterfactory.h
  
  INCLUDEPATH += ../app
  
  DESTDIR = ../plugins
  
  symbian {
      MMP_RULES += EXPORTUNFROZEN
      TARGET.UID3 = 0xE5B38B75
      TARGET.CAPABILITY = 
      TARGET.EPOCALLOWDLLDATA = 1
      addFiles.sources = counter.dll
      addFiles.path = !:/sys/bin
      DEPLOYMENT += addFiles
  }
  
  unix:!symbian {
      maemo5 {
          target.path = /opt/usr/lib
      } else {
          target.path = /usr/lib
      }
      INSTALLS += target
  }
  </code></pre>
  
  <h3>counter.h</h3>
  
  <pre><code>#ifndef COUNTER_H
  #define COUNTER_H
  
  #include &lt;QObject&gt;
  #include "base.h"
  
  class Counter : public Base {
      Q_OBJECT
  public:
      Counter();
  };
  
  #endif // COUNTER_H
  </code></pre>
  
  <h3>counter.cpp</h3>
  
  <pre><code>#include "counter.h"
  
  
  Counter::Counter()
  {
      name_ = "Counter";
  }
  </code></pre>
  
  <h3>counterfactory.h</h3>
  
  <pre><code>#ifndef COUNTER_H
  #define COUNTER_H
  
  #include &lt;QObject&gt;
  #include "factoryinterface.h"
  #include "base.h"
  #include "counter.h"
  
  class CounterFactory : public QObject, public FactoryInterface
  {
      Q_OBJECT
      Q_INTERFACES(FactoryInterface)
  public:
      explicit CounterFactory(QObject *parent = 0);
      Base *get();
      QString name();
  
  signals:
  
  public slots:
  
  };
  
  #endif // COUNTER_H
  </code></pre>
  
  <h3>counterfactory.cpp</h3>
  
  <pre><code>#include "counterfactory.h"
  
  
  CounterFactory::CounterFactory(QObject *parent) :
      QObject(parent)
  {
  }
  
  Base *CounterFactory::get()
  {
      return new Counter;
  }
  
  QString CounterFactory::name()
  {
      return "Counter";
  }
  
  Q_EXPORT_PLUGIN2(counter, CounterFactory)
  </code></pre>
  
  <p><strong>Edit:</strong> Updated error message after compiling in Debug mode.</p>
  
  <p><strong>Edit:</strong> I tried exporting/importing the BaseNode class, but this did not work either. I'm not sure if it is entirely incorrect or if I am doing it incorrectly. The following change was made to the Base class (BASE_LIBRARY was added to DEFINES in the app.pro file):</p>
  
  <pre><code>#include &lt;QtCore/qglobal.h&gt;
  
  #if defined(BASE_LIBRARY)
  #  define BASESHARED_EXPORT Q_DECL_EXPORT
  #else
  #  define BASESHARED_EXPORT Q_DECL_IMPORT
  #endif
  
  class BASESHARED_EXPORT Base : public QObject {
  </code></pre>