-.github/workflows/build-and-test.yml——为一系列功能、平台和工具包的组合建立和运行测试()
-.github/workflows/publish.yml——为符合v*模式的标记发布建立和运行测试,将crate发布到crates.io()
清单2.4显示了建立作业参数,包括功能、通道和平台矩阵。这种作业使用brndnmtthws/rust-actionGitHubAction()来设置Rust环境。
以下列表展示了建立、测试、格式化和运行Clippy(在第三章讨论过)的各个步骤。
以下列表显示了发布我们的crates所需的步骤。
注意:GitHub的Actions目前不支持在使用独立阶段时(比如,在进行布署阶段之前等待建立阶段成功)设置发布门控。为了实现这一点,你必须在推送任何标签之前验证建立阶段是否成功。
在最终的发布步骤中,你须要为提供一个令牌。这可以通过创建一个crates.io帐户,从crates.io帐户设置中生成一个令牌,之后将其添加到GitHub库房设置中的GitHub秘密储存来完成。
2.6链接到C语言库
有时你可能会发觉自己须要使用非Rust代码中的外部库。这一般是通过外部函数插口(FFI)来实现的。FFI是一种相当标准的方法来实现跨语言的互操作性。我们将在第4章中更详尽地再度讨论FFI。
让我们通过一个简单的事例来演示怎么从一个十分流行的C语言库:zlib中调用函数。选择zlib是由于它几乎无处不在,这个事例应当可以在任何安装了zlib的平台上轻松地直接运行。我们将在Rust中实现两个函数:compress()和uncompress()。以下是zlib库中的定义(为了本示例的目的已然简化)。
首先什么是linux,我们将使用extern在Rust中定义C插口。
我们早已将libc作为依赖项包含在内,它在Rust中提供了与C兼容的类型。
当你链接到C库时,你将希望使用来自libc的类型以保持兼容性。若果不这样做可能会引起未定义的行为。我们定义了来自zlib的三个实用函数:compress、compressBound和uncompress。
链接属性告诉rustc我们须要将这种函数链接到zlib。这相当于在链接时添加-lz标志。在macOS上,你可以使用otool-L来验证这一点,如下所示的代码(在Linux上,使用ldd,在Windows上,使用dumpbin):
接出来,我们须要编撰Rust函数来封装C函数,便于从Rust代码中调用。在Rust中直接调用C函数被觉得是不安全的,因而你必须将调用封装在一个unsafe{}块中。
后面函数的zlib_uncompress版本几乎相同,不仅我们须要为目的地缓冲区提供自己的厚度。最后,我们可以展示如下列表所示的使用技巧。
处理FFI(外部函数插口)时最大的挑战是一些CAPI的复杂性以及映射各种类型和函数。为了解决这个问题,你可以使用rustbindgen工具,这在第4章中有更详尽的讨论。
2.7二补码分发
Rust的二补码文件由给定平台的所有Rust依赖项组成,作为单一二补码文件——不包括C运行时——以及可能早已动态链接的任何非Rust库。你可以建立与C运行时静态链接的二补码文件,但默认情况下,这是可选的。为此,在分发Rust二补码文件时,你须要考虑是否希望静态链接C运行时或依赖系统的运行时。
这种二补码文件本身是平台依赖的。它们可以为不同的平台进行交叉编译,但你不能将不同的构架或平台与同一个Rust二补码文件混和。为基于Intel的x64-64CPU编译的二补码文件不会在基于ARM的平台(如AArch64,亦称为ARMv8)上运行,除非使用某种类型的仿真。为macOS编译的二补码文件不会在Linux上运行。
一些操作系统供应商,非常是苹果的macOS,为其他CPU平台提供仿真。可以使用苹果的Rosetta工具手动在ARM上运行x86-64二补码文件,这应当会手动发生。有关macOS二补码分发的更多详尽信息linux ldd -r,请查阅苹果的开发者文档,网址为。在大多数情况下,你会想坚持使用你正在使用的平台的默认设置,但也有例外。
假如你来自像Go这样的语言,你可能早已习惯了分发预编译的二补码文件而毋须害怕C运行时。与Go不同,Rust须要C运行时,但是默认使用动态链接。
2.7.1跨平台编译
你可以使用Cargo来为不同的目标平台交叉编译二补码文件linux ldd -r,但前提是该目标平台有编译器支持。比如,你可以在Windows上轻松编译Linux二补码文件,但在Linux上编译Windows二补码文件就不这么容易了(但并非不可能)。
你可以使用rustup来列举你的寄主平台上可用的目标平台。
$ rustup target list
rustup target list
aarch64-apple-darwin
aarch64-apple-ios
aarch64-fuchsia
aarch64-linux-android
aarch64-pc-windows-msvc
..
你可以使用rustuptargetadd来安装不同的目标,之后使用cargobuild--target来为特定目标建立。比如,在我的基于Intel的macOS机器上,我可以运行以下命令来编译AArch64(M1芯片使用的)的二补码文件:
但是,假若我尝试运行这个二补码文件,它会失败:
$ ./target/aarch64-apple-darwin/debug/simple-project-bash: ./target/aarch64-apple-darwin/debug/simple-project: Bad CPU type in
executable
假如我就能访问一台AArch64构架的macOS设备,我可以将这个二补码文件复制到那台机器上,但是在哪里成功运行它。
2.7.2建立静态链接的二补码文件
普通的Rust二补码文件包含了所有编译后的依赖项,不仅C运行时库。在Windows和macOS上,分发预编译的二补码文件并链接到操作系统的C运行时库是正常的。但是,在Linux上,大多数包是由发行版的维护者从源代码编译的,发行版负责管理C运行时。
当在Linux上分发Rust二补码文件时,你可以按照你的偏好选择使用glibc或musl。Glibc是大多数Linux发行版上的默认C库运行时。但是,当我想分发时,我推荐静态链接到musl。
Linux二补码文件为了最大的可移植性。实际上,在尝试在个别目标上静态链接时,Rust假定你想要使用musl。
注意:在个别情况下,musl与glibc的行为略有不同。这种差别在muslwiki上有文档记录,网址为。
你可以通过这样的方法使用target-feature标志指示rustc使用静态C运行时:
在这段代码中,我们通过RUSTFLAGS环境变量将-Ctarget-feature=+crt-static传递给rustc,这将被Cargo解释并传递给rustc。
我们使用以下代码在x86-64Linux上静态链接musl:
要明晰禁用静态链接,请使用RUSTFLAGS=”-Ctarget-feature=-crt-static”代替(通过将减号[+]改为加号[-])。这可能对于默认静态链接的目标是可取的——如果不确定,请使用默认参数。
或则,你可以通过~/.cargo/config指定Cargo的rustc标志:
[target.x86_64-pc-windows-msvc]
rustflags = ["-Ctarget-feature=+crt-static"]
当添加到~/.cargo/config中时,上述代码将指示rustc在使用x86_64-pc-windows-msvc目标时静态链接。
2.8文档化Rust项目
Rust默认随Rust一起提供的代码文档工具称为rustdoc。
假如你使用过其他项目中的代码文档工具(比如,Javadoc、docstring或RDoc),这么使用rustdoc将会很自然。
使用rustdoc如同在代码中添加注释并生成文档一样简单。
让我们快速过一个示例。首先,创建一个库:
如今,让我们编辑src/lib.rs文件来添加一个名为mult的函数,它接受两个整数(a和b)并将它们相加。我们还将添加一个测试:
我们还没有添加任何文档。在我们添加之前,让我们使用Cargo生成一些空文档。
如今,你应当能在目标目录下看见生成的HTML文档。假如你想在浏览器中打开这种文档,可以打开target/doc/src/rustdoc_example/lib.rs.html来查看它们。结果应当看上去像图2.1。默认的文档是空的,但你可以看见文档中列举了公共函数mult。
接出来,让我们给我们的项目添加一个编译器属性和一些文档。更新src/lib.rspuppy linux,使其看上去像这样:
TIPRust文档使用CommonMark格式编撰,这是Markdown的一个子集。CommonMark的参考可以在找到。
假如你重新运行cargodoc并用新创建的代码文档打开它在浏览器中,你将见到图2.2所示的输出。对于发布到crates.io的crates,有一个配套的rustdoc网站,它会手动为crates生成并托管文档,网址为。诸如,dryoccrate的文档可以在找到。
在已记录的库中,你应当更新Cargo.toml以包含文档属性,该属性链接到项目的文档。这对于这些人在crates.io上找寻资源的人来说是有帮助的。诸如,dryoccrate在Cargo.toml中有以下内容:
[package]
name = "dryoc"
documentation = "https://docs.rs/dryoc"
你不须要做任何其他事情就可以使用docs.rs。当新版本发布到crates.io时,网站会手动生成更新的文档。