Flutter桌面端-MacOS一键打包方案

前言

前阵子在做一个桌面端软件,使用了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/...

相关推荐
千里马学框架12 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台12 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone13 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc13 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo15 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun00770015 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼16 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
茶底世界之下17 小时前
为什么预览、录制、离线导出不能共享同一个背压策略?
ios·swift
AFinalStone17 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen17 小时前
属性动画原理与高级动画实现
android·kotlin·canvas