From 44113dd4b3fbb287ed2a44b5efe71ec5194247c9 Mon Sep 17 00:00:00 2001 From: Fabio Valentini Date: Mar 14 2024 15:36:08 +0000 Subject: [PATCH 1/2] Rust: replace occurrences of stray unicode characters - non-breaking spaces - en-dashes - typographic single quotes Note sure how they ended up there in the first place. --- diff --git a/guidelines/modules/ROOT/pages/Rust.adoc b/guidelines/modules/ROOT/pages/Rust.adoc index 9a88e40..cf141d5 100644 --- a/guidelines/modules/ROOT/pages/Rust.adoc +++ b/guidelines/modules/ROOT/pages/Rust.adoc @@ -1,6 +1,6 @@ = Rust Packaging Guidelines -:last-reviewed: 2023-10-12 +:last-reviewed: 2024-03-14 https://www.rust-lang.org[Rust] is a strongly and statically typed, compiled programming language @@ -26,7 +26,7 @@ specific to the different ways in which projects can be set up: usually built with https://github.com/PyO3/setuptools-rust[setuptools_rust] or https://github.com/PyO3/maturin[maturin] * link:#_mixed_rust_cc_projects[mixed Rust / C/C++ projects] where parts of the project are implemented in Rust: either built by wrapping cargo, - or by utilizing https://mesonbuild.com/Rust.html[meson]’s limited support + or by utilizing https://mesonbuild.com/Rust.html[meson]'s limited support for directly building Rust code For the first three of these cases, @@ -57,7 +57,7 @@ based on this macro. For compatibility with older releases, this environment variable can be set manually at the start of `%build` and `%check` -in package’s spec files: +in package's spec files: [source,shell] ---- @@ -76,13 +76,13 @@ as it is a dependency of `redhat-rpm-config`. When building for ELN or EPEL8, this is not the case, and packages need to use `BuildRequires: rust-toolset`. -Packages that build Rust code with cargo – directly or indirectly – +Packages that build Rust code with cargo - directly or indirectly - or which call any of the `%cargo_*` macros, *MUST* add `BuildRequires: cargo-rpm-macros >= 24`, which provides the implementations of all `%cargo_*` macros. This package is not part of the default buildroot, since it pulls in additional dependencies -(i.e. a Python interpreter). +(i.e. a Python interpreter). For backwards compatibility, packages *MAY* instead depend on earlier versions of the `%cargo_*` macros, @@ -99,7 +99,7 @@ for the RPM macro package automatically. Similar to other languages that produce statically linked binaries, Rust executables (and shared libraries) contain code that originates in other packages -(i.e. packages for other Rust crates), +(i.e. packages for other Rust crates), which in turn are covered by different license terms. This needs to be taken into account @@ -181,7 +181,7 @@ with a path-based dependency. Another way in which cargo supports specifying modified dependencies is by "patching" a crate source, -specifying an alternative source for specific crates – +specifying an alternative source for specific crates - which will likely be either git references or path-based dependencies that are present to override a crate that is published on https://crates.io[crates.io] with a (modified) local copy, @@ -211,7 +211,7 @@ was added in version 25 of cargo-rpm-macros and rust2rpm. that lists the names and versions of all crates in the vendor tarball. This macro *MUST* be called (for example, in the `%build` scriptlet), and the generated file *MUST* be added as a `%license` file - in the appropriate package’s list of `%files`. + in the appropriate package's list of `%files`. An RPM generator parses this file and generates appropriate virtual `Provides` for all bundled crates, as is required for any bundled dependencies. @@ -245,18 +245,18 @@ need manual changes: * invalid `Summary` / `%description`: The heuristics for generating the `Summary` or `%description` for the package from the crate metadata can fail to produce valid values - (i.e. `Summary` tag that is too long). + (i.e. `Summary` tag that is too long). In this case, the `Summary` needs to be shortened manually. This can also be overridden in the package-specific rust2rpm configuration file. * unwanted dependencies / subpackages: Some crates provide non-default / optional features that are either unnecessary - (i.e. only applicable to non-Linux systems), + (i.e. only applicable to non-Linux systems), or have additional dependencies that are not packaged for Fedora. These features and unavailable optional dependencies *MUST* - be removed from crate metadata – otherwise, + be removed from crate metadata - otherwise, the package will either fail to build, or produce subpackages with broken dependencies. * nightly-only / unstable features: @@ -297,7 +297,7 @@ Note that patching `Cargo.toml` files (especially changing the set of optional dependencies and features) *MUST* be done by running `rust2rpm -p`, since changes like these affect spec file generation -(i.e. the list of generated subpackages), +(i.e. the list of generated subpackages), which is only correctly taken into account if the patch is created _before_ generation of the spec file. @@ -309,7 +309,7 @@ It is designed to generate spec files that are compliant with both the general and the Rust Packaging Guidelines. Additionally, due to some properties of packages for Rust crates -(i.e. subpackages that correspond to crate features / optional dependencies), +(i.e. subpackages that correspond to crate features / optional dependencies), it is necessary to re-run https://pagure.io/fedora-rust/rust2rpm[rust2rpm] for every new version of a crate to ensure that generated feature subpackages @@ -329,13 +329,13 @@ On the other hand, projects from other sources *MUST NOT* use the `rust-` prefix for source package names, and *MUST* follow the general Naming Guidelines instead. They also *MUST NOT* have any virtual `Provides` for Rust crates -(i.e. `Provides: crate(%{crate}) = %{version}`). +(i.e. `Provides: crate(%{crate}) = %{version}`). When generating a package for a Rust crate that also (or exclusively) contains an application, the convention followed by https://pagure.io/fedora-rust/rust2rpm[rust2rpm] is -to generate a subpackage with a name that matches the crate’s name -(i.e. the `rust-$crate` source package will have a `$crate` subpackage). +to generate a subpackage with a name that matches the crate's name +(i.e. the `rust-$crate` source package will have a `$crate` subpackage). If this name does not match expectations, it is recommended to either change the name of this subpackage, or to add virtual `Provides` for the expected name. @@ -367,7 +367,7 @@ This happens automatically when using rust2rpm version 25 or newer. === Package sources Projects from https://crates.io[crates.io] *MUST* be packaged from the sources -that are published there (i.e. by using the `%{crates_source}` macro). +that are published there (i.e. by using the `%{crates_source}` macro). If the sources published on https://crates.io[crates.io] do not contain all files that are necessary for creating the package @@ -380,7 +380,7 @@ about including these additional files in published crates. If a crate is also part of a larger project and it is not feasible to package the Rust crate separately, the Rust crate *MAY* be packaged as `rust-$crate` from different sources -(i.e. an upstream tarball) _if and only if_ the crate is also published on https://crates.io[crates.io] +(i.e. an upstream tarball) _if and only if_ the crate is also published on https://crates.io[crates.io] under the same name and with matching versions. In this case, the subpackage(s) corresponding to Rust crates *MUST* have correct virtual `Provides` for the Rust crate. @@ -429,7 +429,7 @@ is almost entirely automated with several RPM macros: for crates that provide a library interface. It runs `cargo package` and installs the resulting directory tree into `%{buildroot}/%{crate_instdir}` - (i.e. `%{buildroot}/%{cargo_registry}/%{crate}-%{version}/`). + (i.e. `%{buildroot}/%{cargo_registry}/%{crate}-%{version}/`). For crates that provide `bin` targets, it installs all built executables into `%{buildroot}/%{_bindir}`. If any built executables need to be installed in a different location, @@ -453,7 +453,7 @@ All packages for Rust crates *MUST* set either `%bcond_without check` or `%bcond_with check`. The value of this macro affects the behaviour of `%cargo_generate_buildrequires`. -All `%cargo_*` macros (except `%cargo_prep`) +All `%cargo_*` macros (except `%cargo_prep` and `%cargo_vendor_manifest`) accept a set of optional flags / arguments that can be used to control the feature flags that are passed to cargo (usually to enable optional / non-default features): @@ -505,7 +505,7 @@ With Semantic Versioning (_"SemVer"_) being the only supported versioning scheme for Rust crates, dependencies on Rust libraries are almost exclusively specified as _"this version or any newer version that is API-compatible with it"_, -i.e. a range of supported versions. +i.e. a range of supported versions. These ranges of supported versions need to be correctly translated into RPM dependencies, @@ -545,7 +545,7 @@ to support resolving dependencies for features and optional dependencies of crat The list of crate "features" (including any implicitly defined features for optional dependencies) *MUST* be kept in sync with the list of subpackages, -i.e. for every feature `$foo` of the crate `$crate`, +i.e. for every feature `$foo` of the crate `$crate`, there must be a subpackage with name `rust-$crate+$foo-devel`, and vice-versa. This is required for RPM generators for `Provides` and `Requires` @@ -574,10 +574,10 @@ will be present in all packages for Rust crates with a library interface. The cargo-rpm-macros package includes RPM generators for automatically generating `Provides` and `Requires` for Rust crates that comply with the Packaging Guidelines -(i.e. install their files into the correct location, `%{crate_instdir}`). +(i.e. install their files into the correct location, `%{crate_instdir}`). It is recommended to verify -that the generated `Provides` and `Requires` are sane – for example, +that the generated `Provides` and `Requires` are sane - for example, the following `Provides` and `Requires` must be present to ensure correct inter-subpackage dependencies: @@ -585,7 +585,7 @@ must be present to ensure correct inter-subpackage dependencies: *MUST* provide `crate($crate) = %{version}` * the `rust-$crate+$feature-devel` subpackages *MUST* provide `crate($crate/$feature) = %{version}` - and require `crate($crate) = %{version}` (i.e. `rust-$crate-devel`) + and require `crate($crate) = %{version}` (i.e. `rust-$crate-devel`) Additionally, dependencies on external Rust crates must be as expected: @@ -593,13 +593,13 @@ Additionally, dependencies on external Rust crates must be as expected: *MUST* require the virtual `Provides` for all non-optional crate dependencies * the `rust-$crate+$feature-devel` subpackages *MUST* require the virtual `Provides` for the optional crate dependencies - and features that are listed as the feature’s dependencies in crate metadata + and features that are listed as the feature's dependencies in crate metadata === Packaging multiple versions In most circumstances, the latest version of a crate *SHOULD* be packaged, -and – if possible – packagers *SHOULD* port crates +and - if possible - packagers *SHOULD* port crates to use the latest available version of their dependencies, and submit these patches to upstream to limit divergence between the upstream project and the Fedora package. @@ -615,7 +615,7 @@ for multiple versions of a library crate simultaneously: by a required SemVer-incompatible library update is very large. In these cases, a "compat package" can be created for the older version -(i.e. usually the current version), +(i.e. usually the current version), and the suffix-less package can be updated to the newer version. https://pagure.io/fedora-rust/rust2rpm[rust2rpm] supports automatically creating "compat packages" @@ -638,19 +638,19 @@ and two additional rules apply when creating them: whether running tests in the old version of the crate would cause additional, potentially undesirable dependencies, for example, older versions of other dependencies - that would require creating additional "compat packages" – + that would require creating additional "compat packages" - in this case, tests *SHOULD* be disabled - (i.e. by flipping the `check` bcond). + (i.e. by flipping the `check` bcond). === The `check` bcond The behaviour of some RPM macros depends on the presence and value of the `_with_check` macro, -i.e. if `%bcond_without check` or `%bcond_with check` -are used in the spec file – notably, +i.e. if `%bcond_without check` or `%bcond_with check` +are used in the spec file - notably, the `%cargo_generate_buildrequires` macro only includes `dev-dependencies` -(i.e. dependencies that are only used -for compiling and / or running a project’s test suite with cargo) +(i.e. dependencies that are only used +for compiling and / or running a project's test suite with cargo) if the `check` bconf is enabled. Additionally, packages for Rust crates or workspace projects @@ -681,7 +681,7 @@ Rust crates can have three different kinds of tests in their test suites: to ensure that code snippets in documentation for public methods are correct and continue to compile. -By default, running `cargo test` (i.e. by calling the `%cargo_test` macro), +By default, running `cargo test` (i.e. by calling the `%cargo_test` macro), all three kinds of tests are run. They can also be invoked separately (for example, because parts of the test suite or large data files are @@ -725,7 +725,7 @@ has basic support for generating spec files for this type of package by running `rust2rpm path/to/Cargo.toml` in unpacked upstream sources. Packages that fall into this category *MUST NOT* ship crate sources in `%{cargo_registry}`, -i.e. they cannot ship `-devel` subpackages +i.e. they cannot ship `-devel` subpackages that contain crate sources or have subpackages that have virtual provides for `crate(...) = %{version}`. @@ -735,7 +735,7 @@ Rust applications that are "crates" but which are not published on https://crates.io[crates.io] *MUST* be named according to the generic https://docs.fedoraproject.org/en-US/packaging-guidelines/Naming/[Naming Guidelines], -i.e. they *MUST NOT* use a `rust-` prefix for the source package name. +i.e. they *MUST NOT* use a `rust-` prefix for the source package name. === Package sources @@ -760,11 +760,11 @@ https://pagure.io/fedora-rust/rust2rpm[rust2rpm] has basic support for generating spec files for this type of package by running `rust2rpm path/to/Cargo.toml` in unpacked upstream sources, (where `./Cargo.toml` must be the path to the "workspace root", -i.e. the `Cargo.toml` file that contains the `[workspace]` table). +i.e. the `Cargo.toml` file that contains the `[workspace]` table). Packages that fall into this category *MUST NOT* ship crate sources in `%{cargo_registry}`, -i.e. they cannot ship `-devel` subpackages that contain crate sources +i.e. they cannot ship `-devel` subpackages that contain crate sources or have any subpackages that have virtual provides for `crate(...) = %{version}`. === Package naming @@ -772,7 +772,7 @@ or have any subpackages that have virtual provides for `crate(...) = %{version}` Rust projects that are organized as "cargo workspaces" *MUST* be named according to the generic https://docs.fedoraproject.org/en-US/packaging-guidelines/Naming/[Naming Guidelines], -i.e. they *MUST NOT* use a `rust-` prefix for the source package name. +i.e. they *MUST NOT* use a `rust-` prefix for the source package name. === Package sources @@ -823,7 +823,7 @@ that the default link:#_compiler_flags[compiler flags] are passed to rustc. Handling of projects that include both C/C++ and Rust code depends on how building the Rust code is integrated -into the project’s build system. +into the project's build system. Independent of the specific setup, the correct link:#_compiler_flags[compiler flags] *MUST* be passed to rustc, @@ -837,7 +837,7 @@ Projects with build systems that call cargo internally to build Rust components as other projects that build Rust code with cargo. Packages *MUST* ensure that the cargo calls -that are internal to the project’s build system +that are internal to the project's build system do not pass flags or arguments that are incompatible with either the default link:#_compiler_flags[compiler flags] or cargo options that are set in the `%cargo_build` macro or configured by `%cargo_prep`. From 1ba36bca91d79123f146ea0ac54e570975a888a1 Mon Sep 17 00:00:00 2001 From: Fabio Valentini Date: Mar 14 2024 15:38:11 +0000 Subject: [PATCH 2/2] Rust: document that the same feature flags must be passed everywhere --- diff --git a/guidelines/modules/ROOT/pages/Rust.adoc b/guidelines/modules/ROOT/pages/Rust.adoc index cf141d5..8047681 100644 --- a/guidelines/modules/ROOT/pages/Rust.adoc +++ b/guidelines/modules/ROOT/pages/Rust.adoc @@ -496,9 +496,21 @@ in which passing these flags or arguments is necessary: (including `%cargo_license` and `%cargo_license_summary`). Note that the `-n` flag should only be used in exceptional circumstances, +for example when enabling a different backend than the one enabled by default, and *MUST NOT* be used to avoid missing dependencies that are part of the `"default"` feature set of a crate. +When passing any of the `-a` or `-n` flags or an `-f` argument +to a `%cargo_build` and / or `%cargo_install` macro, +the same flags MUST also be passed +to `%cargo_license` and `%cargo_license_summary` (if present). +Otherwise, the list of generated licenses and the generated license summary +will not match what is used when the application or library is compiled. + +It is recommended to set these flags in a `rust2rpm.toml` config file +which causes the flags to be injected into generated spec files automatically, +whereever necessary. + === Dynamically generated `BuildRequires` for crate dependencies With Semantic Versioning (_"SemVer"_) being