Rust 工具的打包和分发

如果您确信您的程序已准备好供其他人使用,那么现在该打包并发布它了!

有几种方法,我们将从“最快的设置”到“对用户最方便”的三个方法进行介绍。

最快捷:cargo publish

发布应用程序的最简单方法是使用 cargo。您还记得我们如何将外部依赖项添加到项目中吗?Cargo 从其默认的“crate 仓库”crates.io 下载它们。使用 cargo publish,您也可以将 crate 发布到 crates.io。这适用于所有 crate,包括包含二进制目标的 crate。

将 crate 发布到 crates.io 非常简单:如果您还没有,请在 crates.io 上创建一个帐户。目前,这是通过在 GitHub 上授权您来完成的,因此您需要拥有一个 GitHub 帐户(并在那里登录)。接下来,您需要在本地机器上使用 cargo 登录。为此,请访问您的 crates.io 帐户页面,创建一个新令牌,然后运行 cargo login <your-new-token>。您只需要在每台计算机上执行一次此操作。您可以在 cargo 的 发布指南 中了解更多信息。

现在 cargo 和 crates.io 都认识您了,您就可以发布 crate 了。在您匆忙发布新 crate(版本)之前,最好再次打开您的 Cargo.toml,并确保您添加了必要的元数据。您可以在 cargo 清单格式 的文档中找到可以设置的所有可能字段。以下是一些常见条目的简要概述

[package]
name = "grrs"
version = "0.1.0"
authors = ["Your Name <[email protected]>"]
license = "MIT OR Apache-2.0"
description = "A tool to search files"
readme = "README.md"
homepage = "https://github.com/you/grrs"
repository = "https://github.com/you/grrs"
keywords = ["cli", "search", "demo"]
categories = ["command-line-utilities"]

如何从 crates.io 安装二进制文件

我们已经了解了如何将 crate 发布到 crates.io,您可能想知道如何安装它。与库不同,库在您运行 cargo build(或类似命令)时,cargo 会为您下载并编译它们,您需要明确告诉它安装二进制文件。

这是使用 cargo install <crate-name> 完成的。它默认会下载 crate,编译它包含的所有二进制目标(在“release”模式下,因此可能需要一段时间),并将它们复制到 ~/.cargo/bin/ 目录中。(确保您的 shell 知道在那里查找二进制文件!)

也可以从 git 存储库安装 crate,只安装 crate 的特定二进制文件,并指定一个备用目录来安装它们。查看 cargo install --help 以获取详细信息。

何时使用它

cargo install 是安装二进制 crate 的一种简单方法。对于 Rust 开发人员来说,它非常方便,但有一些明显的缺点:由于它总是从头开始编译您的源代码,因此您的工具的用户需要在其机器上安装 Rust、cargo 和项目所需的所有其他系统依赖项。编译大型 Rust 代码库也可能需要一些时间。

最适合用于分发针对其他 Rust 开发人员的工具。例如:许多 cargo 子命令,如 cargo-treecargo-outdated,都可以使用它来安装。

分发二进制文件

Rust 是一种编译为本地代码的语言,默认情况下会静态链接所有依赖项。当您在包含名为 grrs 的二进制文件的项目上运行 cargo build 时,您最终会得到一个名为 grrs 的二进制文件。试试看:使用 cargo build,它将是 target/debug/grrs,当您运行 cargo build --release 时,它将是 target/release/grrs。除非您使用明确需要在目标系统上安装外部库的 crate(例如使用系统的 OpenSSL 版本),否则此二进制文件将只依赖于常见的系统库。这意味着,您将该文件发送给运行与您相同的操作系统的用户,他们就可以运行它。

这已经非常强大!它解决了我们刚刚看到的 cargo install 的两个缺点:不需要在用户的机器上安装 Rust,并且他们可以立即运行二进制文件,而不是花费一分钟的时间进行编译。

因此,正如我们所见,cargo build 已经为我们构建了二进制文件。唯一的问题是,这些二进制文件不能保证在所有平台上都能正常工作。如果您在 Windows 机器上运行 cargo build,默认情况下您不会得到一个在 Mac 上工作的二进制文件。有没有办法自动为所有有趣的平台生成这些二进制文件?

在 CI 上构建二进制发行版

如果您的工具是开源的,并且托管在 GitHub 上,那么设置一个免费的 CI(持续集成)服务,如 Travis CI,非常容易。(还有其他服务也适用于其他平台,但 Travis 非常流行。)这基本上是在您每次将更改推送到存储库时,在虚拟机中运行设置命令。这些命令是什么,以及它们在哪些类型的机器上运行,都是可以配置的。例如:一个好主意是在安装了 Rust 和一些常见构建工具的机器上运行 cargo test。如果失败,您就知道最近的更改中存在问题。

我们也可以使用它来构建二进制文件并将其上传到 GitHub!事实上,如果我们运行 cargo build --release 并将二进制文件上传到某个地方,我们应该就完成了,对吧?不完全是。我们还需要确保我们构建的二进制文件与尽可能多的系统兼容。例如,在 Linux 上,我们可以不为当前系统编译,而是为 x86_64-unknown-linux-musl 目标编译,以不依赖于默认的系统库。在 macOS 上,我们可以将 MACOSX_DEPLOYMENT_TARGET 设置为 10.7,以只依赖于 10.7 及更早版本中存在的系统功能。

您可以看到一个使用这种方法构建二进制文件的示例 这里,适用于 Linux 和 macOS,以及 这里,适用于 Windows(使用 AppVeyor)。

另一种方法是使用预构建的(Docker)镜像,其中包含构建二进制文件所需的所有工具。这使我们能够轻松地针对更多奇特的平台。The trust 项目包含您可以包含在项目中的脚本以及有关如何设置它的说明。它还包括使用 AppVeyor 对 Windows 的支持。

如果您更愿意在本地设置它,并在自己的机器上生成发行版文件,请查看 trust。它在内部使用 cross,它与 cargo 类似,但会将命令转发到 Docker 容器内的 cargo 进程。镜像的定义也包含在 cross 的存储库 中。

如何安装这些二进制文件

您将用户指向您的发行版页面,该页面可能看起来 像这样,他们可以下载我们刚刚创建的工件。我们刚刚生成的发布工件没有什么特别之处:最终,它们只是包含我们二进制文件的存档文件!这意味着您的工具的用户可以使用浏览器下载它们,解压缩它们(通常会自动发生),并将二进制文件复制到他们喜欢的任何地方。

这确实需要一些手动“安装”程序的经验,因此您需要在 README 文件中添加一个部分,说明如何安装此程序。

何时使用它

通常情况下,拥有二进制发行版是一个好主意,几乎没有缺点。它并不能解决用户必须手动安装和更新工具的问题,但他们可以快速获得最新版本的发布版,而无需安装 Rust。

除了二进制文件之外,还需要打包什么

现在,当用户下载我们的发布版构建时,他们会得到一个 .tar.gz 文件,其中只包含二进制文件。因此,在我们的示例项目中,他们只会得到一个可以运行的 grrs 文件。但是,我们存储库中还有一些其他文件,他们可能希望拥有这些文件。例如,告诉他们如何使用此工具的 README 文件,以及许可证文件。由于我们已经拥有它们,因此很容易添加它们。

还有一些更有趣的文件,特别是对于命令行工具来说很有意义:我们除了 README 文件之外,还可以提供一个手册页,以及将可能的标志的完成添加到 shell 的配置文件?您可以手动编写这些文件,但 clap(我们使用的参数解析库,clap 基于它)有一种方法可以为我们生成所有这些文件。有关更多详细信息,请参见 此深入章节

将您的应用程序添加到软件包仓库中

我们之前看到的两种方法都不是在机器上安装软件的典型方式。特别是使用大多数操作系统上的全局包管理器安装的命令行工具。对用户来说,优势显而易见:无需考虑如何安装程序,如果可以像安装其他工具一样安装,那就更好了。这些包管理器还允许用户在有新版本可用时更新他们的程序。

遗憾的是,支持不同的系统意味着你必须了解这些不同系统的工作原理。对于一些系统来说,这可能和在你的仓库中添加一个文件一样简单(例如,为 macOS 的 brew 添加一个 Formula 文件,就像 这个),但对于其他系统,你通常需要自己提交补丁并将你的工具添加到他们的仓库中。有一些有用的工具,比如 cargo-bundlecargo-debcargo-aur,但描述它们的工作原理以及如何为这些不同的系统正确打包你的工具超出了本章的范围。

相反,让我们看看一个用 Rust 编写的工具,它在许多不同的包管理器中都有提供。

一个例子:ripgrep

ripgrepgrep/ack/ag 的替代品,是用 Rust 编写的。它非常成功,并且为许多操作系统打包:看看 其 README 中的“安装”部分

请注意,它列出了几种不同的安装方式:它首先链接到包含二进制文件的 GitHub 发布页面,这样你就可以直接下载它们;然后它列出了如何使用一堆不同的包管理器来安装它;最后,你也可以使用 cargo install 来安装它。

这似乎是一个非常好的主意:不要选择这里介绍的方法中的任何一种,而是从 cargo install 开始,添加二进制发布,最后开始使用系统包管理器分发你的工具。