前言
前阵子在做一个桌面端软件,使用了Flutter来开发。打包Mac版本的时候发现过程较为繁琐且重复性极高,于是做了一个脚本来协助打包。
方案主要是通过shell脚本调用App打包命令以及create-dmg
命令来生成dmg
格式的安装包。
方案的特点
- 双击shell脚本即可打包成dmg文件,方便快捷
- 仅需配置好
create-dmg
命令,后续脚本直接放到工程中即可使用 dmg
文件名自动读取当前版本号,容易辨认
使用
1.配置 create-dmg 命令
create-dmg 是将.App文件打包为.dmg格式的脚本。
可以使用Homebrew安装此脚本:
brew install create-dmg
注:create-dmg
命令在电脑上安装过的话就不需要重复安装了(可以在终端运行 create-dmg --version
命令来看下是否有安装)。
2.拷贝脚本文件
将github上的packages文件夹拷贝到Flutter项目的根目录下。
注意 generate_mac_dmg
文件和 installer_background.png
文件都需要在里面。
然后给 generate_mac_dmg
文件可执行权限(终端窗口中执行 chmod +x generate_mac_dmg
文件路径 )
3.双击运行
需要打包的时候,直接双击运行 generate_mac_dmg
脚本 。
运行后就会自动打包。打包完成后自动弹出dmg文件所在的文件夹(在脚本目录下的products文件夹)。
原理
本脚本原理较为简单。总体步骤为 清除项目缓存 → 编译项目(会生成.app
文件) → 读取.app
文件路径 → 将.app
文件封装成 dmg
格式。
完整脚本
sh
#!/bin/sh
# macos打包脚本。编译生成.app并打包成dmg格式
# 使用方式:直接运行脚本
# 生成的文件名的前缀。默认会读取.app的名称作为前缀,你可以按照需求自己修改
fileNamePrefix=""
# 设置.app的名称。此为flutter build后生成的.app文件名。如果不设置,默认去/build/macos/Build/Products/Release目录下找。一般不需设置。
appName=""
# # 编译macos release版本
cd "$( dirname "$0" )"
cd ../
# 先清除build文件夹的缓存,避免影响打包
flutter clean
# 直接build,会生成一个.app包
flutter build macos --release
#从pubspec.yaml文件获取版本号
set -e
file=$(cat pubspec.yaml)
fullVersion=$(echo | grep -i -e "version: " pubspec.yaml)
buildName=$(echo $fullVersion | cut -d " " -f 2 | cut -d "+" -f 1)
buildNumber=$(echo $fullVersion | cut -d "+" -f 2 )
echo "$fullVersion BUILD_NAME ${buildName} BUILD_NUMBER ${buildNumber}"
version=$buildName
cd "$( dirname "$0" )"
# 从build的Release文件夹中获取.app文件的名称
cd "../build/macos/Build/Products/Release"
appPath=$(find . -type d -name "*.app")
echo "appPath=${appPath}"
internalAppName=$(basename $appPath .app)
echo "internalAppName=${internalAppName}"
# 如果前面没有设置appName,则使用读取到的名称
if [[ ${appName}x == ""x ]]; then
appName=$internalAppName
fi
# 如果前面没有设置fileNamePrefix,则使用appName的值
if [ ${fileNamePrefix}x == ""x ] ; then
fileNamePrefix=$appName
fi
# 最后生成的文件名
fileName="${fileNamePrefix}_macos_${buildName}_${buildNumber}.dmg"
cd "$( dirname "$0" )"
# 判断目录是否存在
if [ ! -d "./products" ]; then
# 如果目录不存在,则创建目录
mkdir -p "./products"
echo "目录不存在,已创建目录"
else
echo "目录已存在"
fi
cd ./products
test -f "$fileName" && rm "$fileName"
# 从.app生成.dmg
create-dmg \
--volname "${appName}安装器" \
--background "../installer_background.png" \
--window-pos 200 120 \
--window-size 800 450 \
--icon-size 100 \
--icon "${appName}.app" 240 190 \
--hide-extension "${appName}.app" \
--app-drop-link 550 190 \
"./$fileName" \
"../../build/macos/Build/Products/Release"
open ./
清除项目缓存
使用的是Flutter脚本命令 flutter clean
。实际上是删除了flutter build
命令生成的build文件夹。
编译项目
使用的是Flutter脚本命令 flutter build macos --release
。
运行后会在项目根目录生成build文件夹
读取.app文件路径
build成功后会在 /build/macos/Build/Products/Release
目录下找到 .app
文件(该文件可以在电脑上直接运行)
将.app文件封装成 dmg 格式
这里是使用了create-dmg
命令。将.app
文件路径、背景图片路径、导出路径输入后即可。里面的大小和名称可以自由修改看看效果。
sh
# 从.app生成.dmg
create-dmg \
--volname "${appName}安装器" \
--background "../installer_background.png" \
--window-pos 200 120 \
--window-size 800 450 \
--icon-size 100 \
--icon "${appName}.app" 240 190 \
--hide-extension "${appName}.app" \
--app-drop-link 550 190 \
"./$fileName" \
"../../build/macos/Build/Products/Release"
参考
Demo github.com/shixueqian/... create-dmg github.com/create-dmg/...