在 iOS 应用程序中嵌入文件 (C++/Qt/cmake)
Posted
技术标签:
【中文标题】在 iOS 应用程序中嵌入文件 (C++/Qt/cmake)【英文标题】:Embedding files in an iOS app (C++/Qt/cmake) 【发布时间】:2020-11-20 14:50:57 【问题描述】:在 ios c++/Qt 应用程序中,我需要传送一些文件并将它们保存在它们的目录结构中。
对于 android 版本,我们在创建 QApplication 之前捆绑了一个解压到目标上的 zip。
在 iOS 上,CMake 似乎无法将文件捆绑在树中: https://cmake.org/cmake/help/latest/prop_tgt/RESOURCE.html#prop_tgt:RESOURCE https://cmake.org/cmake/help/latest/prop_sf/MACOSX_PACKAGE_LOCATION.html
我不确定这是 cmake 的限制还是 iOS 的全局限制。 来自docs about iOS bundles:
它使用相对扁平的结构,几乎没有多余的目录,以节省磁盘空间并简化对文件的访问。
首选的方法是什么?
-
是否有直接从 CMake 发送文件的解决方案?
如果没有,我怎样才能做到这一点,以便在创建 QApplication 之前它们可用?
xcode 命令
感谢@Cy-4AH,我在 Xcode 中添加了文件夹,并且可以获得执行此操作的命令:
CpResource _PATH_TO_DIRECTORY_ _APP_BUNDLE_DIRECTORY_/_RESOURCE_DIR_NAME_
cd /Users/denis/opt/qfield/ios/QField
export PATH="....."
builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -strip-debug-symbols -strip-tool /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip -resolve-src-symlinks _PATH_TO_DIRECTORY_ _APP_BUNDLE_DIRECTORY_
但是我怎样才能从 cmake 创建呢? builtin-copy
是一个xcode命令。
简单的系统复制命令
从旧的 (2008) discussion 开始,我们可以使用简单的 cp
命令。
这适用于签名,但随后我收到错误unsealed contents present in the bundle root
。
从这个answer 看来,我不能简单地在资源目录中添加文件夹。来自文档anatomy of framework bundles:Nonlocalized resources reside at the top level of the Resources directory
【问题讨论】:
只需放入 app bundle ????♂️。您可以在 xcode 构建日志中查看它如何将文件复制到包中并使用CMake
进行相同的调用
非常感谢@Cy-4AH,这让我更进一步。但问题仍然存在于如何在不实际在 xcode 中执行此操作的情况下从 cmake 触发此操作。
我不完全记得几年前我们是如何解决这个问题的,但我记得我在 CMake 的 source_group 下添加了文件。从objective-c,我只是在没有文件的情况下访问它,比如 [[NSBundle mainBundle] pathForResource:@"test" ofType:@"txt"];
【参考方案1】:
(免责声明:我不是 CMake 用户,可能有更 CMake-ey 的方式来做到这一点)
如果您可以设置构建后操作,则以下终端脚本可以有效地将文件从其他位置同步到您的包中。我在我的游戏引擎中使用它,因为它只在后续构建时复制更新或新文件,并保留目录结构:
mkdir -p PATHTO/ORIGINFOLDERNAME
mkdir -p PATHTOBUILDFOLDER/PROJECTNAME.app/Contents/Resources/DESTINATIONFOLDERNAME
rsync -avu --delete --exclude=".*" PATHTO/ORIGINFOLDERNAME/ PATHTOBUILDFOLDER/PROJECTNAME.app/Contents/Resources/DESTINATIONFOLDERNAME
mkdir
命令仅用于确保在删除文件夹时生成文件夹。
【讨论】:
这实际上是 Xcode 在其内置副本背后所做的事情。这将是一个可接受的解决方案。但最后 cmake 命令正在使用目录。我给你赏金,因为这将是一个解决方案。谢谢! 天哪,谢谢你的赏金!这是我的荣幸!【参考方案2】:显然 CMake 方法也适用于目录。
target_sources($QT_IOS_TARGET PRIVATE $_resource)
set_source_files_properties($_resource PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
它只会被添加到包的根目录,而不是Resources
。
【讨论】:
【参考方案3】:如果嵌入文件不是太大,你可以考虑:
在您的源代码树中,生成一个将该文件嵌入为常量数组的 C++ 文件。例如,如果您的文件仅包含带有新行的 hello, world
,您可能会有类似
/// file contents.cc
const char file_contents[] = "hello, world\n";
并在程序的开头(可能在您的 main
函数中,在您的 QApplication
之前)调用一个写入此类文件的 C++ 函数(可能在 /tmp/
中)。
Makefile
或您的 qmake 东西),有一些东西可以生成来自真正来源的 C++ contents.cc
文件
这是从 POSIX/Linux 的角度出发,根据您的 iOS 调整我的答案。
【讨论】:
这看起来很笨拙。类似的方法是在资源中加入一个 zip 文件并将其解压缩(嵌入多个文件和一个目录结构)。干杯。以上是关于在 iOS 应用程序中嵌入文件 (C++/Qt/cmake)的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS 应用程序中嵌入文件 (C++/Qt/cmake)
如何使用 Qt/C++ 创建/读取/写入文件并使用程序在本地存储设置
在 Windows 上部署 Qt (C++/QML) 应用程序