I have build an application who loads a self-made .dylib and this .dylib had to call an other .dylib.
I'm on OS X and I use Qt. When I'm in Qt Creator I can Debug/Release and it works. It also works when I click on the .app and all the .dylib used by my application where located in .app/Contents/ Frameworks. My problem is for the deployment. When I run macdeployqt, all works and a .dmg is generated but when I launch this .dmg, an error occurs.
This error is logic because the .dylib called by the main .dylib is not in the folder .app/Contents/ Frameworks. I don't know how to add it if I had it in this folder it's fail. It also logic because the app don't call the second .dylib but the main dylib. don't have an app folder so ...
You have to copy the required libraries into the application bundle before you use the macdeployqt
tool. You can perform the copy from the project file of the application itself, by adding custom targets that the main target depends on. These targets will be the copies of the dylibs, and you'll copy them from somewhere else in the build directory.
Usually, you'd have a top-level subdirs project that builds the libraries and your application, e.g.:
+--- lib-dylib-32920629
+--- lib-dylib-32920629.pro
+--- lib1
| +--- lib1.pro
| +--- lib1.cpp
| \--- lib1.h
\--- main
+--- main.pro
\--- main.cpp
Download this project from: https://github.com/KubaO/stackoverflown/tree/master/questions/lib-dylib-39206929
TEMPLATE = subdirs
SUBDIRS += lib1 main
main.depends += lib1
QT = core
CONFIG += c++11
TEMPLATE = lib
HEADERS += lib1.h
SOURCES += lib1.cpp
#ifndef LIB1_H
#define LIB1_H
#include <QObject>
class Lib1 {
public:
QString text();
};
#endif
#include "lib1.h"
QString Lib1::text() {
return QStringLiteral("Hello from Lib1");
}
A custom deployLib
function can be used to deploy the library into the application bundle:
QT = widgets
CONFIG += c++11
TEMPLATE = app
SOURCES += main.cpp
LIBS += -L../lib1 -llib1
INCLUDEPATH += ..
DEPENDPATH += ..
defineReplace(libVersions) {
# libVersions(1,2,3) - returns .1.2.3. .1.2. .1. .
versions=.$${1}.$${2}.$${3}. .$${1}.$${2}. .$${1}. .
return($$versions)
}
defineReplace(dylibs) {
# dylibs(base,1,2,3) - returns libbase.1.2.3.dylib libbase.1.2.dylib ... libbase.dylib
base = $$1
versions = $$libVersions("$$2","$$3","$$4")
libs =
for (version, versions): libs += lib$${base}$${version}dylib
return($$libs)
}
defineTest(deployLib) {
# deployLib(target,target2path,target2,1,2,3)
# deploys target2path/libtarget2.1.2.3.dylib,... to the target's application bundle
target = $$1
libpath = $$2
libtarget = $$3
libs = $$dylibs($$libtarget,$$4,$$5,$$6)
targetdir = $${target}.app/Contents/MacOS
mktargetdir = "(test -d $$targetdir/ || mkdir -p $$targetdir/)"
for (lib, libs) {
out = $$targetdir/$$lib
$${lib}.target = $$out
$${lib}.commands = $$mktargetdir
$${lib}.commands += "&& $$QMAKE_COPY_FILE $$libpath/$$libtarget/$$lib $$out"
export($${lib}.target)
export($${lib}.commands)
QMAKE_EXTRA_TARGETS += $$lib
PRE_TARGETDEPS += $$out
}
export(QMAKE_EXTRA_TARGETS)
export(PRE_TARGETDEPS)
return(true)
}
macx {
deployLib(main, .., lib1, 1, 0, 0)
}
#include "lib1/lib1.h"
#include <QtWidgets>
int main(int argc, char ** argv) {
QApplication app{argc, argv};
Lib1 lib1;
QLabel label{lib1.text()};
label.setMinimumSize(200, 200);
label.setFont(QFont{"Helvetica", 20});
label.show();
return app.exec();
}