跳至主要内容

构建并发布 Linux 应用到 Snap 商店

在典型的开发周期中,您使用命令行中的 flutter run 或 IDE 中的**运行**和**调试**选项来测试应用。默认情况下,Flutter 会构建应用的调试版本。

当您准备好准备应用的发布版本时,例如要发布到 Snap 商店,此页面可以提供帮助。

先决条件

#

要构建并发布到 Snap 商店,您需要以下组件

设置构建环境

#

使用以下说明设置您的构建环境。

安装 snapcraft

#

在命令行中,运行以下命令

sudo snap install snapcraft --classic

安装 LXD

#

要安装 LXD,请使用以下命令

sudo snap install lxd

LXD 在 Snap 构建过程中是必需的。安装后,需要配置 LXD 以供使用。默认答案适用于大多数用例。

sudo lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, dir, lvm, zfs, ceph) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty disk or partition? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=5GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]:
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

在第一次运行时,LXD 可能无法连接到其套接字

An error occurred when trying to communicate with the 'LXD'
provider: cannot connect to the LXD socket
('/var/snap/lxd/common/lxd/unix.socket').

这意味着您需要将您的用户名添加到 LXD (lxd) 组,因此请退出您的会话,然后重新登录

sudo usermod -a -G lxd <your username>

Snapcraft 概述

#

snapcraft 工具根据 snapcraft.yaml 文件中列出的说明构建 Snap 包。要了解 snapcraft 及其核心概念的基本知识,请查看Snap 文档Snapcraft 简介。此页面底部列出了其他链接和信息。

Flutter snapcraft.yaml 示例

#

将 YAML 文件放在 Flutter 项目的 <project root>/snap/snapcraft.yaml 下。(并记住 YAML 文件对空格敏感!)例如

yaml
name: super-cool-app
version: 0.1.0
summary: Super Cool App
description: Super Cool App that does everything!

confinement: strict
base: core22
grade: stable

slots:
  dbus-super-cool-app: # adjust accordingly to your app name
    interface: dbus
    bus: session
    name: org.bar.super_cool_app # adjust accordingly to your app name and
    
apps:
  super-cool-app:
    command: super_cool_app
    extensions: [gnome] # gnome includes the libraries required by flutter
    plugs:
    - network
    slots:
      - dbus-super-cool-app
parts:
  super-cool-app:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart # The main entry-point file of the application

以下部分解释了 YAML 文件的各个部分。

元数据

#

snapcraft.yaml 文件的这一部分定义并描述了应用程序。Snap 版本是从构建部分派生(采用)的。

yaml
name: super-cool-app
version: 0.1.0
summary: Super Cool App
description: Super Cool App that does everything!

等级、限制和基础

#

此部分定义了 Snap 包的构建方式。

yaml
confinement: strict
base: core18
grade: stable
等级
指定 Snap 包的质量;这与以后的发布步骤相关。
限制
指定 Snap 包安装到最终用户系统后将具有的系统资源访问级别。严格限制会将应用程序访问权限限制到特定资源(在 app 部分中由插件定义)。
基础
Snap 包旨在成为自包含的应用程序,因此,它们需要自己的私有核心根文件系统,称为 basebase 关键字指定用于提供最小通用库集的版本,并在运行时作为应用程序的根文件系统挂载。

应用

#

此部分定义了 Snap 包中存在的应用程序。每个 Snap 包可以包含一个或多个应用程序。此示例包含单个应用程序——super_cool_app。

yaml
apps:
  super-cool-app:
    command: super_cool_app
    extensions: [gnome]
命令

指向相对于 Snap 包根目录的二进制文件,并在调用 Snap 包时运行。

扩展

一个或多个扩展的列表。Snapcraft 扩展是可重用的组件,可以在构建时和运行时向 Snap 包公开库和工具集,而无需开发人员了解包含的框架。gnome 扩展向 Flutter Snap 包公开 GTK 3 库。这可确保更小的占用空间并更好地与系统集成。

插槽

系统接口的一个或多个插槽的列表。当 Snap 包被严格限制时,这些是提供必要功能所必需的。此 Flutter Snap 包需要访问网络。

DBus 接口

DBus 接口提供了一种方法,使 Snap 包可以通过 DBus 进行通信。提供 DBus 服务的 Snap 包声明一个具有众所周知的 DBus 名称和使用的总线的插槽。想要与提供 Snap 包的服务通信的 Snap 包声明提供 Snap 包的插槽。请注意,需要您的 Snap 包的声明才能通过 Snap 商店交付并声明此众所周知的 DBus 名称(只需将 Snap 包上传到商店并请求手动审查,审查人员将查看)。

安装提供 Snap 包后,snapd 将生成安全策略,允许它在指定的总线上侦听众所周知的 DBus 名称。如果指定了系统总线,snapd 还将生成 DBus 总线策略,允许“root”拥有该名称,并且任何用户都可以与该服务通信。非 Snap 包进程可以通过传统的权限检查与提供 Snap 包进行通信。其他(使用)Snap 包可能仅通过连接 Snap 包的接口与提供 Snap 包进行通信。

dbus-super-cool-app: # adjust accordingly to your app name
  interface: dbus
  bus: session
  name: dev.site.super_cool_app

部件

#

此部分定义了组装 Snap 包所需的源。

可以使用插件自动下载和构建部件。与扩展类似,snapcraft 可以使用各种插件(例如 Python、C、Java 和 Ruby)来帮助构建过程。Snapcraft 还有一些特殊的插件。

nil 插件
不执行任何操作,实际的构建过程使用手动覆盖处理。
flutter 插件
提供必要的 Flutter SDK 工具,以便您可以使用它,而无需手动下载和设置构建工具。
yaml
parts:
  super-cool-app:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart # The main entry-point file of the application

桌面文件和图标

#

桌面条目文件用于将应用程序添加到桌面菜单。这些文件指定应用程序的名称和图标、它所属的类别、相关的搜索关键词等等。这些文件扩展名为 .desktop,并遵循 XDG 桌面条目规范版本 1.1。

Flutter super-cool-app.desktop 示例

#

将 .desktop 文件放在 Flutter 项目的 <project root>/snap/gui/super-cool-app.desktop 下。

注意:图标和 .desktop 文件名必须与 yaml 文件中应用名称相同!

例如

yaml
[Desktop Entry]
Name=Super Cool App
Comment=Super Cool App that does everything
Exec=super-cool-app 
Icon=${SNAP}/meta/gui/super-cool-app.png # Replace name with your app name.
Terminal=false
Type=Application
Categories=Education; # Adjust accordingly your snap category.

将您的图标(扩展名为 .png)放在 Flutter 项目的 <project root>/snap/gui/super-cool-app.png 下。

构建 Snap 包

#

完成 snapcraft.yaml 文件后,按如下方式从项目的根目录运行 snapcraft

要使用 Multipass VM 后端

snapcraft

要使用 LXD 容器后端

snapcraft --use-lxd

测试 Snap 包

#

构建 Snap 包后,您将在根项目目录中获得一个 <name>.snap 文件。

$ sudo snap install ./super-cool-app_0.1.0_amd64.snap --dangerous

发布

#

您现在可以发布 Snap 包了。该过程包括以下步骤

  1. snapcraft.io上创建一个开发者帐户,如果您还没有的话。
  2. 注册应用名称。注册可以通过 Snap 商店 Web UI 门户或从命令行进行,如下所示
    snapcraft login
    snapcraft register
  3. 发布应用。在阅读下一节以了解如何选择 Snap 商店频道后,将 Snap 包推送到商店
    snapcraft upload --release=<channel> <file>.snap

Snap 商店频道

#

Snap 商店使用频道来区分不同版本的 Snap 包。

snapcraft upload 命令将 Snap 包文件上传到商店。但是,在运行此命令之前,您需要了解不同的发布频道。每个频道包含三个组件

轨道
所有 Snap 包都必须具有一个名为 latest 的默认轨道。除非另有说明,否则这是隐含的轨道。
风险
定义应用程序的准备情况。Snap 商店中使用的风险级别为:stablecandidatebetaedge
分支
允许创建短期 Snap 包序列以测试错误修复。

Snap 商店自动审查

#

Snap 商店对您的 Snap 包运行多个自动检查。根据 Snap 包的构建方式以及是否存在任何特定的安全问题,也可能进行手动审查。如果检查通过且没有错误,则 Snap 包将在商店中可用。

其他资源

#

您可以在 snapcraft.io 网站上的以下链接中了解更多信息