Generating the "effective" license of statically linked Rust binaries is one of the last, really annoying manual steps in Rust packaging. It would be great if we could automate at least some of the steps that are required here.
I used to use this script to output the list of licenses for all installed Rust crates in the RPM buildroot after a mock build with "--without check" (to skip dev-dependencies, which are not linked into shipped binaries):
for i in $(rpm -qa | grep "rust-.*-devel"); do rpm -q $i --qf "%{LICENSE}\n"; done | sort | uniq
This works fine, but it doesn't list the licenses by individual components, which would be necessary for a license breakdown.
As a better version, I started to use this:
dnf repoquery --cacheonly "rust-*-devel" --installed --qf "%{LICENSE}: %{source_name} %{version}"
This prints a list of "crate: license" (including compat packages) that can be included in .spec files.
However, both approaches are slightly wrong, insofar as they exclude dev-dependencies (only required for building / running test executables, not the shipped binary), but they don't exclude build-dependencies.
@alebastr did some digging and came up with a way to query cargo itself for the information we need:
cargo tree --workspace --offline --edges 'normal' --prefix none --format '{l}: {p}#' | cut -d\# -f1 | grep -v "($PWD" | sort -u
This command will print the list of "$LICENSE: $CRATE $VERSION". It also works when run during %build stage of an RPM build, using the local RPM based crate registry as source of data.
%build
It would be great if we could put that into a new macro, something like %cargo_license, which would write this information to a file, like LICENSE.dependencies, which can then be included as %license LICENSE.dependencies in %files. I've started doing this manually, but having a macro to do all the heavy lifting would be great (and it would also eliminate the need to keep track of this list in a separate file).
%cargo_license
LICENSE.dependencies
%license LICENSE.dependencies
rust2rpm could even automatically include usage of the new %cargo_license macro if it detects that a package builds a binary. Or even include it unconditionally in %cargo_build, since it doesn't hurt to run it for all builds, either, I guess.
%cargo_build
Then the packager would only need to collect the licenses into the value of the "License" tag of the subpackage that contains the binary, which is much less work than what's required today (and which is also very confusing to Rust packaging newcomers).
Metadata Update from @decathorpe: - Issue set to the milestone: 23
I managed to simplify the "cargo tree" command a little, and also made small adaptations:
cargo tree --workspace --offline --edges normal,no-proc-macro --no-dedupe --target all --prefix none --format "{l}: {p}" | sed -e "s: ($(pwd))::g" | sort -u
(*)
cargo tree also supports setting feature flags like other cargo commands (i.e. -f foo,bar and --all-features are both valid arguments)
cargo tree
cargo
-f foo,bar
--all-features
Can we make this into some kind of official RPM macro, similar to %cargo_build et al.?
Fixed by commit 69b5574. This will make the proposed macros available for broader testing, and once any remaining kinks are ironed out, they can be documented in the Rust Packaging Guidelines.
Metadata Update from @decathorpe: - Issue close_status updated to: Fixed - Issue status updated to: Closed (was: Open)
Login to comment on this ticket.