OS X QT App redistributable bundle 部署教程
来源:互联网 发布:免费的算账软件 编辑:程序博客网 时间:2024/05/21 20:29
大家做 OS X App开发的时候, 应该注意到Apple简洁的应用程序分发方式 - App bundle, 作者摸索后发现QT官方的文档不是很简洁, 照着教程做容易走弯路, 在这里分享一个比较简单的制作方法:
1) QT项目, 动态库编译为dylib, 可执行程序编译为app bundle输出.
2) 拷贝编译出来的动态库到/usr/lib下
3) 使用QT的macdeployqt工具生成可重分发包, 它会帮你将动态链接的QT framework打进App bundle里.
4) 不建议使用 otool/install_name_tool 自己写库依赖. 希望能自己写成功的同学批评指正.
详细讲一下Apple App bundle: App bundle简而言之就是一个目录树结构:
MyApp.app ----- Contents ------- Frameworks
------- MacOs -------- MyApp
------- Resources
------- Plugins
------- Info.plist
Frameworks 目录一般保存 .framework打包形式的动态库, 可以是项目编译出来的, 也可以第三方的库. MacOs保存可执行文件, Resouces下保存资源. 制作完毕的App bundle, 发布后要求可以放在用户的任何目录执行.
Framework ----- Apple 对程序库独特的打包方式, 目录结构类似于App bundle, 支持单个或多个程序库伞状嵌套, 支持程序库的多版本配置. 具体有兴趣的同学可移步:
https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/OSX_Technology_Overview/SystemFrameworks/SystemFrameworks.html
Framework/App Bundle的制作, 在Apple的X Code工具下制作比较容易,请搜索相关教程. 在QT中制作步骤如下:
QT 项目输出 framework, app bundle的pro设置:
config -= lib_bundle
config += app_bundle
拷贝项目编译输出的dylib到usr/lib下:
sudo cp -R -f mydylib.dylib usr/lib
配置Qt frameworks, 改变引用:
macdeployqt myapp.app -verbose=1
点击下app, 应该能工作了. 虽然看起来很简单, 但也走过一些弯路, 有不少心得, 分享一下吧. 刚开始, 我认为参考Qt 官方的部署文档, 以及install_name_tool教程:
http://qt-project.org/doc/qt-5.0/qtdoc/deployment-mac.html
http://bbs.csdn.net/topics/350155746
应该很容易就能搞定, 到最后发现使用otool, install_name_tool直接修改每个库和程序的引用就行, 但是结果不太好,原因如下:
1) 程序库之间的引用比较复杂, 自己写配置极其容易出错.
2) 即使写对了install_name_tool, QT中深层次依赖仍然没有搞定, 会出一些奇怪的问题, 以及crash, 自己写需要对程序库之间的依赖关系非常熟悉.
展开讲一下, 比如说我的项目有5个动态库, 1个可执行文件, 使用了QtCore, QtGui两个framework, 假设库分别为a,b,c,d,e, 可执行程序为MyApp. b依赖a, c依赖a,b, d依赖a, b, c, e依赖c, d, MyApp依赖a,b, c,d, e. 那么咱们用otool 逐个检查每个库或可执行文件, 以f为例:
otool -L MyApp.app/Contents/MacOs/MyApp
你会发现MyApp对a, b, c, d, e, QtCore, QtGui都有依赖. 这个时候, 按照Qt部署教程的做法, 先把QtCore, QtGui 两个framework,拷贝到MyApp/Frameworks下( OS X 10.9 在
/Library/Frameworks/) 下, 并建立一个Library目录保存dylib. 然后逐条用install_name_tool修改MyApp的依赖:
install_name_tool -change a.dylib @loader_path/../Library/a..dylib MyApp/Contents/MacOS/MyApp
...
install_name_tool -change e.dylib @loader_path/../Library/e..dylib MyApp/Contents/MacOS/MyApp
修改完了项目的动态库, 再修改Qt的模块引用:
install_name_tool -change QtGui.framework/Versions/4/QtGui @loader_path/../Frameworks/QtGui.framework/Versions/4/QtGui MyApp/Contents/MacOS/MyApp
install_name_tool -change QtCore.framework/Versions/4/QtCore @loader_path/../Frameworks/QtCore.framework/Versions/4/QtCore MyApp/Contents/MacOS/MyApp
别忘了QtGui自己依赖QtCore, 继续修改:
install_name_tool -change QtCore.framework/Versions/4/QtCore @loader_path/../Frameworks/QtCore.framework/Versions/4/QtCore MyApp.app/Contents/Frameworks/QtGui.framework/Versions/4/QtGui
搞定了MyApp, 再继续修改a, b, c, d, e吧.
最后当你觉得松了一口气,点击运行的时候,程序crash掉了. 这里有个调试的办法, 就是用终端运行MyApp/Contents/MacOS/MyApp, 看看有何抱怨. 我碰到过一个qt_menu.nib不能加载的问题, 拷贝这个东西到MyApp/Resouces下,问题解决.
最后,能运行了, 但是似乎程序图标不见了. 看看终端, 抱怨QPixmap is null. 为什么图标不能显示? Google一下有的同学在嵌入式开发里也碰到同样的问题,最后他发现libjpg没有烧到板子上去. 猛然警觉, 是不是QtGui引用的图片库没打包成功?这么做太琐碎,太容易错了, 去弄清楚每个第三方库的依赖, 对客户程序员的要求太高了点吧,是不是路走错了?
继续看看Qt 官方的配置文档, 发现Qt提供了一个macdeployqt工具专门来干这个事情. 使用之,非常简单,可以制作dmg, 所有问题解决.看看打好的包里的framework, 活活有8个framework被打包进来: QtGui, QtCore, QtDelarative, QtNetwork, QtScript, QtSql, QtSvg, QtXmlPatterns.
感想: 苹果非常强势地推进自家的X Code, LLDB, OS X 10.9, 似乎完全不考虑QT的感受, QT失去Nokia的支持后似乎对OS X支持得一般, 也许在苹果后面追赶擦屁股的感觉并不太好. 不过在OS X上用QT的程序员应该大大的有, 希望大家多多交流,.
- OS X QT App redistributable bundle 部署教程
- iOS和OS X中的bundle
- MACOS X QT部署
- Mplayer/mencoder as application bundle for Mac OS X?
- Firefox OS App开发及部署
- Qt开发环境之Mac OS部署
- Qt开发环境之Mac OS部署
- Qt开发环境如何部署Mac OS
- Mac OS X 10.5系统部署实践
- #Mac OS X下Maven部署
- Mac OS X 下 App 的卸载
- Administrator Privilege in Mac OS X app
- Mac OS X必备APP推荐之一
- Installing Qt for Mac OS X
- Mac os x下编译安装Qt
- 苹果MAC OS X双系统安装教程
- 【git】Mac OS X Git安装教程
- Mac OS X Git安装教程
- Qt Model/View 学习笔记 (七)
- LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- ORA-12514 :Oracle 10g 连接时问题小记
- 听框架师——李云谈如何成为一个技术“牛人”
- 好友的blog
- OS X QT App redistributable bundle 部署教程
- Direct9学习之--------------------------动画<骨骼动画>
- Direct3D VertexBuffer Lock() and Unlock() function
- VC 6.0 调试技巧
- UVA 10795 - A Different Task(递归)
- fork 与 vfork区别
- dos获取键盘输入
- Linux 性能监控常用命令
- WCF服务编程-HelloWorld(转载)