通过CMake构建的ios上Qt应用程序的运行时错误

时间:2014-07-30 17:10:47

标签: c++ ios qt cmake qt5

你好stackoverflowers:)

如果我构建一个Qt / qmake示例项目(在我的情况下是“analog clock”示例)并将其部署到运行iOS 7.1的设备上,一切顺利:应用程序在设备上执行完美。 Chapeau - 来自digia的人们做了一项艰巨的工作,将ios工具链整合到他们的Qt工作流程中。

但是,如果我将qmake项目翻译成CMake项目,事情就不会那么顺利了。我已经附加了Qt-5.3.1版本的模拟时钟示例(见下文),其中我添加了一个CMakeLists.txt和一个运行CMake的脚本来生成iOS的XCode项目。该项目编译甚至链接(我不得不添加一些额外的链接库,请参阅CMake源文件)。耶。

但是这里有陷阱:应用程序在运行时崩溃并出现以下错误消息:

  

错误:无法加载平台插件“ios”

作为this线程状态中的注释,必须通过项目设置“强制加载”libqios。这样做并没有太多改善情况,只是将错误信息更改为:

  

错误:您在调用UIApplicationMain之前创建了QApplication。   如果您正在编写本机iOS应用程序,并且只想使用Qt   应用程序的一部分,创建QApplication的好地方是从内部   你的UIApplication委托内的'applicationDidFinishLaunching'。

我有两个问题:

  • 有没有人知道运行时错误的问题是什么?我知道qmake(和相应的ios mkspecs)做了很多魔术。但是如何将其转换为CMake?
  • 为什么我必须手动将几个库(harfbuzzng,qios,libpng和几个iOS框架)链接到我的目标?不应该find_package(Qt5 ...)为我做这个工作吗?

Here是包含我的Qt-CMake项目的zip文件的链接。我正在使用的Qt版本是适用于iOS的Qt-5.3.1。

编辑:我发现qmake示例如果将其从Qt示例文件夹结构中删除,就不会像这样工作。直接查看Qt示例:path / to / Qt / examples / widgets / widgets / analogclock。

1 个答案:

答案 0 :(得分:5)

经过几个小时的挖掘,我发现了一种如何为我的Qt应用程序创建一个CMake项目的方法。我通过Google获得的关键提示以及检查qmake生成的输出。我发现这些脚本实际上完成了整个魔术并将其中的一部分应用到我的CMake源中。

这是适合我的食谱。为了完整起见,我还添加了我在上面发布问题时已经知道的步骤:

  • 将CMake引入ios工具链。查看我的示例项目的cmake / toolchain / ios.toolchain.cmake。它设置了几个CMake属性,并寻找必要的工具和框架。 (我不记得我从哪里获得该文件了 - 但是如果你谷歌也可以在其他几个项目中使用它。)你必须将这个设置文件作为参数传递给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中的storyboard键。这一步我不太详细了解。这些方法的灵感来自于stackoverflow上的this帖子。

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

  • 修复4 :现在顶部的樱桃:对于iOS,您必须使用相应的“C”格式版本重命名main()函数。显然,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[])

Here也是我在问题中提到的同一个项目,这次是从上面应用的修补程序。要构建此项目,只需调用build_ios.sh,然后打开在构建文件夹中创建的xcodeproj文件。

注意:工作假设是XCode的正确版本(在我的情况下为5.1.1)可用且您拥有有效的签名身份(在CMakeLists.txt中更改它!)。此外,在我的示例项目中(见下文),我假设为iOS构建的OpenCV可用。我需要它来解决链接器问题:libpng中缺少一些随OpenCV一起提供的对象。

我希望这很有帮助。