12.2-MacOS下打包QT应用程序为DMG包,看这一篇就足够了(包括第三方Lib库)
一、前言
在MacOS系统中,应用软件的安装目录,就在应用软件自己里面。因此所谓安装macos软件,就是直接把应用软件复制到你想安装的目录即可。当然标准的应用软件安装目录为“/Applications”。
这种安装目录就在软件自己里面的方式叫做“bundle”。所谓的bundle是指,软件是以目录的形式存在,目录中有主可执行程序和此程序所依赖的库文件,以及此软件相关的配置文件和图标等。只是在macos系统中把这个目录以一个有图标的文件形式来显示,从而直接看起了就像一个“软件”,并且你双击这个“软件”可以运行此软件。
关于macOS下bundle包的定义
On the Mac, a GUI application must be built and run from a bundle. A bundle is a directory >structure that appears as a single entity when viewed in the Finder. A bundle for an >application typcially contains the executable and all the resources it needs.
二、把Qt编写的程序转化为“双击可执行的软件”,生成可用Bundle
在MacOS系统中,用Qt Creater 编写的程序,在Qt Creater可以点击“运行”按钮来启动软件,但是你在目录中找到这个软件,双击却不能启动,报错提示为找不到此程序的依赖库。因此,使用Qt Creater编写的程序,需要按照以下步骤来生成一个双击可启动运行的Bundle。然后才能打包为DMG或PKG安装包。顺序按照以下步骤操作即可获取一个可以“双击可正确运行的Bundle”
- 使用Qt Creater把自己的应用程序编译一份Release版本,在QtCreater中点击运行,以保证程序可正常运行。编译生成的xxx.app在下图中的…release目录中:

- 打开终端,切换到编译生成的xxx.app包所在的目录(或者把xxx.app单独复制到一个目录),执行以下命令自动给此app添加所依赖的qt动态库。(xxx.app 为编译生成的release执行文件的名字)
macdeployqt ./xxx.app
执行完此命令后,右键xxx.app包选择查看包内容,即可打开一个目录,展开目录可以看到macdeployqt给这个bundle增加了有关qt的依赖库文件,从而达到双击即可运行的目的。如下图所示:

注意:如果提示找不到此命令的解决办法:
在你的qt安装目录找到这个命令的位置,把其路径添加到“bash环境”里面即可。如下图所示:
command not found: macdeployqt //提示找不到此命令
cd ~ //切换到用户家目录
vim .bash_profile //用vim编辑配置文件bash_profile 注:按键盘的“i”进入vim插入模式
//在bash_profile中新增以下这一行的内容,下面这一行的意思是在此目录查找macdeployqt这个命令
export PATH=${PATH}:/Users/robert/Qt5.12.5/5.12.5/clang_64/bin
:wq //退出并保存
source .bash_profile //执行这个命令使刚才的配置立即生效
如果你正确执行完macdeployqt命令,此时你双击xxx.app即可正确运行你的软件,就可以跳过3、4、5、6,直接阅读“三”小节即可。
-
但是如果你双击运行后提示一个崩溃对话框,说程序无法运行,如下图所示:
点击对话框中的“上报”可以查看详细报错内容,查看完成之后点击“不发送”即可。
从报错详情可以看到是一个第三方库镜像(文件)没有找到,因此导致程序启动崩溃。明白了报错原因, 那么解决办法就是找到这个库镜像,添加到这个app包中即可。添加方法请继续阅读4、5、6。 -
执行以下命令查看缺失库镜像的情况
otool -L LedStripEditor.app/Contents/MacOS/LedStripEditor
执行结果截图如下:
根据以上命令的结果可以看到,以“@loader_path/”开头的库文件是自己软件所使用的第三方库,本示例使用的是ffmpeg的动态库。虽然双击执行时候,报错中只报错了ffmpeg的其中一个动态库镜像,但是推断其他其实也是缺失的,应该是指系统检测到第一个不存在的动态库就报错了。
- 既然找到了缺失库的内容了,那么程序是你自己开发的,你当然能找到所缺失库镜像的实际储存位置。现在把他们找出来放到bundle包的Contents/Frameworks目录下即可。这个目录是专门放置第三方库的位置。新建一个FFMPEG目录,并把需要的动态库镜像文件复制进来,如下图所示:

- 但是,macos系统下并不像windows一样直接复制进去即可。还需要专用的命令工具,以下详细说明;
使用以下命令,来更改“@loader_path/libavdevice.58.dylib”成为"@rpath/FFMPEG/libavdevice.58.dylib"
注意,以后每次对xxx.app包重新编辑,都需要再次执行一次以下命令,因此建议把命令写到一个shell脚本中方便快速更改。
install_name_tool -change "@loader_path/libavdevice.58.dylib" "@rpath/FFMPEG/libavdevice.58.dylib" LedStripEditor.app/Contents/MacOS/LedStripEditor
使用以上命令依次对以“@loader_path”开头的库文件做处理,最后的再次使用“otool -L”查看如下:
此时双击xxx.app包即可成功运行程序,表示一个可执行包制作完成了。
注意,不同的路径开头,表示在不同的地方查找依赖文件
详情参考自
https://wincent.com/wiki/%40executable_path%2C_%40load_path_and_%40rpath
无前缀path表示:在系统的/usr/lib 或/usr/local/lib 查找此库镜像
@executable_path表示:可执行文件所在的目录,根具这个目录写镜像库的绝对路径或相对路径
@loader_path表示:在/Library/Application Support/Foo/Plug-Ins/Bar.bundle 查找此依赖库
@rpath表示:是一个动态查找库的模式,表示在-rpath @executable_path/…/Frameworks 或 /Library/Frameworks 目录查找依赖库。
三、把xxx.app把打包成DMG镜像安装包,
虽然直接把xxx.app分发给用户即可正常使用,但是为了规范使用,需要做个安装指引,目的是让用户把xxx.app复制到电脑的 Applications目录下。
- 准备材料
- 双击可以运行的xxx.app
- 安装软件背景图,分辨率1200*900(可以自定义),可以右键保存图片,作为测试背景图片

- 应用程序替身(相当于windows下的应用程序文件夹的快捷方式),“应用程序替身”的制作方式如下:

- 制作磁盘映像
打开LaunchPad,然后找到“磁盘工具”新建一个空白镜像,如下图所示 :
在“磁盘名称”填写你安装包的名字,在“大小”填写空白磁盘的大小,这个大小最后就是安装软件包的大小,注意这个大小需要比所要放置的总文件大小大一点,比如我的示例中,需要放置的总文件为102M,因此我给空白镜像设置的大小为110M。填写好之后点击“保存”即可。如下图所示:

- 把准备放入安装包的文件拖拽到空白镜像中,步骤如下图所示:

- 设置“镜像文件夹的背景图片”
在拖拽完成之后,在镜像所在的文件夹的空白处点击右键,选择“查看显示选项”,在弹出的对话框中设置背景图片,如下图所示:


- 隐藏背景图片文件
可以从上图中看出,添加完背景图片后,背景图片源文件还在,但是不能删除它,因此把它隐藏起来。隐藏的原理是在背景图片的文件名之前加入一个英文逗点符合。用命令来完成此步骤如下:

最终效果如下:

6.在“访达(finder)”中,弹出此“镜像文件”,即完成DMG安装包的制作。