openSUSE:Rust 软件打包
维护/创建使用 Rust 代码的软件包
依赖关系
您应该安装以下软件包来帮助构建 openSUSE 的 rust 软件包。
zypper install obs-service-cargo osc obs-service-tar obs-service-obs_scm \
obs-service-recompress obs-service-set_version obs-service-format_spec_file \
cargo cargo-packaging sudo
可选地,您可以安装 cargo lock2rpmprovides 来帮助生成许可证字符串。
cargo install cargo-lock2rpmprovides
如果您想缓存构建工件,从 osc-0.173.0 开始,您可以使用 sccache 来帮助减少重复构建时间。
# ~/.config/osc/oscrc sccache = 1 sccache_uri = file:///var/cache/obs_sccache.tar
或者,您可以使用网络 sccache
# ~/.config/osc/oscrc sccache = 1 sccache_uri = redis://127.0.0.1:6379
设置 redis 缓存超出了本页的范围。
创建软件包
您应该使用以下命令签出您的空白软件包
osc co home:<username>/package cd home:<username>/package
一个 rust 软件包的骨架 RPM 规范文件是
Name: hellorust # This will be set by osc services, that will run after this. Version: 0.0.0 Release: 0 Summary: A hello world with a number of the day printer # If you know the license, put it's SPDX string here. # Alternately, you can use cargo lock2rpmprovides to help generate this. License: Unknown Url: https://github.com/Firstyear/hellorust Source0: %{name}-%{version}.tar.zst Source1: registry.tar.zst # Pull in the latest rust/cargo toolchain BuildRequires: cargo # This contains rpm macros to assist with building BuildRequires: cargo-packaging # Disable this line if you wish to support all platforms. # In most situations, you will likely only target tier1 arches for user facing components. ExclusiveArch: %{rust_tier1_arches} %description A hello world with a number of the day printer. %prep # The number passed to -a (a stands for "after") should be equivalent to the Source tag number # of the vendor tarball, 1 in this case (from Source1). %autosetup -p1 -a1 # Remove exec bits to prevent an issue in fedora shebang checking. Uncomment only if required. # find vendor -type f -name \*.rs -exec chmod -x '{}' \; %build export CARGO_HOME=$PWD/.cargo %{cargo_build} %install # using cargo_install (only supports bindir) export CARGO_HOME=$PWD/.cargo %{cargo_install} # manual process, this can place binaries in other directories like sbindin # install -D -d -m 0755 %{buildroot}%{_bindir} # install -m 0755 %{_builddir}/%{name}-%{version}/target/release/%{name} %{buildroot}%{_bindir}/%{name} %check export CARGO_HOME=$PWD/.cargo %{cargo_test} %files %license LICENSE-FILE %{_bindir}/%{name} %changelog
有一些注释区域您需要填写和检查。请注意,如果您使用 %{cargo_install},%{cargo_build} 是多余的,因为 %{cargo_install} 将同时重建和安装。
一些项目可能需要自定义 rust 标志作为构建参数,可以使用以下变量在规范文件的开头设置。
%define __rustflags --cfg tokio_unstable
但是接下来我们将创建一个服务文件,允许 OBS 帮助我们获取源代码并将它们打包给我们。这应该放在一个名为 _service 的文件中
<services>
<service mode="manual" name="tar_scm">
<param name="url">https://github.com/Firstyear/hellorust.git</param>
<param name="versionformat">@PARENT_TAG@~@TAG_OFFSET@</param>
<param name="scm">git</param>
<param name="revision">v0.1.1</param>
<param name="match-tag">*</param>
<param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param>
<param name="versionrewrite-replacement">\1</param>
<param name="changesgenerate">enable</param>
<param name="changesauthor"> YOUR EMAIL HERE </param>
</service>
<service mode="manual" name="recompress">
<param name="file">*.tar</param>
<param name="compression">zst</param>
</service>
<service mode="manual" name="set_version"/>
<service name="cargo_vendor" mode="manual">
<param name="src">hellorust</param>
<param name="compression">zst</param>
<param name="update">true</param>
<param name="method">registry</param>
</service>
</services>
此服务文件为我们做了很多工作
- 它将根据我们设置的版本从 git 获取源代码。
- 它会将它们转换为 tar.zst 供我们使用。
- 它将更新 rpm 的 changelog,并设置规范文件中的正确版本。
- 它将下载我们的 rust 依赖项,然后将它们打包到 vendor.tar.zst 中。
- 它会扫描我们的项目是否存在已知的漏洞。这些来自 RustSec advisory 数据库。
您可以使用以下命令运行它
osc service ra
可选地,您现在可以运行 lock2rpmprovides
cd hellorust cargo lock2rpmprovides
这将生成一个您可以复制到规范文件中的许可证字符串。
然后您可以添加所需的源代码并提交到 OBS
osc add _service _servicedata cargo_config hellorust-0.1.1~git0.db340ad.tar.zst hellorust.spec vendor.tar.zst osc ci
如果您在构建软件包时遇到任何提及 crate 依赖项冲突的问题,您可以禁用自动更新依赖项,如下所示
<param name="update">false</param>
看看这是否可以解决问题。因为 git forge 上的 crates 通常只会对较旧的 Cargo.lock 文件运行 CI,而不是最新的 semver 兼容依赖项。
从这里,您可以按照 如何为 Factory 贡献 指南进行操作。
使用 Cargo 工作区的项目
工作区是 Cargo 的一项功能,可以从同一个 git 树构建多个项目。您可以对规范进行以下更改以在同一个项目中构建它们
BuildRequires: cargo-packaging >= 1.2.0
[...]
%build
%{cargo_build} --all
[...]
%install
%{cargo_install -p project1}
%{cargo_install -p project2}
更新您的软件包
一旦您的软件包被接受,您可以使用以下步骤对其进行更新
osc bco devel:project/pkgname cd home:username:branches:devel:project/pkgname osc service ra osc status
然后检查更改,并 osc rm 任何旧文件,并 osc add 任何更新的源文件。
从那里您可以执行构建和 ci/sr
osc build osc ci osc results osc sr
修补已打包的 crates
有时有必要修补已打包的 crates,原因有很多,通常是因为尚未在上游版本中发布的 CVE。或者,如果您想修复 Leap 中较旧版本的 CVE。
虽然理论上您可以修改和重新打包您的 vendor-tarball,但我们尝试保持 vendor-tarball 不变,并使用补丁文件,以便清楚地了解我们修改了什么。
这有点棘手,但可以按以下方式进行
首先,手动或使用以下命令提取您的 sources- 和 vendor-tarballs
quilt setup your.spec
或者,如果您正在使用服务文件,则使用
osc service run obs_scm
但是请注意,您必须手动提取 vendor-tarball。
然后 cd 进入 source-dir。
现在您可以选择运行
cargo tree | less
以识别您需要更改/升级的任何子(子子)软件包。
根据您需要执行的操作,继续执行下面的相应说明。
强制使用更高版本的直接依赖项
假设我们有一个如下所示的依赖树
your_package v1.0 ├── dep_lvl_1 v4.4 ...
并且您想将 dep_lvl_1 升级到 v4.5
为此,您需要您的顶级 Cargo.toml 文件、如果存在 Cargo.lock 文件,以及 vendor/dep_lvl_1/ 放在某种版本控制下(quilt 可能不适合此用途,因为您可能事先不知道哪些文件会被更新 crate 修改)。
编辑您的 Cargo.toml 文件,以使 cargo 使用 v4.5 作为 dep_lvl_1。
使用以下命令验证
cargo tree | less
然后运行
cargo vendor
以更新 crate dep_lvl_1。
跳转到 所有步骤的最终步骤。
强制使用更高版本的子依赖项
假设我们有一个如下所示的依赖树
your_package v1.0 ├── dep_lvl_1 v4.4 │ ├── dep_lvl_2 v1.3 ...
并且您想将 dep_lvl_2 升级到 v1.4。
为此,您需要您的顶级 Cargo.toml 文件、如果存在 Cargo.lock 文件,以及 vendor/dep_lvl_1/Cargo.toml 和 vendor/dep_lvl_2/ 放在某种版本控制下(quilt 可能不适合此用途,因为您可能事先不知道哪些文件会被更新 crate 修改)。
编辑您要更改的 Cargo.toml 文件
vi vendor/dep_lvl_1/Cargo.toml
并找到请求 dep_lvl_2 的位置。相应地将版本更改为 v1.4。
添加到顶级 Cargo.toml 文件
[patch.crates-io]
dep_lvl_1 = { path="vendor/dep_lvl_1" }
运行
cargo vendor
以下载 dep_lvl_2 的新版本
跳转到 所有步骤的最终步骤。
实际修改依赖项代码
假设我们有一个如下所示的依赖树
your_package v1.0 ├── dep_lvl_1 v4.4 │ ├── dep_lvl_2 v1.3 ...
并且您想直接修改 dep_lvl_2 的代码。
为此,您需要您的顶级 Cargo.toml 文件、如果存在 Cargo.lock 文件,以及您需要编辑的文件,例如 vendor/dep_lvl_2/src/lib.rs 放在某种版本控制下。
编辑您要更改的源文件
vi vendor/dep_lvl_2/src/lib.rs
添加到顶级 Cargo.toml 文件
[patch.crates-io]
dep_lvl_2 = { path="vendor/dep_lvl_2" }
跳转到 所有步骤的最终步骤。
最终步骤
如果您在来这里之前运行了 cargo vendor,请检查您是否有一个 .cargo/config.toml 文件。如果没有,请创建该目录并将 cargo_config 文件从您的附加源复制到那里。
然后也将它置于版本控制之下,并将 cargo vendor 的输出写入 .cargo/config.toml(在大多数情况下,此文件不会被修改,但在极少数情况下可能会发生,当我们玩转依赖树时。因此,我们也希望将此修改包含在我们的补丁中)。
使用以下命令验证您拥有所有内容的正确版本
cargo tree | less
创建您所做的修改的补丁(使用您的版本控制,例如 git diff > ../modifying_vendored_crate.patch 或 quilt refresh),并将其添加到您的规范文件中。