Ошибка выполнения приложения Qt на iOS, созданного с помощью CMake

StackOverflow https://stackoverflow.com//questions/25042916

  •  21-12-2019
  •  | 
  •  

Вопрос

Привет, stackoverflowers :)

Если я создам образец проекта Qt/qmake (в моем случае "аналоговые часы" пример) и разверните его на устройстве под управлением iOS 7.1, все пройдет гладко:приложение безупречно работает на устройстве.Вводная часть — ребята из digia проделали огромную работу по интеграции набора инструментов ios в рабочий процесс Qt.

Однако если я переведу проект qmake в проект CMake, все пойдет уже не так гладко.Я приложил пример аналоговых часов из выпуска Qt-5.3.1 (см. ниже), куда я добавил CMakeLists.txt и скрипт, который запускает CMake для создания проекта XCode для iOS.Проект компилируется и даже связывается (мне пришлось добавить несколько дополнительных библиотек ссылок, см. исходный файл CMake).Ура.

Но вот ловушка:Приложение аварийно завершает работу во время выполнения со следующим сообщением об ошибке:

Ошибка:Не удалось загрузить плагин платформы «ios».

В качестве комментария в этот В теме говорится, что необходимо «принудительно загрузить» libqios через настройки проекта.Это не сильно улучшило ситуацию, а только изменило сообщение об ошибке на:

Ошибка:Вы создаете QApplication перед вызовом UIApplicationMain.Если вы пишете нативное приложение для iOS и хотите использовать QT только для частей приложения, хорошее место для создания QAPPLICATION - это из -за «ApplicationDidfinishLaUnking» внутри вашего делегата UIAPLICATION.

У меня есть два вопроса:

  • Есть ли у кого-нибудь идеи, в чем проблема с ошибками времени выполнения?Я знаю, что qmake (и соответствующие спецификации ios mkspecs) творят чудеса.Но как перевести это в CMake?
  • Почему мне приходится вручную связывать несколько библиотек (harfbuzzng, qios, libpng и несколько платформ iOS) с моей целью?Разве find_package(Qt5 ...) не должен выполнить эту работу за меня?

Здесь — это ссылка на zip-файл, содержащий мой проект Qt-CMake.Версия Qt, которую я использую, — Qt-5.3.1 для iOS.

Редактировать:Я обнаружил, что образец qmake не работает таким образом, если вырвать его из структуры папок примеров Qt.Посмотрите непосредственно на пример Qt:путь/к/Qt/examples/widgets/widgets/analoglocks.

Это было полезно?

Решение

После нескольких часов копания я нашел способ создать проект CMake для моего приложения Qt для iOS.Ключевые подсказки я получил через Google и проверив выходные данные, сгенерированные qmake.Я нашел сценарии, которые на самом деле творят всю магию, и применил ее части к своим источникам CMake.

Это рецепт, который мне помог.Для полноты картины я добавил также шаги, о которых уже знал, когда публиковал вопрос выше:

  • Представьте CMake в цепочке инструментов iOS.См. cmake/toolchain/ios.toolchain.cmake моего примера проекта.Он устанавливает несколько свойств CMake и ищет необходимые инструменты и платформы.(Я уже не помню, откуда у меня этот файл, но он используется и в нескольких других проектах, если вы его ищете в Google.) Вам нужно передать этот установочный файл в качестве аргумента CMake (см. ниже).

  • Установите несколько целевых свойств вашего исполняемого файла, чтобы превратить его в пакет приложений (iOS).Должно быть ясно.Обратите внимание, что существует шаблон Info.plist.in, который будет завершен CMake.

  • Исправить 1:Свяжите недостающие библиотеки и платформы с приложением вручную в CMake.По какой-то причине find_package(Qt5 ...) не возвращает полный список зависимостей.Хотя очень вероятно, что я здесь что-то упускаю.

  • Исправить 2:Обязательно принудительно загрузите libqios, чтобы избежать сообщения об отсутствующем плагине iOS.В CMake:

    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -force_load ${YOUR_QT_ROOT_PATH}/plugins/platforms/libqios.a" )

  • Исправить 3:Удалите ключ раскадровки в Info.plist.in.Этот шаг я не понимаю в деталях.Средство было вдохновлено этот пост на stackoverflow.

    <key>UIMainStoryboardFile</key> <string>main</string>

  • Исправить 4:А теперь вишенка на торте:для iOS вам необходимо переименовать функцию main() в соответствующую версию в формате «C».Судя по всему, Qt поставляется со своим собственным main точку входа и переименовывает ту, которую вы написали, в qtmn().Магию qmake выполняет этот скрипт:ваш/qt/root/path/mkspecs/macx-ios-clang/rename_main.sh.Я не понимаю всей механики этого в деталях.В моем случае меня вполне устраивало переименование сигнатуры функции main:

    // Replace... int main(int argc, char *argv[])

    // ... with this line: extern "C" int qtmn(int argc, char *argv[])

Здесь это снова тот же проект, о котором я говорил в этом вопросе, на этот раз с исправлениями, внесенными сверху.Чтобы построить этот проект, просто позвоните build_ios.sh, и откройте файл xcodeproj, созданный в папке сборки.

Примечание:Рабочие предположения заключаются в том, что доступна правильная версия XCode (в моем случае 5.1.1) и что у вас есть действующее удостоверение подписи (измените его в CMakeLists.txt!).Более того, в моем примере проекта (см. ниже) я предполагаю, что доступен OpenCV, созданный для iOS.Мне нужно было это, чтобы обойти проблему компоновщика:в libpng, поставляемом с OpenCV, отсутствовали некоторые объекты.

Я надеюсь, что это было полезно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top