Мне трудно развернуть динамические разделяемые библиотеки на iOS.
Чтобы изолировать и раскрыть проблему, у меня есть очень простой проект «HelloWorld»: класс экспорта библиотеки с функцией, возвращающей «Hello World», и программой, использующей класс и отображающей сообщение.
Я использую QtCreator с Qt 5.5.
Я могу генерировать .dylib
файл и ссылка моей программы. Но при развертывании его на iPhone я получаю сообщение об ошибке:
Démarrage des processus distants.
dyld: Library not loaded: libMyLib.1.dylib
Referenced from: /private/var/mobile/Containers/Bundle/Application/D6942CCE-828D-4C10-86DA-F7DA7ADF7449/MyApp.app/MyApp
Reason: image not found
На Android у меня была такая же проблема, и я мог ее исправить, добавив общую библиотеку в файл конечного пакета (apk) вручную, используя ANDROID_EXTRA_LIBS
, Но я не могу найти аналога для iOS.
Вот мои .pro файлы. Полный проект можно скачать Вот. Я сообщил об этом Qt как ошибка, но если бы кто-то мог предложить какой-то обходной путь, это помогло бы!
MyLib.pro:
QT -= core gui
TARGET = MyLib
TEMPLATE = lib
DEFINES += MYLIB_LIBRARY
SOURCES += mylib.cpp
CONFIG += shared
HEADERS += mylib.h\
mylib_global.h
MyApp.pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = MyApp
TEMPLATE = appSOURCES += main.cpp\
dialog.cpp
HEADERS += dialog.h
INCLUDEPATH += ../MyLib
LIBS += ../MyLib/libMyLib.dylib
Я бы хотел, чтобы решение было встроено в QtCreator. Единственное, что нужно изменить, — это один из двух файлов .pro. Возможно с вызовами после сборки к командам MACOS …? Или просто инструкция после сборки в MyApp.pro, чтобы скопировать dylib в нужное место (целевая папка .app) перед развертыванием приложения? Я действительно удивлен, что QtCreator не скрывает это молча ….
Замечания: Этот вопрос предлагает установить DYLD_LIBRARY_PATH
, Но у меня нет подсказок, чтобы сделать это в файле MyApp.pro, и как это поможет при развертывании iOS (так как DYLD_LIBRARY_PATH может установить MAC PATH для lib, а не iPhone PATH для lib …)
1) Убедитесь, что в вашем библиотечном проекте у ваших дилибов есть имя для установки @rpath/mylib.dylib
или такой. Например. добавляя QMAKE_SONAME_PREFIX = @rpath
в вашу библиотеку .pro файл.
(Вы можете проверить, посмотрев на первую строку otool -L /path/to/libmylib.dylib
, Если библиотека является предварительно созданной третьей стороной, измените ее на install_name_tool -id @rpath/libmylib.dylib
)
2) добавить следующее .pro-файл приложения
# link to the lib:
LIBS += -L../mylib -lmylib
# make the app find the libs:
QMAKE_RPATHDIR = @executable_path/Frameworks
# deploy the libs:
mylib.files = $$OUT_PWD/mylib/libmylib.1.dylib
mylib.path = Frameworks
QMAKE_BUNDLE_DATA += mylib
Я придумал обходной путь для этого, на случай, если он кому-нибудь поможет.
Создайте свою библиотеку статически, а не динамически (замените CONFIG += shared
от CONFIG += staticlib
Теперь компилятор сгенерирует *.a
файлы вместо *.dylib
, Вы должны использовать это расширение при компоновке библиотек (замените LIBS += myLib.dylib
от LIBS += myLib.a
)
Если ваша библиотека была связана только с программой, вы сделали
Если ваша библиотека, назовем ее (A), использовалась другой библиотекой (B), то (B) больше не должна с ней связываться (Нет LIB
флаг в B.pro). Только программа верхнего уровня будет связываться со всеми вашими статическими библиотеками.
При таком подходе я мог бы развернуть программу с использованием 15 библиотек на iPhone с помощью QtCreator.