Distributing custom Qt plugins in OSX application bundle
I am building a custom application that has certain pieces of the functionality separated out into Qt plugins. This has been working quite well using QPluginLoader
and qobject_cast
, but up until now, I have been using a hard-coded absolute path (didn't want to complicate things before I had it working!).
I'm getting close to needing to deploy the application to other machines, so I decided to try to package the plugins up into the application bundle (I'm building this primarily for OSX). It took some research, but this is what I've come up with:
MyApp.pro file:
# ...
macx {
plugins.path = Contents/Plugins
plugins.files = ../PluginDir-build-desktop/libMyPlugin.dylib
QMAKE_BUNDLE_DATA += plugins
}
This gives a nice bundle structure that looks something like this:
MyApp.app
|
+- Contents
|
+- MacOS
| |
| +- MyApp
|
+- Plugins
| |
| +- libMyPlugin.dylib
|
... other support files ...
So I add the plugin path to the library search paths:
main.cpp:
// ...
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDir pluginsDir(a.applicationDirPath());
pluginsDir.cdUp();
pluginsDir.cd("Plugins");
a.addLibraryPath(pluginsDir.absolutePath());
// ...
return a.exec();
}
And then try to load the plugin, like so:
// ...
QPluginLoader pluginLoader;
pluginLoader.setFileName("libPhotoshopPlugin.dylib");
IMyPluginInterface* plugin = qobject_cast<IMyPluginInterface*>(pluginLoader.instance());
// ...
Unfortunately, plugin always comes out NULL. But when I do this:
// ...
QPluginLoader pluginLoader;
pluginLoader.setFileName("../Plugins/libPhotoshopPlugin.dylib");
IMyPluginInterface* plugin = qobject_cast<IMyPluginInterface*>(pluginLoader.instance());
// ...
I get the plugin instance just fine and everything works as it should.
Why do I have to specify the path in the filename I pass to the QPluginLoader? Shouldn't it pick that up from the QApplication
library paths? Is there something I'm just doing stupidly wrong? (I'm guessing and hoping this is more likely)
Additional note:
If I change the plugins.path in the MyApp.pro file to Contents/MacOS
, the libMyPlugin.dylib get output next to MyApp and everything works just fine. If this is the way I should be doing it anyway, I will gladly continue doing it.
But the Qt documentation shows the Qt plugins (qtjpeg and similar) being开发者_StackOverflow社区 deployed in the Contents/plugins
directory and a similar method for adding the directory to the QApplication
library path.
I store plugins in application.app/Contents/plugins and use the following code to obtain the plugins directory:
...
#elif defined(Q_OS_MAC)
QDir pluginsDir = QDir(qApp->applicationDirPath());
pluginsDir.cdUp();
pluginsDir.cd("plugins");
#else
...
Now you have the correct path to the plugins dir, and can load the plugin. I also have a file qt.conf in application.app/Contents/Resources with the following contents:
[Paths]
Plugins = plugins
精彩评论