Как развернуть приложение с внешней .dylib, которая вызывает другую .dylib?

Я создал приложение, которое загружает самодельный .dylib, и этот .dylib должен вызывать другой .dylib.

Я на OS X и использую Qt. Когда я нахожусь в Qt Creator, я могу отлаживать/выпускать, и это работает. Это также работает, когда я нажимаю на .app и все .dylib, используемые моим приложением, находятся в .app/Contents/Frameworks. Моя проблема связана с развертыванием. Когда я запускаю macdeployqt, все работает и создается .dmg, но когда я запускаю этот .dmg, возникает ошибка.

Эта ошибка логична, потому что .dylib, вызываемый основным .dylib, не находится в папке .app/Contents/Frameworks. Я не знаю, как добавить его, если он у меня был в этой папке, это не удается. Это также логично, потому что приложение вызывает не вторую .dylib, а основную dylib. у меня нет папки с приложениями...


person Landelin Delcoucq    schedule 29.08.2016    source источник


Ответы (1)


Перед использованием инструмента macdeployqt необходимо скопировать необходимые библиотеки в пакет приложения. Вы можете выполнить копирование из файла проекта самого приложения, добавив пользовательские цели, от которых зависит основная цель. Этими целями будут копии dylib, и вы скопируете их из другого места в каталоге сборки.

Обычно у вас есть проект subdirs верхнего уровня, который создает библиотеки и ваше приложение, например:

+--- lib-dylib-32920629
    +--- lib-dylib-32920629.pro
    +--- lib1
    |   +--- lib1.pro
    |   +--- lib1.cpp
    |   \--- lib1.h
    \--- main
        +--- main.pro
        \--- main.cpp

Загрузите этот проект с: https://github.com/KubaO/stackoverflown/tree/master/questions/lib-dylib-39206929

lib-dylib-39206929.pro

TEMPLATE = subdirs
SUBDIRS += lib1 main
main.depends += lib1

lib1/lib1.pro

QT = core
CONFIG += c++11
TEMPLATE = lib
HEADERS += lib1.h
SOURCES += lib1.cpp

lib1/lib1.h

#ifndef LIB1_H
#define LIB1_H

#include <QObject>

class Lib1 {
public:
    QString text();
};

#endif

lib1/lib1.cpp

#include "lib1.h"

QString Lib1::text() {
    return QStringLiteral("Hello from Lib1");
}

главная/main.pro

Пользовательскую функцию deployLib можно использовать для развертывания библиотеки в комплекте приложений:

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)
}

основной/main.cpp

#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();
}
person Kuba hasn't forgotten Monica    schedule 29.08.2016
comment
И если мой .dylib и мой min находятся в двух отдельных проектах. - person Landelin Delcoucq; 30.08.2016
comment
Как вы видите выше, они находятся в двух отдельных проектах: lib1.pro и main.pro. Просто случается, что у вас есть проект верхнего уровня, чтобы отметить зависимости между ними. Таким образом, если вы измените библиотеку, зависимое приложение будет повторно связано с ней. Вам не обязательно иметь именно такую ​​структуру каталогов, вы также можете иметь проект верхнего уровня на том же уровне, что и другие проекты. Затем вы поместите фиктивные подпапки в проект верхнего уровня и фиктивные .pro файлы, которые include являются реальными проектами. Реальные проекты также должны ссылаться на свои источники через $$PWD. - person Kuba hasn't forgotten Monica; 30.08.2016