通过CMake构建的iOS Qt应用程序运行时出现错误

4
如果我构建一个Qt/qmake示例项目(在我的情况下是“模拟时钟”示例),并将其部署到运行iOS 7.1的设备上,一切都很顺利:应用程序在设备上无缝执行。棒极了 - digia的人们在将ios工具链集成到他们的Qt工作流中做了出色的工作。
然而,如果我将qmake项目转换为CMake项目,情况就不那么顺利了。我附加了来自Qt-5.3.1发布版的模拟时钟示例(见下文),其中我添加了一个CMakeLists.txt文件和一个运行CMake生成iOS XCode项目的脚本。项目编译甚至链接(我不得不添加一些额外的链接库,参见CMake源文件)。耶!
但是这里有个陷阱:应用程序在运行时崩溃,并显示以下错误消息:

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

作为this线程中的一条评论所述,人们必须通过项目设置“强制加载”libqios。这样做并没有改善情况,只是将错误消息更改为:
错误:在调用UIApplicationMain之前创建QApplication。 如果您正在编写原生iOS应用程序,并且仅想在应用程序的某些部分中使用Qt,则可以从UIApplication委托内的'applicationDidFinishLaunching'中创建QApplication。
我有两个问题:
1. 有人知道运行时错误的问题吗?我知道qmake(以及相应的ios mkspecs)会进行一些魔法。但如何将其转换为CMake?
2. 为什么我必须手动链接多个库(harfbuzzng、qios、libpng和几个iOS框架)到我的目标?find_package(Qt5 ...)不应该为我完成这项工作吗?

这里是一个包含我的Qt-CMake项目的zip文件的链接。我使用的Qt版本是适用于iOS的Qt-5.3.1。

编辑: 我发现,如果你将qmake示例从Qt示例文件夹结构中拆分出来,它就不能像这样工作。请直接查看Qt示例:path/to/Qt/examples/widgets/widgets/analogclock。


Qt5在静态链接时表达依赖关系似乎存在问题。我不得不为harfbuzz等静态情况下自己制定规则。 - yano
1个回答

5
在挖掘了几个小时后,我找到了一种方法来为我的iOS Qt应用程序创建CMake项目。我通过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中删除storyboard密钥。这一步我不太明白。这个方法受到this stackoverflow上的帖子的启发。 UIMainStoryboardFile main 修复4:现在是iOS的最佳解决方案:您必须使用相应的“C”格式化版本重命名main()函数。显然,Qt带有自己的main入口点,并将您编写的一个重命名为qtmn()。这个qmake魔法由这个脚本执行:your/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中更改!)。此外,在我的示例项目(请参见下文)中,我假设已经为iOS构建了OpenCV。我需要它来解决链接器问题:libpng中缺少一些对象,这些对象随OpenCV一起提供。


2
我的Dropbox账户被删除了。以上一些链接已经失效。对此表示抱歉。 - normanius
有没有一种方法可以获取“固定”的模拟时钟项目,而不使用Dropbox? - fghj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接