# __rustc: path to the default rustc executable %__rustc /usr/bin/rustc # __rustdoc: path to the default rustdoc executable %__rustdoc /usr/bin/rustdoc # rustflags_opt_level: default optimization level # # It corresponds to the "-Copt-level" rustc command line option. %rustflags_opt_level 3 # rustflags_debuginfo: default verbosity of debug information # # It corresponds to the "-Cdebuginfo" rustc command line option. # In some cases, it might be required to override this macro with "1" or even # "0", if memory usage gets too high during builds on some resource-constrained # architectures (most likely on 32-bit architectures), which will however # reduce the quality of the produced debug symbols. %rustflags_debuginfo 2 # rustflags_codegen_units: default number of parallel code generation units # # The default value of "1" results in generation of better code, but comes at # the cost of longer build times. %rustflags_codegen_units 1 # build_rustflags: default compiler flags for rustc (RUSTFLAGS) # # -Copt-level: set optimization level (default: highest optimization level) # -Cdebuginfo: set debuginfo verbosity (default: full debug information) # -Ccodegen-units: set number of parallel code generation units (default: 1) # -Cforce-frame-pointers: force inclusion of frame pointers (default: enabled # on x86_64 and aarch64 on Fedora 37+) # # Additionally, some linker flags are set which correspond to the default # Fedora compiler flags for hardening and for embedding package versions into # compiled binaries. # # ref. https://doc.rust-lang.org/rustc/codegen-options/index.html %build_rustflags %{shrink: -Copt-level=%rustflags_opt_level -Cdebuginfo=%rustflags_debuginfo -Ccodegen-units=%rustflags_codegen_units -Cstrip=none %{expr:0%{?_include_frame_pointers} && ("%{_arch}" != "ppc64le" && "%{_arch}" != "s390x" && "%{_arch}" != "i386") ? "-Cforce-frame-pointers=yes" : ""} %[0%{?_package_note_status} ? "-Clink-arg=%_package_note_flags" : ""] } # __cargo: cargo command with environment variables # # CARGO_HOME: This ensures cargo reads configuration file from .cargo/config, # and prevents writing any files to $HOME during RPM builds. %__cargo /usr/bin/env CARGO_HOME=.cargo RUSTFLAGS='%{build_rustflags}' /usr/bin/cargo # __cargo_common_opts: common command line flags for cargo # # _smp_mflags: run builds and tests in parallel %__cargo_common_opts %{?_smp_mflags} # cargo_prep: macro to set up build environment for cargo projects # # This involves four steps: # - create the ".cargo" directory if it doesn't exist yet # - dump custom cargo configuration into ".cargo/config" # - remove "Cargo.lock" if it exists (it breaks builds with custom cargo config) # - remove "Cargo.toml.orig" if it exists (it breaks running "cargo package") # # Options: # -V - unpack and use vendored sources from Source tarball # (deprecated; use -v instead) # -v - use vendored sources from # -N - Don't set up any registry. Only set up the build configuration. %cargo_prep(V:v:N)\ %{-v:%{-V:%{error:-v and -V are mutually exclusive!}}}\ %{-v:%{-N:%{error:-v and -N are mutually exclusive!}}}\ (\ set -euo pipefail\ %{__mkdir} -p target/rpm\ /usr/bin/ln -s rpm target/release\ %{__rm} -rf .cargo/\ %{__mkdir} -p .cargo\ cat > .cargo/config << EOF\ [build]\ rustc = "%{__rustc}"\ rustdoc = "%{__rustdoc}"\ \ [profile.rpm]\ inherits = "release"\ opt-level = %{rustflags_opt_level}\ codegen-units = %{rustflags_codegen_units}\ debug = %{rustflags_debuginfo}\ strip = "none"\ \ [env]\ CFLAGS = "%{build_cflags}"\ CXXFLAGS = "%{build_cxxflags}"\ LDFLAGS = "%{build_ldflags}"\ \ [install]\ root = "%{buildroot}%{_prefix}"\ \ [term]\ verbose = true\ EOF\ %{-V:%{__tar} -xoaf %{S:%{-V*}}}\ %{!?-N:\ cat >> .cargo/config << EOF\ [source.vendored-sources]\ directory = "%{-v*}%{-V:./vendor}"\ \ [source.crates-io]\ registry = "https://crates.io"\ replace-with = "vendored-sources"\ EOF}\ %{__rm} -f Cargo.toml.orig\ ) # __cargo_parse_opts: function-like macro which parses common flags into the # equivalent command-line flags for cargo %__cargo_parse_opts(naf:) %{shrink:\ %{-n:%{-a:%{error:Can't specify both -n and -a}}} \ %{-f:%{-a:%{error:Can't specify both -f(%{-f*}) and -a}}} \ %{-n:--no-default-features} \ %{-a:--all-features} \ %{-f:--features %{-f*}} \ %{nil} \ } # cargo_build: builds the crate with cargo with the specified feature flags %cargo_build(naf:)\ %{shrink: \ %{__cargo} build \ %{__cargo_common_opts} \ --profile rpm \ %{__cargo_parse_opts %{-n} %{-a} %{-f:-f%{-f*}}} \ %* \ } # cargo_test: runs the test suite with cargo with the specified feature flags # # To pass command-line arguments to the cargo test runners directly (for # example, to skip certain tests during package builds), both the cargo_test # macro argument parsing and "cargo test" argument parsing need to be bypassed, # i.e. "%%cargo_test -- -- --skip foo" for skipping all tests with names that # match "foo". %cargo_test(naf:)\ %{shrink: \ %{__cargo} test \ %{__cargo_common_opts} \ --profile rpm \ --no-fail-fast \ %{__cargo_parse_opts %{-n} %{-a} %{-f:-f%{-f*}}} \ %* \ } # cargo_install: install files into the buildroot # # For "binary" crates, this macro installs all "bin" build targets to _bindir # inside the buildroot. The "--no-track" option prevents the creation of the # "$CARGO_HOME/.crates.toml" file, which is used to keep track of which version # of a specific binary has been installed, but which conflicts between builds # of different Rust applications and is not needed when building RPM packages. %cargo_install(t:naf:)\ (\ set -euo pipefail \ %{shrink: \ %{__cargo} install \ %{__cargo_common_opts} \ --profile rpm \ --no-track \ --path . \ %{__cargo_parse_opts %{-n} %{-a} %{-f:-f%{-f*}}} \ %* \ } \ ) # cargo_license: print license information for all crate dependencies # # The "no-build,no-dev,no-proc-macro" argument results in only crates which are # linked into the final binary to be considered. # # Additionally, deprecated SPDX syntax ("/" instead of "OR") is normalized # before sorting the results to ensure reproducible output of this macro. # # This macro must be called with the same feature flags as other cargo macros, # in particular, "cargo_build", otherwise its output will be incomplete. # # The "cargo tree" command called by this macro will fail if there are missing # (optional) dependencies. %cargo_license(naf:)\ (\ set -euo pipefail\ %{shrink: \ %{__cargo} tree \ --workspace \ --offline \ --edges no-build,no-dev,no-proc-macro \ --no-dedupe \ %{__cargo_parse_opts %{-n} %{-a} %{-f:-f%{-f*}}} \ --prefix none \ --format "{l}: {p}" \ | sed -e "s: ($(pwd)[^)]*)::g" -e "s: / :/:g" -e "s:/: OR :g" \ | sort -u \ }\ ) # cargo_license_summary: print license summary for all crate dependencies # # This macro works in the same way as cargo_license, except that it only prints # a list of licenses, and not the complete license information for every crate # in the dependency tree. This is useful for determining the correct License # tag for packages that contain compiled Rust binaries. %cargo_license_summary(naf:)\ (\ set -euo pipefail\ %{shrink: \ %{__cargo} tree \ --workspace \ --offline \ --edges no-build,no-dev,no-proc-macro \ --no-dedupe \ %{__cargo_parse_opts %{-n} %{-a} %{-f:-f%{-f*}}} \ --prefix none \ --format "# {l}" \ | sed -e "s: / :/:g" -e "s:/: OR :g" \ | sort -u \ }\ ) # cargo_vendor_manifest: write list of vendored crates and their versions # # The arguments for the internal "cargo tree" call emulate the logic # that determines which crates are included when running "cargo vendor". # The results are written to "cargo-vendor.txt". # # TODO: --all-features may be overly broad; this should be modified to # use %%__cargo_parse_opts to handle feature flags. %cargo_vendor_manifest()\ (\ set -euo pipefail\ %{shrink: \ %{__cargo} tree \ --workspace \ --offline \ --edges normal,build \ --no-dedupe \ --all-features \ --prefix none \ --format "{p}" \ | grep -v "$(pwd)" \ | sed -e "s: (proc-macro)::" \ | sort -u \ > cargo-vendor.txt \ }\ )