跳转到主要内容

使用Cargo子命令轻松创建Debian软件包(.deb)

项目描述

Cargo项目的Debian软件包

这是一个Cargo辅助命令,可以自动从Cargo项目创建二进制Debian软件包 (.deb)。

注意 从v2.0.0版本开始,deb软件包版本将带有"-1"后缀。您可以通过添加--deb-revision=""标志或revision = ""在Cargo元数据中禁用此功能。默认后缀是为了符合Debian的打包标准。

安装

rustup update   # Debian's Rust is too outdated, use rustup.rs
cargo install cargo-deb

需要Rust 1.63+,可选dpkgdpkg-devliblzma-dev。与Ubuntu兼容。如果LZMA依赖项让您头疼,请尝试使用cargo install cargo-deb --no-default-features

如果您遇到编译错误,请运行rustup update!如果运行rustup update时出错,请卸载您的rust/cargo软件包,并安装官方Rust

使用

cargo deb

在Rust项目的根目录下运行cargo deb后,Debian软件包将创建在target/debian/<project_name>_<version>-1_<arch>.deb(或您可以使用--output选项更改位置)。此软件包可以使用dpkg -i target/debian/*.deb进行安装。

默认情况下,调试符号从主二进制文件中移除,除非在Cargo.toml中设置了[profile.release] debug = true。如果运行了cargo deb --separate-debug-symbols,调试符号将作为单独的文件打包,并安装在/usr/lib/debug/<path-to-binary>.debug

cargo deb --install构建并安装项目到全局。

配置

从带有二进制文件的Cargo项目中创建基本包不需要进行配置。此命令从Cargo.toml文件中获取所需的基本信息。它使用Cargo字段:nameversionlicenselicense-filedescriptionreadmehomepagerepository

为了创建更完整的Debian包,您还可以定义一个新的表[package.metadata.deb],其中包含maintainercopyrightlicense-filechangelogdependsconflictsbreaksreplacesprovidesextended-description/extended-description-filesectionpriorityassets

对于包含一个或多个systemd单元文件的Debian包,您还可以定义一个新的(内联)表[package.metadata.deb.systemd-units],以便自动将单元文件添加为资产,并正确安装单元。 Systemd集成

[package.metadata.deb]选项

所有内容都是可选的

  • name:Debian包的名称。如果不存在,则使用crate的名称。
  • maintainer:维护Debian打包的人。如果不存在,则使用第一个作者。
  • copyright:软件的版权授予谁和何时。如果不存在,则使用作者列表。
  • license-file:包含许可证文件位置和顶部要跳过的行数的2元素数组。如果不存在,则使用包级别的license-file
  • depends:项目的运行时依赖项。如果没有提供,或列表中包含$auto关键字时自动生成。
  • pre-depends:项目的预依赖项。默认为空。
  • recommends:项目的推荐依赖项。默认为空。
  • suggests:项目的建议依赖项。默认为空。
  • enhances:此包可以增强的包列表。默认为空。
  • conflictsbreaksreplacesprovides包转换控制。
  • extended-description:项目的扩展描述 —— 越详细越好。如果没有提供,则使用extended-description-file(见下文)或包的readme文件。
  • extended-description-file:包含项目扩展描述的文件。如果指定,当没有提供extended-description时使用。
  • revision:Debian包的附加版本(当包比项目更新得更频繁时)。默认为"1",但可以设置为空字符串以省略修订版。
  • section:软件所属的应用程序类别
  • priority:定义包是required还是optional
  • assets:要包含在包中的文件及其权限。如果没有指定资产,则从列出的二进制文件(复制到/usr/bin/)和包的readme文件(复制到usr/share/doc/…)中获取默认值。
    1. 每个资产的第一个参数是该资产在Rust项目中的位置。允许使用全局模式。您可以在资产路径中使用target/release/,即使Cargo配置了交叉编译或使用自定义CARGO_TARGET_DIR。目标目录路径将被自动纠正。
    2. 第二个参数是文件将被复制的位置。
      • 如果该参数以/结尾,则将推断目标是为文件复制的目录。
      • 否则,将推断在复制时源参数将被重命名。
    3. 第三个参数是要分配给该文件的权限(八进制字符串)。
  • merge-assets: 请参阅“高级用法”下的“合并资源”部分 查看“合并资源”
  • maintainer-scripts: 包含 templatespreinstpostinstprermpostrm 脚本的目录 脚本
  • conf-files: 配置文件列表,在包升级时,包管理系统不会覆盖这些文件。
  • triggers-file: dpkg 触发功能使用的触发控制文件的路径。
  • changelog: Debian 格式的 变更日志文件 的路径。
  • features: 当构建包时使用的 Cargo 功能 列表。
  • default-features: 是否使用除 features 列表之外的默认 crate 功能(默认 true)。
  • separate-debug-symbols: 是否保留调试符号,但将它们从可执行文件中删除,并保存到单独的文件中(默认 false)。
  • preserve-symlinks: 是否在资源文件中保留符号链接(默认 false)。
  • systemd-units: 自动安装 systemd 单元 的可选配置设置。

自定义 Cargo.toml 添加示例

[package.metadata.deb]
maintainer = "Michael Aaron Murphy <mmstickman@gmail.com>"
copyright = "2017, Michael Aaron Murphy <mmstickman@gmail.com>"
license-file = ["LICENSE", "4"]
extended-description = """\
A simple subcommand for the Cargo package manager for \
building Debian packages from Rust projects."""
depends = "$auto"
section = "utility"
priority = "optional"
assets = [
    ["target/release/cargo-deb", "usr/bin/", "755"],
    ["README.md", "usr/share/doc/cargo-deb/README", "644"],
]

高级用法

Debian 包可以使用多种不同的压缩格式,但目标系统可能仅支持其中的一些。当前默认格式是 xz,但为了支持新的格式,这可能在任何时候改变。可以使用 --compress-type 命令行选项显式指定格式。支持的格式是 "gzip" 和 "xz"。

--fast 标志使用更轻的压缩。适用于非常大的包或快速部署。

--compress-system 强制使用系统命令行工具进行数据压缩。

[package.metadata.deb.variants.$name]

一个 Cargo.toml 文件中可以有多个元数据的变体。使用 --variant=name 选择要使用的变体。变体中设置的选项将覆盖 [package.metadata.deb] 选项。它会自动调整包名。

合并资源

在定义一个变体时,也可以定义一个资源合并策略。

如果使用 merge-assets 选项,cargo-deb 将合并提供给该选项的资产列表与父资产列表。有三种合并策略,即 appendby.destby.src

  • merge-assets.append: 将此资产列表附加到父资产列表。
  • merge-assets.by.dest: 将此资产列表合并到父资产列表,基于目标路径连接。将替换源路径和权限。
  • merge-assets.by.src: 将此资产列表合并到父资产列表,基于源路径连接。将替换目标路径和权限。

注意:允许同时使用 appendby.* 选项,其中前者在后者之前应用。

merge-assets 示例

# Example parent asset list
[package.metadata.deb]
assets = [
    # binary
    ["target/release/example", "usr/bin/", "755"],
    # assets
    ["assets/*", "var/lib/example", "644"],
    ["target/release/assets/*", "var/lib/example", "644"],
    ["3.txt", "var/lib/example/3.txt", "644"],
    ["3.txt", "var/lib/example/merged.txt", "644"],
]

# Example merging by appending asset list
[package.metadata.deb.variants.mergeappend]
merge-assets.append = [
    ["4.txt", "var/lib/example/appended/4.txt", "644"]
]

# Example merging by `dest` path
[package.metadata.deb.variants.mergedest]
merge-assets.by.dest = [
    ["4.txt", "var/lib/example/merged.txt", "644"]
]

# Example merging by `src` path
[package.metadata.deb.variants.mergesrc]
merge-assets.by.src = [
    ["3.txt", "var/lib/example/merged-2.txt", "644"]
]

# Example merging by appending and by `src` path
[package.metadata.deb.variants.mergeappendandsrc]
merge-assets.append = [
    ["4.txt", "var/lib/example/appended/4.txt", "644"]
]
merge-assets.by.src = [
    ["3.txt", "var/lib/example/merged-2.txt", "644"]
]

[package.metadata.deb.systemd-units]

请参阅 systemd 集成.

交叉编译

cargo deb 支持交叉编译。可以在任何 Unix-like 主机上运行,包括 macOS,前提是已设置交叉编译的构建环境。

  • 交叉编译目标必须通过 rustup 安装(例如 rustup target add i686-unknown-linux-gnu)并且必须在宿主系统上安装(例如 apt-get install libc6-dev-i386)。请注意,RustDebian 的架构名称不同。有关支持值的列表,请参见 rustc --print target-list
  • 必须安装与 Linux 兼容的链接器和系统库(例如 glibc 或 musl),并使其对 Rust/Cargo 可用。
    • dpkg --add-architecture <debian 架构名称>
    • apt-get install pkg-config build-essential crossbuild-essential-<debian 架构名称>
  • Cargo 必须配置为使用交叉链接器
  • 使用 C 库的 Cargo 依赖项可能不会正常工作,除非您安装了目标系统的 sysroot 并为 pkg-config 配置了相应的路径。设置 PKG_CONFIG_ALLOW_CROSS=1 完全无法解决问题,反而只会使情况变得更糟。
    • apt-get install libssl-dev:<debian 架构名称>
  • 除非您为目标系统安装了 C 编译器并配置了适当的 CC_<target> 变量,否则构建 C 代码的 Cargo 依赖项可能不会正常工作。
    • export HOST_CC=gcc
    • export CC_x86_64_unknown_linux_gnu=/usr/bin/x86_64-linux-gnu-gcc(根据您的操作系统正确修改目标和路径)
  • 除非您安装了与目标兼容的版本并在 .cargo/config 中配置其路径(通过添加 [target.<target triple>] strip = { path = "…" } objcopy = { path = "…" }),否则解包可能无法正常工作。或者,可以使用 --no-strip

是的,这些要求很繁琐。您也可以尝试 crosscargo zigbuild,因为 Zig 在交叉编译方面做得更好,然后运行 cargo deb --target=… --no-build

cargo deb --target=i686-unknown-linux-gnu

交叉编译的存档保存在 target/<target triple>/debian/*.deb 中。实际存档路径将在成功后打印出来。

请注意,您无法使用交叉编译来构建 Debian 的旧版本。如果您需要支持比宿主系统更旧的 Debian 版本,请考虑使用容器或虚拟机,或者创建完全静态的 MUSL 二进制文件。

单独的调试信息

要获取调试符号,请在 Cargo.toml 中将 [profile.release] debug = true 设置为 true。故意不支持使用 dev 配置文件进行构建。

cargo deb --separate-debug-symbols

从可执行文件中删除调试符号并将它们作为单独的文件放置在 /usr/lib/debug 中。需要 GNU objcopy 工具。

自定义构建标志

如果您想自己处理构建过程,可以使用 cargo deb --no-build,这样 cargo-deb 命令将不会尝试重新构建您的项目。

cargo deb -- <cargo build flags>

-- 后的标志将传递给 cargo build,因此您可以使用例如 -Z--frozen--locked 这样的选项。请仅使用 cargo-deb 本地不支持的功能。

工作空间

Cargo-deb 理解工作空间,并在必要时可以构建工作空间中的所有 crate。但是,您必须选择一个 crate 作为包元数据的来源。您可以使用 -p crate_name--manifest-path=<path/to/Cargo.toml> 选择要构建的 crate。

自定义版本字符串

cargo deb --deb-version my-custom-version

覆盖从 Cargo 清单生成的版本字符串。它还会抑制 revision 选项。

lzma_stream_encoder_mt 的未定义引用错误

当系统提供的 LZMA 库版本过旧时会发生这种情况。尝试使用捆绑版本

cargo install cargo-deb --features=static-lzma

或通过设置 --compress-system 标志使用 xz 命令行工具。

项目详细信息


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分发

此版本没有可用的源分发文件。请参阅有关 生成分发归档 的教程。

构建分发

cargo_deb-2.0.0-py3-none-win_amd64.whl (1.9 MB 查看哈希值)

上传时间 Python 3 Windows x86-64

cargo_deb-2.0.0-py3-none-win32.whl (1.8 MB 查看哈希值)

上传时间 Python 3 Windows x86

cargo_deb-2.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.6 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.17+ x86-64

cargo_deb-2.0.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (2.6 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.17+ i686

cargo_deb-2.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.5 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.17+ ARM64

cargo_deb-2.0.0-py3-none-macosx_11_0_arm64.whl (2.0 MB 查看哈希值)

上传时间 Python 3 macOS 11.0+ ARM64

cargo_deb-2.0.0-py3-none-macosx_10_7_x86_64.whl (2.0 MB 查看哈希值)

上传时间 Python 3 macOS 10.7+ x86-64

支持者