fastforge (原名 flutter_distributor)是一个强大的工具,支持跨平台发布和高级打包选项。
安装
确保 fastforge 已安装:
1 |
$ dart pub global activate fastforge |
配置文件
为高级打包配置所需的文件:
-
macOS:
-
如果打包 DMG 安装包:macos/packaging/dmg/make_config.yaml
macos/packaging/dmg/make_config.yamlYAML12345678910title: 应用名称contents:- x: 448y: 244type: linkpath: "/Applications"- x: 192y: 244type: filepath: 应用名称.app -
如果打包 PKG 安装包:macos/packaging/pkg/make_config.yaml
macos/packaging/pkg/make_config.yamlYAML12install-path: /Applications#sign-identity: <your-sign-identity> -
distribute_options.yaml
distribute_options.yamlYAML1output: dist/
-
-
Windows:
-
如果打包 exe 安装包:windows/packaging/exe/inno_setup.sas
windows/packaging/exe/inno_setup.sasINI12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273[Setup]AppId={{APP_ID}}AppVersion={{APP_VERSION}}AppName={{DISPLAY_NAME}}AppPublisher={{PUBLISHER_NAME}}AppPublisherURL={{PUBLISHER_URL}}AppSupportURL={{PUBLISHER_URL}}AppUpdatesURL={{PUBLISHER_URL}}DefaultDirName={{INSTALL_DIR_NAME}}DisableProgramGroupPage=yesOutputDir=.OutputBaseFilename={{OUTPUT_BASE_FILENAME}}Compression=lzmaSolidCompression=yesSetupIconFile={{SETUP_ICON_FILE}}WizardStyle=modernPrivilegesRequired={{PRIVILEGES_REQUIRED}}ArchitecturesAllowed=x64ArchitecturesInstallIn64BitMode=x64CloseApplications=force[Languages]{% for locale in LOCALES %}{% if locale == 'en' %}Name: "english"; MessagesFile: "compiler:Default.isl"{% endif %}{% if locale == 'hy' %}Name: "armenian"; MessagesFile: "compiler:Languages\\Armenian.isl"{% endif %}{% if locale == 'bg' %}Name: "bulgarian"; MessagesFile: "compiler:Languages\\Bulgarian.isl"{% endif %}{% if locale == 'ca' %}Name: "catalan"; MessagesFile: "compiler:Languages\\Catalan.isl"{% endif %}{% if locale == 'zh' %}Name: "chinesesimplified"; MessagesFile: "compiler:Languages\\ChineseSimplified.isl"{% endif %}{% if locale == 'co' %}Name: "corsican"; MessagesFile: "compiler:Languages\\Corsican.isl"{% endif %}{% if locale == 'cs' %}Name: "czech"; MessagesFile: "compiler:Languages\\Czech.isl"{% endif %}{% if locale == 'da' %}Name: "danish"; MessagesFile: "compiler:Languages\\Danish.isl"{% endif %}{% if locale == 'nl' %}Name: "dutch"; MessagesFile: "compiler:Languages\\Dutch.isl"{% endif %}{% if locale == 'fi' %}Name: "finnish"; MessagesFile: "compiler:Languages\\Finnish.isl"{% endif %}{% if locale == 'fr' %}Name: "french"; MessagesFile: "compiler:Languages\\French.isl"{% endif %}{% if locale == 'de' %}Name: "german"; MessagesFile: "compiler:Languages\\German.isl"{% endif %}{% if locale == 'he' %}Name: "hebrew"; MessagesFile: "compiler:Languages\\Hebrew.isl"{% endif %}{% if locale == 'is' %}Name: "icelandic"; MessagesFile: "compiler:Languages\\Icelandic.isl"{% endif %}{% if locale == 'it' %}Name: "italian"; MessagesFile: "compiler:Languages\\Italian.isl"{% endif %}{% if locale == 'ja' %}Name: "japanese"; MessagesFile: "compiler:Languages\\Japanese.isl"{% endif %}{% if locale == 'no' %}Name: "norwegian"; MessagesFile: "compiler:Languages\\Norwegian.isl"{% endif %}{% if locale == 'pl' %}Name: "polish"; MessagesFile: "compiler:Languages\\Polish.isl"{% endif %}{% if locale == 'pt' %}Name: "portuguese"; MessagesFile: "compiler:Languages\\Portuguese.isl"{% endif %}{% if locale == 'ru' %}Name: "russian"; MessagesFile: "compiler:Languages\\Russian.isl"{% endif %}{% if locale == 'sk' %}Name: "slovak"; MessagesFile: "compiler:Languages\\Slovak.isl"{% endif %}{% if locale == 'sl' %}Name: "slovenian"; MessagesFile: "compiler:Languages\\Slovenian.isl"{% endif %}{% if locale == 'es' %}Name: "spanish"; MessagesFile: "compiler:Languages\\Spanish.isl"{% endif %}{% if locale == 'tr' %}Name: "turkish"; MessagesFile: "compiler:Languages\\Turkish.isl"{% endif %}{% if locale == 'uk' %}Name: "ukrainian"; MessagesFile: "compiler:Languages\\Ukrainian.isl"{% endif %}{% endfor %}[Tasks]Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: {% if CREATE_DESKTOP_ICON != true %}unchecked{% else %}checkedonce{% endif %}Name: "launchAtStartup"; Description: "{cm:AutoStartProgram,{{DISPLAY_NAME}}}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: {% if LAUNCH_AT_STARTUP != true %}unchecked{% else %}checkedonce{% endif %}[Files]Source: "{{SOURCE_DIR}}\\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; NOTE: Don't use "Flags: ignoreversion" on any shared system files[Icons]Name: "{autoprograms}\\{{DISPLAY_NAME}}"; Filename: "{app}\\{{EXECUTABLE_NAME}}"Name: "{autodesktop}\\{{DISPLAY_NAME}}"; Filename: "{app}\\{{EXECUTABLE_NAME}}"; Tasks: desktopiconName: "{userstartup}\\{{DISPLAY_NAME}}"; Filename: "{app}\\{{EXECUTABLE_NAME}}"; WorkingDir: "{app}"; Tasks: launchAtStartup[Run]Filename: "{app}\\{{EXECUTABLE_NAME}}"; Description: "{cm:LaunchProgram,{{DISPLAY_NAME}}}"; Flags: {% if PRIVILEGES_REQUIRED == 'admin' %}runascurrentuser{% endif %} nowait postinstall skipifsilent[Code]function InitializeSetup(): Boolean;varResultCode: Integer;beginExec('taskkill', '/F /IM 应用名称.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)Result := True;end;windows/packaging/exe/make_config.yaml
windows/packaging/exe/make_config.yamlYAML1234567891011121314151617app_id: 6L913538-42B1-4596-G479-BJ779F21A65Dpublisher: 应用名称publisher_url: https://github.com/aaa/aaadisplay_name: 应用名称executable_name: 应用名称.exeoutput_base_file_name: 应用名称.execreate_desktop_icon: trueinstall_dir_name: "{autopf64}\\应用名称"setup_icon_file: ..\..\windows\runner\resources\app_icon.icolocales:- ar- en- fa- ru- pt- trscript_template: inno_setup.sas -
如果打包 msix windows/packaging/msix/make_config.yaml
windows/packaging/msix/make_config.yamlYAML12345678910111213141516171819202122232425262728293031323334353637383940414243# 应用名称display_name: 应用名称# 应用名称publisher_display_name: 应用名称# 应用名称identity_name: 应用名称.appioimsix_version: 2.5.7.0# 应用图标logo_path: windows\runner\resources\app_icon.ico# 应用能力capabilities: internetClient, internetClientServer, privateNetworkClientServer# 多语言languages: en-us, zh-cn, zh-tw, tr-tr,fa-ir,ru-ru,pt-br,es-esprotocol_activation: 应用名称execution_alias: 应用名称# 签名证书# certificate_path: windows\sign.pfx# 签名证书密码certificate_password:# 发布者的唯一识别IDpublisher: CN=8CB43675-F44B-4AA5-9372-E8727781BDC4install_certificate: "false"# let OS know if the application can be run on start_up. If it's false# the application will deny to the OS if it was added as a start_up# applicationenable_at_startup: "false"# 应用启动参数startup_task:parameters: --autostart
-
-
Linux:
-
linux/packaging/appimage
有两个文件 linux/packaging/appimage/AppRun
linux/packaging/appimage/AppRunShell12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849#!/bin/bashcd "$(dirname "$0")"export LD_LIBRARY_PATH=usr/lib# Usage infoshow_help() {cat << EOFUsage: ${0##*/} ...start app or app, when no parameter is given, app is executed.-v show versionEOF}show_version() {printf "app version "jq .version <./data/flutter_assets/version.json}# Initialize variables:service=0 #declare -i serviceOPTIND=1# Resetting OPTIND is necessary if getopts was used previously in the script.# It is a good idea to make OPTIND local if you process options in a function.# if no arg is provided, execute appif [[ $# == 0 ]];thenexec ./appelse# processing argumentscase $1 inappCli)exec ./appCli ${@:3}exit 0;;h)show_helpexit 0;;v) show_versionexit 0;;*)show_help >&2exit 1;;esacfilinux/packaging/appimage/make_config.yaml
linux/packaging/appimage/make_config.yamlYAML123456789101112131415161718192021222324252627282930313233343536display_name: App名称icon: ./assets/images/source/ic_launcher_border.pngkeywords:- Higeneric_name: App名称actions:- name: Startlabel: startarguments:- --start- name: Stoplabel: stoparguments:- --stopcategories:- Networkstartup_notify: trueapp_run_file: AppRun# You can specify the shared libraries that you want to bundle with your app## flutter_distributor automatically detects the shared libraries that your app# depends on, but you can also specify them manually here.## The following example shows how to bundle the libcurl library with your app.## include:# - libcurl.so.4include: [] -
linux/packaging/deb 文件 linux/packaging/deb/make_config.yaml
linux/packaging/deb/make_config.yamlYAML123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113# the name used to display in the OS. Specifically desktop# entry namedisplay_name: AppName# package name for debian/apt repository# the name should be all lowercase with -+.package_name: AppName# 所有者maintainer:name: xxxemail: xxx@xxx.com# 联合作者# co_authors:# - name: xxxx# email: xxxx@xxxx.com# enum options -> required, important, standard, optional, extra# refer: https://www.debian.org/doc/debian-policy/ch-archive.html#s-prioritiespriority: optional# enum options: admin, cli-mono, comm, database, debug, devel, doc, editors, education, electronics, embedded, fonts, games, gnome, gnu-r, gnustep, graphics, hamradio, haskell, httpd, interpreters, introspection, java, javascript, kde, kernel, libdevel, libs, lisp, localization, mail, math, metapackages, misc, net, news, ocaml, oldlibs, otherosfs, perl, php, python, ruby, rust, science, shells, sound, tasks, tex, text, utils, vcs, video, web, x11, xfce, zope# refer: https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsectionssection: x11# the size of binary in kilobyteinstalled_size: 6604# direct dependencies required by the application# refer: https://www.debian.org/doc/debian-policy/ch-relationships.htmldependencies:- libqt5widgets5 (>= 5.15)- libwebkit2gtk (>= 4.0), libsoup (>= 2.4), gettext (>= 0.21)# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html# build_dependencies_indep:# - texinfo# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html# build_dependencies:# - kernel-headers-2.2.10 [!hurd-i386]# - gnumach-dev [hurd-i386]# - libluajit5.1-dev [i386 amd64 kfreebsd-i386 armel armhf powerpc mips]# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html# recommended_dependencies:# - neofetch# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html# suggested_dependencies:# - libkeybinder-3.0-0 (>= 0.3.2)# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html# enhances:# - spotube# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html# pre_dependencies:# - libc6# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html#packages-which-break-other-packages-breaks# breaks:# - libspotify (<< 3.0.0)# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html#conflicting-binary-packages-conflicts# conflicts:# - spotify# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html#virtual-packages-provides# provides:# - libx11# refer: https://www.debian.org/doc/debian-policy/ch-relationships.html#overwriting-files-and-replacing-packages-replaces# replaces:# - spotifyessential: falsepostinstall_scripts:- echo "Installed AppName"postuninstall_scripts:- echo "Surprised Why?"# application icon path relative to project url# icon: assets/logo.pngkeywords:- AppName# a name to categorize the app into a section of applicationgeneric_name: EisApp# supported mime types that can be opened using this application# supported_mime_type:# - audio/mpeg# shown when right clicked the desktop entry icons# actions:# - Gallery# - Create# the categories the application belong to# refer: https://specifications.freedesktop.org/menu-spec/latest/categories:- Network# let OS know if the application can be run on start_up. If it's false# the application will deny to the OS if it was added as a start_up# applicationstartup_notify: false -
linux/packaging/rpm 文件 linux/packaging/rpm/make_config.yaml
linux/packaging/rpm/make_config.yamlYAML123456789101112131415161718192021display_name: Appurl: https://github.com/app/app-next/license: Otherpackager: ApppackagerEmail: linux@App.compriority: optionalsection: x11installed_size: 6604essential: falseicon: ./assets/images/source/ic_launcher_border.pngkeywords:- Higeneric_name: Appgroup: Applications/Internetstartup_notify: true
-
命令示例
-
打包 macOS (DMG 和 PKG)
123$ export PATH="$PATH":"$HOME/.pub-cache/bin"$ fastforge package --flutter-build-args=verbose --platform macos --targets dmg,pkg -
打包 Windows (EXE 和 MSIX)
12345$Env:PATH += ";$HOME/AppData/Local/Pub/Cache/bin"dart pub global activate fastforgefastforge package --flutter-build-args=verbose --platform windows --targets exe,msix -
打包 Linux (DEB、RPM 和 AppImage)
123$ export PATH="$PATH":"$HOME/.pub-cache/bin"$ fastforge package --flutter-build-args=verbose --platform linux --targets deb,rpm,appimage