From 253e956cc3b439f5d0640c730bd197b73be2105a Mon Sep 17 00:00:00 2001 From: Fabio Valentini Date: Feb 11 2021 13:28:11 +0000 Subject: update Rust guidelines and example spec files - mention rust2rpm more prominently since it creates 99% Guidelines-compliant spec files - BuildRequires are now automatically generated and no longer have to be specified manually - include how to generate the effective License tag for subpackages containing statically linked Rust binaries - Modularity is no longer used for building on any branch, add a short note about the build process for Rust packages - crate packages will start being available with fedora 34 in addition to rawhide (see the F34 System-Wide Change page for details: https://fedoraproject.org/wiki/Changes/Rust_Crate_Packages_For_Release_Branches ) - mention general Updates policy exceptions for source-only Rust packages - refreshed .spec file examples with current specs from rawhide --- diff --git a/guidelines/modules/ROOT/examples/rust-ripgrep.spec b/guidelines/modules/ROOT/examples/rust-ripgrep.spec index bb09114..6de6efe 100644 --- a/guidelines/modules/ROOT/examples/rust-ripgrep.spec +++ b/guidelines/modules/ROOT/examples/rust-ripgrep.spec @@ -1,10 +1,11 @@ -# Generated by rust2rpm +# Generated by rust2rpm 15 %bcond_without check +%global __cargo_skip_build 0 %global crate ripgrep Name: rust-%{crate} -Version: 0.10.0 +Version: 12.1.1 Release: 1%{?dist} Summary: Line oriented search tool using Rust's regex library @@ -13,40 +14,29 @@ License: Unlicense or MIT URL: https://crates.io/crates/ripgrep Source: %{crates_source} # Initial patched metadata -# * No windows # * No simd -# * Use jit_if_available, https://github.com/BurntSushi/ripgrep/commit/eb18da04506b959c0251099eae83e16d22ce8bcb +# * No jemalloc Patch0: ripgrep-fix-metadata.diff -# Really use jit_if_available -Patch0001: 0001-pcre2-use-jit_if_available.patch ExclusiveArch: %{rust_arches} BuildRequires: rust-packaging -BuildRequires: (crate(clap/suggestions) >= 2.32.0 with crate(clap/suggestions) < 3.0.0) -BuildRequires: (crate(grep/default) >= 0.2.3 with crate(grep/default) < 0.3.0) -BuildRequires: (crate(grep/pcre2) >= 0.2.3 with crate(grep/pcre2) < 0.3.0) -BuildRequires: (crate(ignore/default) >= 0.4.4 with crate(ignore/default) < 0.5.0) -BuildRequires: (crate(lazy_static/default) >= 1.1.0 with crate(lazy_static/default) < 2.0.0) -BuildRequires: (crate(log/default) >= 0.4.5 with crate(log/default) < 0.5.0) -BuildRequires: (crate(num_cpus/default) >= 1.8.0 with crate(num_cpus/default) < 2.0.0) -BuildRequires: (crate(regex/default) >= 1.0.5 with crate(regex/default) < 2.0.0) -BuildRequires: (crate(serde_json/default) >= 1.0.23 with crate(serde_json/default) < 2.0.0) -BuildRequires: (crate(termcolor/default) >= 1.0.3 with crate(termcolor/default) < 2.0.0) -%if %{with check} -BuildRequires: (crate(serde/default) >= 1.0.77 with crate(serde/default) < 2.0.0) -BuildRequires: (crate(serde_derive/default) >= 1.0.77 with crate(serde_derive/default) < 2.0.0) -%endif -BuildRequires: %{_bindir}/a2x -%global _description \ -Line oriented search tool using Rust's regex library.\ -Combines the raw performance of grep with the usability of the silver searcher. +%global _description %{expand: +Line-oriented search tool that recursively searches your current directory for +a regex pattern while respecting your gitignore rules. ripgrep has first class +support on Windows, macOS and Linux.} %description %{_description} %package -n %{crate} Summary: %{summary} +# * ASL 2.0 or Boost +# * ASL 2.0 or MIT +# * MIT +# * MIT or ASL 2.0 +# * Unlicense or MIT +License: MIT and (Boost or ASL 2.0) %description -n %{crate} %{_description} @@ -59,8 +49,8 @@ Summary: %{summary} %dir %{_datadir}/bash-completion/completions %{_datadir}/bash-completion/completions/rg.bash %dir %{_datadir}/fish -%dir %{_datadir}/fish/vendor_functions.d -%{_datadir}/fish/vendor_functions.d/rg.fish +%dir %{_datadir}/fish/vendor_completions.d +%{_datadir}/fish/vendor_completions.d/rg.fish %dir %{_datadir}/zsh %dir %{_datadir}/zsh/site-functions %{_datadir}/zsh/site-functions/_rg @@ -69,18 +59,22 @@ Summary: %{summary} %autosetup -n %{crate}-%{version_no_tilde} -p1 %cargo_prep +%generate_buildrequires +%cargo_generate_buildrequires -a +echo '/usr/bin/asciidoctor' + %build %cargo_build -a %install %cargo_install -a -%{__install} -Dpm0644 -t %{buildroot}%{_mandir}/man1 \ +install -Dpm0644 -t %{buildroot}%{_mandir}/man1 \ target/release/build/%{crate}-*/out/rg.1 -%{__install} -Dpm0644 -t %{buildroot}%{_datadir}/bash-completion/completions \ +install -Dpm0644 -t %{buildroot}%{_datadir}/bash-completion/completions \ target/release/build/%{crate}-*/out/rg.bash -%{__install} -Dpm0644 -t %{buildroot}%{_datadir}/fish/vendor_functions.d \ +install -Dpm0644 -t %{buildroot}%{_datadir}/fish/vendor_completions.d \ target/release/build/%{crate}-*/out/rg.fish -%{__install} -Dpm0644 -t %{buildroot}%{_datadir}/zsh/site-functions \ +install -Dpm0644 -t %{buildroot}%{_datadir}/zsh/site-functions \ complete/_rg %if %{with check} @@ -89,5 +83,3 @@ Summary: %{summary} %endif %changelog -* Mon Mar 18 21:02:51 CET 2019 Igor Gnatenko - 0.10.0-1 -- Initial package diff --git a/guidelines/modules/ROOT/examples/rust-serde.spec b/guidelines/modules/ROOT/examples/rust-serde.spec index 130b942..863d10d 100644 --- a/guidelines/modules/ROOT/examples/rust-serde.spec +++ b/guidelines/modules/ROOT/examples/rust-serde.spec @@ -1,28 +1,29 @@ -# Generated by rust2rpm -%bcond_without check +# Generated by rust2rpm 15 +# * RUSTC_BOOTSTRAP breaks tests +%bcond_with check %global debug_package %{nil} %global crate serde Name: rust-%{crate} -Version: 1.0.89 +Version: 1.0.116 Release: 1%{?dist} Summary: Generic serialization/deserialization framework -# Upstream license specification: MIT/Apache-2.0 +# Upstream license specification: MIT OR Apache-2.0 License: MIT or ASL 2.0 URL: https://crates.io/crates/serde Source: %{crates_source} ExclusiveArch: %{rust_arches} +%if %{__cargo_skip_build} +BuildArch: noarch +%endif BuildRequires: rust-packaging -%if %{with check} -BuildRequires: (crate(serde_derive/default) >= 1.0.0 with crate(serde_derive/default) < 2.0.0) -%endif -%global _description \ -A generic serialization/deserialization framework. +%global _description %{expand: +Generic serialization/deserialization framework.} %description %{_description} @@ -38,7 +39,7 @@ which use "%{crate}" crate. %files devel %license LICENSE-MIT LICENSE-APACHE %doc README.md crates-io.md -%{cargo_registry}/%{crate}-%{version}/ +%{cargo_registry}/%{crate}-%{version_no_tilde}/ %package -n %{name}+default-devel Summary: %{summary} @@ -50,7 +51,7 @@ This package contains library source intended for building other packages which use "default" feature of "%{crate}" crate. %files -n %{name}+default-devel -%ghost %{cargo_registry}/%{crate}-%{version}/Cargo.toml +%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml %package -n %{name}+alloc-devel Summary: %{summary} @@ -62,7 +63,7 @@ This package contains library source intended for building other packages which use "alloc" feature of "%{crate}" crate. %files -n %{name}+alloc-devel -%ghost %{cargo_registry}/%{crate}-%{version}/Cargo.toml +%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml %package -n %{name}+derive-devel Summary: %{summary} @@ -74,7 +75,7 @@ This package contains library source intended for building other packages which use "derive" feature of "%{crate}" crate. %files -n %{name}+derive-devel -%ghost %{cargo_registry}/%{crate}-%{version}/Cargo.toml +%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml %package -n %{name}+rc-devel Summary: %{summary} @@ -86,7 +87,7 @@ This package contains library source intended for building other packages which use "rc" feature of "%{crate}" crate. %files -n %{name}+rc-devel -%ghost %{cargo_registry}/%{crate}-%{version}/Cargo.toml +%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml %package -n %{name}+serde_derive-devel Summary: %{summary} @@ -98,7 +99,7 @@ This package contains library source intended for building other packages which use "serde_derive" feature of "%{crate}" crate. %files -n %{name}+serde_derive-devel -%ghost %{cargo_registry}/%{crate}-%{version}/Cargo.toml +%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml %package -n %{name}+std-devel Summary: %{summary} @@ -110,7 +111,7 @@ This package contains library source intended for building other packages which use "std" feature of "%{crate}" crate. %files -n %{name}+std-devel -%ghost %{cargo_registry}/%{crate}-%{version}/Cargo.toml +%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml %package -n %{name}+unstable-devel Summary: %{summary} @@ -122,12 +123,15 @@ This package contains library source intended for building other packages which use "unstable" feature of "%{crate}" crate. %files -n %{name}+unstable-devel -%ghost %{cargo_registry}/%{crate}-%{version}/Cargo.toml +%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml %prep %autosetup -n %{crate}-%{version_no_tilde} -p1 %cargo_prep +%generate_buildrequires +%cargo_generate_buildrequires + %build %cargo_build @@ -140,5 +144,3 @@ which use "unstable" feature of "%{crate}" crate. %endif %changelog -* Mon Mar 18 20:55:02 CET 2019 Igor Gnatenko - 1.0.89-1 -- Initial package diff --git a/guidelines/modules/ROOT/examples/rust-yubibomb.spec b/guidelines/modules/ROOT/examples/rust-yubibomb.spec index 151d24e..17ade8a 100644 --- a/guidelines/modules/ROOT/examples/rust-yubibomb.spec +++ b/guidelines/modules/ROOT/examples/rust-yubibomb.spec @@ -1,10 +1,10 @@ -# Generated by rust2rpm +# Generated by rust2rpm 13 %bcond_without check %global crate yubibomb Name: rust-%{crate} -Version: 0.2.0 +Version: 0.2.1 Release: 1%{?dist} Summary: Rust command line tool that prints out a 6-digit random number @@ -12,26 +12,23 @@ Summary: Rust command line tool that prints out a 6-digit random number License: GPLv3 URL: https://crates.io/crates/yubibomb Source: %{crates_source} -# Initial patched metadata -# * Bump regex to 1, https://gitlab.com/bowlofeggs/yubibomb/commit/301cb10cd056cd33c4736b87aaad333f77c6c252 -Patch0: yubibomb-fix-metadata.diff ExclusiveArch: %{rust_arches} +%if %{__cargo_skip_build} +BuildArch: noarch +%endif BuildRequires: rust-packaging -BuildRequires: (crate(rand/default) >= 0.4.0 with crate(rand/default) < 0.5.0) -%if %{with check} -BuildRequires: (crate(regex/default) >= 1.0.0 with crate(regex/default) < 2.0.0) -%endif -%global _description \ -Don't you love when you accidentally tap your Yubikey when you have your IRC\ -client in focus and you send 987947 into Freenode? Want to be able to have that\ -experience without having to reach all the way over to your laptop's USB port?\ -Now you can! +%global _description %{expand: +Don't you love when you accidentally tap your Yubikey when you have your IRC +client in focus and you send 987947 into Freenode? Want to be able to have that +experience without having to reach all the way over to your laptop's USB port? +Now you can!.} %description %{_description} +%if ! %{__cargo_skip_build} %package -n %{crate} Summary: %{summary} @@ -41,6 +38,7 @@ Summary: %{summary} %license LICENSE %doc README.md %{_bindir}/yubibomb +%endif %package devel Summary: %{summary} @@ -54,7 +52,7 @@ which use "%{crate}" crate. %files devel %license LICENSE %doc README.md -%{cargo_registry}/%{crate}-%{version}/ +%{cargo_registry}/%{crate}-%{version_no_tilde}/ %package -n %{name}+default-devel Summary: %{summary} @@ -66,12 +64,15 @@ This package contains library source intended for building other packages which use "default" feature of "%{crate}" crate. %files -n %{name}+default-devel -%ghost %{cargo_registry}/%{crate}-%{version}/Cargo.toml +%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml %prep %autosetup -n %{crate}-%{version_no_tilde} -p1 %cargo_prep +%generate_buildrequires +%cargo_generate_buildrequires + %build %cargo_build @@ -84,5 +85,3 @@ which use "default" feature of "%{crate}" crate. %endif %changelog -* Mon Mar 18 21:09:53 CET 2019 Igor Gnatenko - 0.2.0-1 -- Initial package diff --git a/guidelines/modules/ROOT/pages/Rust.adoc b/guidelines/modules/ROOT/pages/Rust.adoc index 5ad8769..8412bda 100644 --- a/guidelines/modules/ROOT/pages/Rust.adoc +++ b/guidelines/modules/ROOT/pages/Rust.adoc @@ -1,65 +1,133 @@ = Rust Packaging Guidelines -:last-reviewed: 2019-03-28 +:last-reviewed: 2021-01-24 -This document details best practices for packaging Rust crates. -Note that the rust2rpm tool, -available as a Fedora package or at https://pagure.io/fedora-rust/rust2rpm, -automates many of these steps. -It is advisable to try `+rust2rpm $crate+` first -before attempting to write a specfile by hand. +CAUTION: The workflow for Rust packaging on Fedora will be different starting with Fedora 34. + Older releases (up until Fedora 33) do not ship source-only packages for Rust crates, + but only application packages created via a special build process. + In general, the Rust Packaging Guidelines apply to all current Fedora releases, + only the build process differs depending on the targeted Fedora release. -CAUTION: This document is applicable only for Fedora Rawhide. - Stable releases do not contain any crates. - However, this document can be used to build modules - with Rust applications - (with crates filtered out). +== rust2rpm -== Naming +Note that the https://pagure.io/fedora-rust/rust2rpm[*rust2rpm*] tool +(packaged as `python3-rust2rpm` for Fedora) +automates most of the steps that are necessary for creating .spec files for Rust crates. -Rust crates MUST be named `rust-$crate`. -The crates are expected to be from https://crates.io[crates.io]. -Rust applications that aren't from crates.io MUST follow the main guidelines for package names. +It is advisable to try `+rust2rpm $crate+` first, +and to only modify its output for your needs, +before attempting to write a .spec file by hand. -At this time, -Rust libraries MUST be from crates.io, -as this enforces a certain standard in how they are packaged and built. +Most of the time, rust2rpm output can be used almost without modifications, +except for adding `LICENSE` files with `+%license+` to the appropriate `+%files+` listings, +or sometimes trimming the `Summary` if the upstream description text is too long. -== Dependencies +== Package Naming -Packages MUST have `+BuildRequires: rust-packaging+`. +Packages for Rust crates MUST be named `rust-$crate`. + +Any library crates that get packaged MUST be published on crates.io, +since this enforces a certain standard in how crates are packaged and built, +and also ensures that all crate dependencies are available from crates.io as well. + +Crates that only contain an application -- but no library -- may be packaged +even if they are not published on crates.io, +because those packages are leaves and no other Rust packages can depend on them. + +Rust applications that are not published to crates.io MUST follow the default xref:Naming.adoc[Naming Guidelines]. + +== Package sources + +The primary Source for library crates -- that MUST be published on crates.io -- +MUST be specified as `+%{crates_source}+`, +which uses the `+%{crate}+` and `+%{version}+` macros to calculate the download URL. + +Application crates do not have to be published on crates.io, +so only the general Guidelines for Sources apply. + +In the case that crates published to crates.io are missing files +(`.desktop` files for GUI applications, manual pages, default configuration files, etc.), +they MAY be included from the upstream sources, +but the packager SHOULD query upstream to include those missing files in their published crates. + +== Package Dependencies + +All Rust packages MUST have `+BuildRequires: rust-packaging+`. + +=== Bundled Dependencies + +NOTE: As stated in the general xref:index.adoc#bundling[Packaging Guidelines], + packages MUST be built against system libraries, if that is possible. + For Rust, this means that packages MUST NOT use dependencies from a "vendor tarball" + (e.g. crated by running `+cargo vendor+`), + but package all library dependencies separately. + +However, two common reasons that can make building a package +against system libraries (crates) basically impossible are +if a crate applies downstream patches on top of its dependencies, +or if it depends on "internal" crates that are not published on crates.io. +In these circumstances, packagers MAY use bundled dependencies, +but - if possible - SHOULD work with upstream to, for example, +make their downstream patches unnecessary, or publish internal crates. + +If bundled dependencies are used to build a binary package, +the subpackage that will contain the compiled binary +MUST have `+Provides: bundled(crate(foo)) = version+` for each bundled crate +and the packager MUST keep this list of crates and their versions up-to-date +every time the package or its bundled dependencies are updated. === Automatic Dependency Generation -`rust-packaging` automatically creates Requires/Provides -based on `+%{cargo_registry}/*/Cargo.toml+` files. +`rust-packaging` automatically creates Requires and Provides +based on cargo metadata in `+%{cargo_registry}/*/Cargo.toml+` files. The Provides generator creates: * `crate($name) = $version` for base package (`rust-$name-devel`) * `crate($name/$feature) = $version` for feature subpackages (`rust-$name+$feature-devel`) -The automatic requirement generator takes this into account -and creates the appropriate rich dependencies -to ensure that the code works. +The Provides / Requires generator relies on empty subpackages with special names +for encoding the dependency information of optional features. +These subpackages MUST be named `+rust-%{crate}+$FEATURE-devel+` +for all features that are present in `Cargo.toml` after patching this file in `+%prep+`. -For example: +NOTE: These feature subpackage definitions are automatically correctly generated + when using rust2rpm (if necessary, with the `-p` flag to apply any initial changes). + +The dependency generator then creates `Requires` for all features that a crate depends on. +For example, a dependency on `syn` with the `visit` and `extra-traits` features .... syn = { version = "0.15", features = ["visit", "extra-traits"] } .... -becomes +will be encoded as .... -(crate(syn/default) >= 0.15.0 with crate(syn/default) < 0.16.0) -(crate(syn/extra-traits) >= 0.15.0 with crate(syn/extra-traits) < 0.16.0) -(crate(syn/visit) >= 0.15.0 with crate(syn/visit) < 0.16.0) +Requires: (crate(syn/default) >= 0.15.0 with crate(syn/default) < 0.16.0) +Requires: (crate(syn/extra-traits) >= 0.15.0 with crate(syn/extra-traits) < 0.16.0) +Requires: (crate(syn/visit) >= 0.15.0 with crate(syn/visit) < 0.16.0) .... +where the `default` feature of `syn` is also included, +because the `default-features=false` option was not specified. + === BuildRequires -Packagers MUST specify all BuildRequires according to the definition in Cargo.toml, -for example: +Rust packages SHOULD use automatic generation of `BuildRequires` +by including this scriptlet between `+%prep+` and `+%build+`: + +.... +%generate_buildrequires +%cargo_generate_buildrequires +.... + +This will automatically generate the necessary `BuildRequires` based on the `Cargo.toml` file. +This step runs *after* `+%prep+`, so any modification of `Cargo.toml` +(for example, after applying patches to remove dependencies or to modify versions of dependencies) +will be taken into account. + +If using `+%cargo_generate_buildrequires+` is not possible, +`BuildRequires` MUST be specified manually and kept up-to-date with each package update: .... [dependencies] @@ -75,27 +143,68 @@ BuildRequires: (crate(atty/default) >= 0.2.2 with crate(atty/default) < 0.3.0) BuildRequires: (crate(clap/default) >= 2.24.1 with crate(clap/default) < 3.0.0) .... -=== Versions +== Crate Versions + +* Packagers SHOULD package the latest version of a crate. +* Packagers SHOULD patch crates to use the latest version of their dependencies, + to reduce the downstream maintenance burden and the need for compat packages. +* When introducing patches to bump the version of dependencies, + packagers SHOULD forward these patches to the upstream project + to keep the divergence between downstream and upstream small over time. + +=== Compatibility packages for older crate versions + +If it is not possible to port a crate to the version of a dependency that is available in Rawhide, +a compatibility ("compat") package for the *older* version of a crate can be introduced. +No package reviews for such compatibility packages are necessary, +but they must follow the xref:Naming.adoc#multiple[Naming Guidelines] for compatibility packages. + +For example, the latest `rust-nix` package might ship the latest version of `nix`, +but some packages still require the older `0.14.1` version of the crate -- +in this case, the compatibility package would be called `rust-nix0.14`. + +NOTE: Compatibility packages for older versions of library crates + are always parallel-installable with each other, + since all files in them are namespaced by both the crate's name *and* version. + +However, compatibility packages for older crate versions MUST NOT ship application binaries. +Neither the names of the subpackages that contain those binaries, +nor the binaries themselves, are namespaced by the crate version. +The package for the _older_ version MUST be adapted to remove its binary subpackage, +so it only contains `-devel` subpackage(s) but no `+%{crate}+` subpackage, +which would conflict with the corresponding package from the newer version of the crate. -* Packagers SHOULD use latest version of dependent crates. -* Packagers SHOULD patch crates to use the latest version of dependent crates to reduce maintenance burden. -* When doing so, - packagers SHOULD forward these upstream - so that the upstream software is fixed to support the latest versions of their dependencies. +NOTE: When introducing a compatibility package, the packager SHOULD check + if keeping the test suite enabled causes additional unwanted dependencies, + for example, on other compatibility packages, or on old versions of other packages. + If that is the case, the test suite SHOULD be disabled to lower the overall maintenance burden. == ExclusiveArch All rust packages MUST have `+ExclusiveArch: %{rust_arches}+`. -== Others +== License for binary packages -Packagers MUST run `+%cargo_prep+` to prepare configuration for further cargo invocations -(sets up RUSTFLAGS and all other stuff). +Since Rust applications are statically linked and contain code from all their dependencies, +the effective license for the subpackage containing the built binary +must be calculated from the individual licenses of all dependencies. -=== Exclude unnecessary files +The `+rust2rpm+` project provides a https://pagure.io/fedora-rust/rust2rpm/blob/master/f/tools/fedora-helper.py[helper script] +that can be used to obtain a list of Licenses of all real crate dependencies, +excluding dependencies that are only required at build-time or for running tests. + +Both the list of individual licenses *and* the `License` tag with the effective license +MUST be included in the subpackage that contains the statically linked binary. + +== Miscellaneous + +Packagers MUST run `+%cargo_prep+` after unpacking the crate's sources in `+%prep+`, +which sets up configuration for cargo (compilation flags, location of system crates, etc.). + +=== Excluding unnecessary files * Packagers SHOULD exclude files which are not used by anything (things like `appveyor.yml` and CI scripts). -* Packagers SHOULD use https://doc.rust-lang.org/cargo/reference/manifest.html#the-exclude-and-include-fields-optional[exclude field in Cargo.toml] instead of using `+%exclude+` +* Packagers SHOULD use the https://doc.rust-lang.org/cargo/reference/manifest.html#the-exclude-and-include-fields-optional[exclude field in Cargo.toml] instead of using `+%exclude+` in `+%files+` * Packagers SHOULD forward such patches to upstream Example: @@ -114,17 +223,15 @@ Example: ---- -=== Nightly, Other Platforms, etc. crates +=== Nightly features and dependencies for other platforms -Packagers MUST NOT package crates which do not work with the distribution. -That is, -if the crate depends on nightly-only features -or works only for non-Linux platforms, -the crate is not suitable for inclusion in Fedora. +Packagers MUST NOT package crates which do not work on Fedora, this includes: -If the crate can be made usable, -packagers MUST patch packages which use such dependencies, -for example: +* crates depending on nightly-only features of the Rust compiler +* crates with (non-Linux) platform-specific dependencies + +If such features and/or platform-specific dependencies are optional and can be removed, +the `Cargo.toml` file MUST be patched to remove them, for example: [source,diff] ---- @@ -142,26 +249,53 @@ for example: ---- -Such patches SHOULD be forwarded upstream. +== Notes on the build process + +CAUTION: The build process for Rust packages has evolved over time, + especially for binary packages. + Packages for source-only library crates were historically only built on Rawhide, + but will also start being available on stable branches starting with Fedora 34. + +* Originally, binary packages for stable releases were built using Modularity, + leveraging its buildroot-only packages filtering capabilities, + but this approach was dropped in the Fedora 31 timeframe. +* From Fedora 31 to Fedora 33, binary packages are built with a special process + (leveraging koji side tags), using base packages from the relevant stable Fedora release, + except for Rust crates, which are included from Rawhide. +* Starting with Fedora 34, the workflow for building Rust packages will no longer be special -- + packages for both library crates *and* applications will be available and built normally, + without having to rely on a special procedure for release branches. + +NOTE: Source-only Rust packages were granted a general exception to the + https://docs.fedoraproject.org/en-US/fesco/Updates_Policy/[Updates policy], + so they can be freely updated in release branches in addition to rawhide + (announced in the corresponding FESCo ticket: + https://pagure.io/fesco/issue/2474[F34 System-Wide Change: Rust Crate Packages For Release Branches]). == Examples -=== Library +=== Library crate -Rust library packages are packaged as source-only packages, -as we do not build dynamic link libraries at this time +Rust library crates are packaged as source-only packages +because Rust does not (yet) support shared libraries due to the lack of a stabilized ABI for Rust. +The source code is shipped in a `-devel` subpackage, +with separate subpackages for all features specified in `Cargo.toml`, +which encode the dependency information for all features and dependencies. + .rust-serde.spec [source] ---- include::{examplesdir}/rust-serde.spec[] ---- -=== Binary +=== Binary crate -Application packages are compiled into binaries, -with the application name used as the package name for the output binary package. +Rust applications are compiled to statically linked binaries, +which are put into a subpackage that matches the name of the crate (without `rust-` prefix), +e.g. the `rust-ripgrep` source package produces a `ripgrep` binary package, +which contains the `ripgrep` binary. .rust-ripgrep.spec [source] @@ -171,6 +305,14 @@ include::{examplesdir}/rust-ripgrep.spec[] === Library + Binary +Some crates ship both a compiled binary and a reusable library component, +in this case, +both the `-devel` subpackage(s) *and* the subpackage containing the binary are built. + +When building a package like this for a stable Fedora release (up to and including Fedora 33), +the .spec file SHOULD be modified to remove all `-devel` subpackages, +so no dangling broken dependencies on other (unavailable) library crates are introduced. + .rust-yubibomb.spec [source] ----