|
| 1 | +--- |
| 2 | +id: debian-ubuntu |
| 3 | +title: Debian / Ubuntu 打包 |
| 4 | +--- |
| 5 | + |
| 6 | +Avalonia Linux 程序可以通过双击可执行文件或在终端中启动的方式,在大多数 Linux 发行版中运行。但是为了提供更好的用户体验,建议将程序安装到系统中,这样用户可以通过桌面快捷方式(比如在 GNOME 和 KDE 等桌面环境中)或通过命令行启动程序,前提是将程序添加到 PATH当中。 |
| 7 | + |
| 8 | +Debian 和 Ubuntu 等相关的发行版将其应用程序打包为 .deb 文件,这样可以通过 sudo apt install ./your_package.deb 命令进行安装。 |
| 9 | + |
| 10 | +## 打包教程 |
| 11 | + |
| 12 | +在本教程中,我们将使用 `dpkg-deb` 工具来编译你的 `.deb` 包。 |
| 13 | + |
| 14 | +### 1) 在暂存文件夹组织程序文件 |
| 15 | + |
| 16 | +Debian 包遵循以下基本结构: |
| 17 | + |
| 18 | +```sh |
| 19 | +./staging_folder/ # 暂存文件夹 |
| 20 | +├── DEBIAN |
| 21 | +│ └── control # 包控制文件 |
| 22 | +└── usr |
| 23 | + ├── bin |
| 24 | + │ └── myprogram # 启动脚本 |
| 25 | + ├── lib |
| 26 | + │ └── myprogram |
| 27 | + │ ├── libHarfBuzzSharp.so # Avalonia 本地库 |
| 28 | + │ ├── libSkiaSharp.so # Avalonia 本地库 |
| 29 | + │ ├── other_native_library_1.so |
| 30 | + │ ├── myprogram_executable # 主可执行文件 |
| 31 | + │ ├── myprogram.dll |
| 32 | + │ ├── my_other_dll.dll |
| 33 | + │ ├── ... # 所有由 dotnet publish 生成的文件 |
| 34 | + └── share |
| 35 | + ├── applications |
| 36 | + │ └── MyProgram.desktop # 桌面快捷方式文件 |
| 37 | + ├── icons |
| 38 | + │ └── hicolor |
| 39 | + │ ├── ... # 其他分辨率图标(可选) |
| 40 | + └── pixmaps |
| 41 | + └── myprogram.png # 主应用程序图标 |
| 42 | +``` |
| 43 | + |
| 44 | +每个文件夹的含义: |
| 45 | + |
| 46 | +* `DEBIAN`: 需要包含 `control` 文件。 |
| 47 | +* `/usr/bin/`: 包含启动脚本(推荐用于通过命令行启动程序)。 |
| 48 | +* `/usr/lib/myprogram/`: 所有由 `dotnet publish` 生成的文件存放的位置。 |
| 49 | +* `/usr/share/applications/`: 存放桌面快捷方式的文件夹。 |
| 50 | +* `/usr/share/pixmaps/` 和 `/usr/share/icons/hicolor/**`: 应用程序图标所在的文件夹。 |
| 51 | + |
| 52 | +:::info |
| 53 | + |
| 54 | +`/usr/share/icons/hicolor/**` 是可选的,即使没有这些图片,你的应用程序图标也可以显示在桌面上,但建议为更好的区分度来提供它们。 |
| 55 | +::: |
| 56 | + |
| 57 | +### 2) 创建`control` 文件 |
| 58 | + |
| 59 | +`control` 文件放在 `DEBIAN` 文件夹中。 |
| 60 | + |
| 61 | +这个文件描述了程序的一般方面,如名称、版本、类别、依赖项、维护者、处理器架构和许可证。[Debian 文档](https://www.debian.org/doc/debian-policy/ch-controlfields.html) 提供了文件中所有可能字段的更详细描述。 |
| 62 | + |
| 63 | +:::tip[作者提示] |
| 64 | + |
| 65 | +不必过于担心填写所有可能的字段,大多数字段不是必需的。本教程旨在制作一个“够用就行”的 Debian 包。 |
| 66 | +::: |
| 67 | + |
| 68 | +.NET 依赖项可以通过运行 `apt show dotnet-runtime-deps-8.0`(后缀根据其他 .NET 版本变化)列出;它们将出现在以 *Depends: ...* 开头的行中。你也可以在 [.NET Core 仓库](https://github.com/dotnet/core/blob/main/release-notes/8.0/linux-packages.md) 中查看它们。 |
| 69 | + |
| 70 | +Avalonia 所需的依赖项是:`libx11-6, libice6, libsm6, libfontconfig1`。 |
| 71 | + |
| 72 | +总的来说,所有 .NET 和 Avalonia 依赖项都是必需的,再加上你的应用程序特定的任何其他依赖项。 |
| 73 | + |
| 74 | +下面是一个简单的 `control` 文件示例。 |
| 75 | + |
| 76 | +``` |
| 77 | +Package: myprogram |
| 78 | +Version: 3.1.0 |
| 79 | +Section: devel |
| 80 | +Priority: optional |
| 81 | +Architecture: amd64 |
| 82 | +Installed-Size: 68279 |
| 83 | +Depends: libx11-6, libice6, libsm6, libfontconfig1, ca-certificates, tzdata, libc6, libgcc1 | libgcc-s1, libgssapi-krb5-2, libstdc++6, zlib1g, libssl1.0.0 | libssl1.0.2 | libssl1.1 | libssl3, libicu | libicu74 | libicu72 | libicu71 | libicu70 | libicu69 | libicu68 | libicu67 | libicu66 | libicu65 | libicu63 | libicu60 | libicu57 | libicu55 | libicu52 |
| 84 | +Maintainer: Ken Lee <[email protected]> |
| 85 | +Homepage: https://github.com/kenlee/myprogram |
| 86 | +Description: This is MyProgram, great for doing X. |
| 87 | +Copyright: 2022-2024 Ken Lee <[email protected]> |
| 88 | +``` |
| 89 | + |
| 90 | +### 3) 创建启动脚本 |
| 91 | + |
| 92 | +推荐这个步骤有两个原因:首先可以减少桌面快捷方式的复杂性,其次使你的应用程序可以从终端运行。 |
| 93 | + |
| 94 | +启动脚本的文件名最好是 `myprogram`(不带 `.sh` 扩展名),这样当用户在终端中输入 "myprogram" 时,他/她将启动你的程序。 |
| 95 | + |
| 96 | +**myprogram_executable** 文件通常与其 .NET 项目的名称相同,例如,如果你的 Avalonia .csproj 项目名为 *MyProgram.Desktop*,那么由 dotnet publish 生成的主可执行文件将是 `MyProgram.Desktop`。 |
| 97 | + |
| 98 | +启动脚本示例: |
| 99 | + |
| 100 | +```sh |
| 101 | +#!/bin/bash |
| 102 | + |
| 103 | +# 使用 exec 以避免包装脚本作为一个单独的进程存在 |
| 104 | +# "$@" 用于将命令行参数传递给应用程序 |
| 105 | + |
| 106 | +exec /usr/lib/myprogram/myprogram_executable "$@" |
| 107 | +``` |
| 108 | + |
| 109 | +### 4) 创建桌面快捷方式 |
| 110 | + |
| 111 | +桌面快捷方式文件遵循 [FreeDesktop 规范](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#recognized-keys)。Arch Linux Wiki 也有一些好的[Arch Linux规范](https://wiki.archlinux.org/title/Desktop_entries)。 |
| 112 | + |
| 113 | +下面是一个桌面快捷方式文件的示例。 |
| 114 | + |
| 115 | +``` |
| 116 | +[Desktop Entry] |
| 117 | +Name=MyProgram |
| 118 | +Comment=MyProgram, great for doing X |
| 119 | +Icon=myprogram |
| 120 | +Exec=myprogram |
| 121 | +StartupWMClass=myprogram |
| 122 | +Terminal=false |
| 123 | +Type=Application |
| 124 | +Categories=Development |
| 125 | +GenericName=MyProgram |
| 126 | +Keywords=keyword1; keyword2; keyword3 |
| 127 | +``` |
| 128 | + |
| 129 | +:::tip |
| 130 | + |
| 131 | +如果你想要你的应用程序可以打开文件,请在 `Exec` 行的末尾,`myprogram` 之后附加 **%F**;如果它应该打开 URL,则附加 **%U**。 |
| 132 | + |
| 133 | +::: |
| 134 | + |
| 135 | +### 5) 添加 hicolor 图标(可选) |
| 136 | + |
| 137 | +Hicolor 图标遵循如下文件夹结构。 |
| 138 | + |
| 139 | +[这篇博客](https://martin.hoppenheit.info/blog/2016/where-to-put-application-icons-on-linux/) 建议我们根据 [Debian Menu System 文档](https://www.debian.org/doc/packaging-manuals/menu.html/ch3.html#s3.7) 和 [FreeDesktop 文档](https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-0.11.html#install_icons),将图标放在 `hicolor` 和 `pixmaps` 目录中。 |
| 140 | +``` |
| 141 | +├── icons |
| 142 | +│ └── hicolor |
| 143 | +│ ├── 128x128 |
| 144 | +│ │ └── apps |
| 145 | +│ │ └── myprogram.png |
| 146 | +│ ├── 16x16 |
| 147 | +│ │ └── apps |
| 148 | +│ │ └── myprogram.png |
| 149 | +│ ├── 256x256 |
| 150 | +│ │ └── apps |
| 151 | +│ │ └── myprogram.png |
| 152 | +│ ├── 32x32 |
| 153 | +│ │ └── apps |
| 154 | +│ │ └── myprogram.png |
| 155 | +│ ├── 48x48 |
| 156 | +│ │ └── apps |
| 157 | +│ │ └── myprogram.png |
| 158 | +│ ├── 512x512 |
| 159 | +│ │ └── apps |
| 160 | +│ │ └── myprogram.png |
| 161 | +│ ├── 64x64 |
| 162 | +│ │ └── apps |
| 163 | +│ │ └── myprogram.png |
| 164 | +│ └── scalable |
| 165 | +│ └── apps |
| 166 | +│ └── myprogram.svg |
| 167 | +``` |
| 168 | + |
| 169 | +### 6) 编译 `.deb` 包 |
| 170 | + |
| 171 | +```sh |
| 172 | +# 对于 x64 架构,建议的后缀是 amd64。 |
| 173 | +dpkg-deb --root-owner-group --build ./staging_folder/ "./myprogram_${versionName}_amd64.deb" |
| 174 | +``` |
| 175 | + |
| 176 | +## 完整的 Linux shell 脚本示例 |
| 177 | + |
| 178 | +```bash |
| 179 | +#!/bin/bash |
| 180 | + |
| 181 | +# 清理 |
| 182 | +rm -rf ./out/ |
| 183 | +rm -rf ./staging_folder/ |
| 184 | + |
| 185 | +# .NET 发布 |
| 186 | +# 推荐使用 self-contained 发布,这样用户不需要安装 .NET运行时 |
| 187 | +dotnet publish "./src/MyProgram.Desktop/MyProgram.Desktop.csproj" \ |
| 188 | + --verbosity quiet \ |
| 189 | + --nologo \ |
| 190 | + --configuration Release \ |
| 191 | + --self-contained true \ |
| 192 | + --runtime linux-x64 \ |
| 193 | + --output "./out/linux-x64" |
| 194 | + |
| 195 | +# 暂存目录 |
| 196 | +mkdir staging_folder |
| 197 | + |
| 198 | +# Debian control文件 |
| 199 | +mkdir ./staging_folder/DEBIAN |
| 200 | +cp ./src/MyProgram.Desktop.Debian/control ./staging_folder/DEBIAN |
| 201 | + |
| 202 | +# 启动脚本 |
| 203 | +mkdir ./staging_folder/usr |
| 204 | +mkdir ./staging_folder/usr/bin |
| 205 | +cp ./src/MyProgram.Desktop.Debian/myprogram.sh ./staging_folder/usr/bin/myprogram |
| 206 | +chmod +x ./staging_folder/usr/bin/myprogram # 设置启动脚本的执行权限 |
| 207 | + |
| 208 | +# 其他文件 |
| 209 | +mkdir ./staging_folder/usr/lib |
| 210 | +mkdir ./staging_folder/usr/lib/myprogram |
| 211 | +cp -f -a ./out/linux-x64/. ./staging_folder/usr/lib/myprogram/ # 从publish目录复制所有文件 |
| 212 | +chmod -R a+rX ./staging_folder/usr/lib/myprogram/ # 设置所有文件的读权限 |
| 213 | +chmod +x ./staging_folder/usr/lib/myprogram/myprogram_executable # 设置主可执行文件的执行权限 |
| 214 | + |
| 215 | +# 桌面快捷方式 |
| 216 | +mkdir ./staging_folder/usr/share |
| 217 | +mkdir ./staging_folder/usr/share/applications |
| 218 | +cp ./src/MyProgram.Desktop.Debian/MyProgram.desktop ./staging_folder/usr/share/applications/MyProgram.desktop |
| 219 | + |
| 220 | +# 桌面图标 |
| 221 | +# 一个 1024px x 1024px 的 PNG 文件,类似于 VS Code 使用的图标 |
| 222 | +mkdir ./staging_folder/usr/share/pixmaps |
| 223 | +cp ./src/MyProgram.Desktop.Debian/myprogram_icon_1024px.png ./staging_folder/usr/share/pixmaps/myprogram.png |
| 224 | + |
| 225 | +# Hicolor 图标 |
| 226 | +mkdir ./staging_folder/usr/share/icons |
| 227 | +mkdir ./staging_folder/usr/share/icons/hicolor |
| 228 | +mkdir ./staging_folder/usr/share/icons/hicolor/scalable |
| 229 | +mkdir ./staging_folder/usr/share/icons/hicolor/scalable/apps |
| 230 | +cp ./misc/myprogram_logo.svg ./staging_folder/usr/share/icons/hicolor/scalable/apps/myprogram.svg |
| 231 | + |
| 232 | +# 制作 .deb 文件 |
| 233 | +dpkg-deb --root-owner-group --build ./staging_folder/ ./myprogram_3.1.0_amd64.deb |
| 234 | +``` |
| 235 | + |
| 236 | +## 安装 |
| 237 | + |
| 238 | +```sh |
| 239 | +sudo apt install ./myprogram_3.1.0_amd64.deb |
| 240 | +``` |
| 241 | + |
| 242 | +## 卸载 / 删除 |
| 243 | + |
| 244 | +```sh |
| 245 | +sudo apt remove myprogram |
| 246 | +``` |
| 247 | + |
| 248 | +## 第三方打包工具(适用于 Debian / Ubuntu) |
| 249 | + |
| 250 | +* https://github.com/quamotion/dotnet-packaging |
| 251 | +* https://github.com/SuperJMN/DotnetPackaging |
| 252 | +* https://github.com/kuip |
0 commit comments