#!/usr/bin/make -f include /usr/share/dpkg/architecture.mk include /usr/share/dpkg/buildflags.mk include /usr/share/rustc/architecture.mk export CFLAGS CXXFLAGS CPPFLAGS LDFLAGS export DEB_HOST_RUST_TYPE DEB_HOST_GNU_TYPE export CARGO_PROFILE_RELEASE_DEBUG=true # stdbuf needs libstdbuf.so; upstream's GNUmakefile builds it with # feat_external_libstdbuf and installs it into LIBSTDBUF_DIR. export LIBSTDBUF_DIR = /usr/libexec/rust-coreutils # who/pinky read the session list from logind rather than utmp on systemd # systems, so build with the logind backend enabled. export CARGOFLAGS += --features feat_systemd_logind # libcrypto for the cksum/md5sum/sha*sum digests: much faster on CPUs without # the SHA extensions. OPENSSL_NO_VENDOR links Debian's shared libcrypto instead # of building the vendored openssl-src copy. export CARGOFLAGS += --features openssl export OPENSSL_NO_VENDOR = 1 export CARGOFLAGS += --features feat_diagnostics # Use lld whenever it is available: it links the big multicall binary much # faster than GNU ld. Fall back to the default linker on arches where lld is # not installed. Always ask the linker to print its version banner (-Wl,-v) # so the build log records which linker actually ran. LLD := $(shell command -v ld.lld 2>/dev/null) ifneq ($(LLD),) export RUSTFLAGS = -C link-arg=-fuse-ld=lld -C link-arg=-Wl,-v else export RUSTFLAGS = -C link-arg=-Wl,-v endif # Fat LTO + 1 codegen unit + full debuginfo of the giant multicall crate is # fatal on some arches: s390x hits the 150min buildd timeout, 32-bit arches OOM # on the ~3GB address space ("rustc-LLVM ERROR: out of memory"). Set the cargo # profile env overrides so they apply to every cargo invocation (build, test, # install), unlike a Cargo.toml sed that only wraps one step. ifeq ($(DEB_HOST_ARCH),s390x) export CARGO_PROFILE_RELEASE_LTO = false export CARGO_PROFILE_RELEASE_CODEGEN_UNITS = 16 export CARGO_PROFILE_RELEASE_DEBUG = 1 endif ifeq ($(DEB_HOST_ARCH_BITS),32) export CARGO_PROFILE_RELEASE_LTO = thin export CARGO_PROFILE_RELEASE_CODEGEN_UNITS = 16 export CARGO_PROFILE_RELEASE_DEBUG = 1 endif # PGO: instrument, train with util/build-pgo.sh, rebuild with -Cprofile-use. # Doubles the build time and has to run the instrumented binary, hence 64-bit # and native only. Opt out with DEB_BUILD_OPTIONS=nopgo. PGO_ARCHS = amd64 arm64 PGO_DIR = $(CURDIR)/debian/pgo PGO_PROFDATA = $(PGO_DIR)/coreutils.profdata # llvm-profdata must match the LLVM rustc was built against: only it can read # the .profraw files. Debian ships it in llvm-, rustup in its sysroot. LLVM_MAJOR := $(shell rustc --version --verbose | sed -n 's/^LLVM version: \([0-9]*\).*/\1/p') RUST_SYSROOT := $(shell rustc --print sysroot) LLVM_PROFDATA := $(firstword $(wildcard \ /usr/lib/llvm-$(LLVM_MAJOR)/bin/llvm-profdata \ $(RUST_SYSROOT)/lib/rustlib/$(DEB_HOST_RUST_TYPE)/bin/llvm-profdata)) ifeq (,$(filter nopgo,$(DEB_BUILD_OPTIONS))) ifeq ($(DEB_BUILD_ARCH),$(DEB_HOST_ARCH)) ifneq (,$(filter $(DEB_HOST_ARCH),$(PGO_ARCHS))) ifneq (,$(LLVM_PROFDATA)) PGO = y endif endif endif endif ifeq ($(PGO),y) # On both the test and install steps, so they share one set of artifacts. PGO_RUSTFLAGS = -C profile-use=$(PGO_PROFDATA) endif VERSION := $(shell dpkg-parsechangelog -S Version|sed -e "s|.*~\(.*\)-.*|\1|g") UPSTREAM_VERSION := $(shell dpkg-parsechangelog -S Version|cut -d- -f1) # Build a multicall binary instead of multiple binaries # to reduce the storage footprint export MULTICALL = y # Vendoring setup. # The crates are NOT part of the upstream tarball (which is the pristine # GitHub tag): they are vendored into debian/rust-vendor by the 'vendor' # target below and shipped in the .debian.tar. This is what the Ubuntu # package does, so the two stay mergeable. export CARGO_VENDOR_DIR = debian/rust-vendor export CARGO_HOME = $(CURDIR)/debian/cargo_home # Configure dh_quilt_patch for applying vendor patches. # This allows debian/rust-vendor/ to be patched without dpkg-source issues. export QUILT_PATCH_DIR = debian/patches/rust-vendor export QUILT_PC = debian/rust-vendor/.pc %: dh $@ --buildsystem cargo override_dh_auto_configure: # The translations live in a separate upstream repository and are shipped # as a component tarball; without them the package would silently build # without any localisation. @if [ ! -d l10n/src ]; then \ echo "Error: l10n translations not found! Run 'uscan' to download the l10n tarball." >&2; \ exit 1; \ fi # The tldr examples embedded in the manpages (see improve-man.diff) come # from the tldr-pages release shipped in debian/, since the upstream # tarball does not contain it and the build has no network access. cp debian/tldr.zip docs/tldr.zip dh_auto_configure # Debian's dh-cargo hardcodes "prepare-debian debian/cargo_registry # --link-from-system" in its configure step, while Ubuntu's honours # CARGO_VENDOR_DIR. Point cargo back at our vendor directory afterwards # so the build uses the same crates on both distributions. DEB_CARGO_CRATE=coreutils_$(VERSION) /usr/share/cargo/bin/cargo prepare-debian $(CARGO_VENDOR_DIR) # dh-cargo-vendored-sources only exists in Ubuntu's dh-cargo; it checks # XS-Vendored-Sources-Rust against the vendor directory. Run it when it # is there so the Ubuntu build behaves exactly as before. [ ! -x /usr/share/cargo/bin/dh-cargo-vendored-sources ] || /usr/share/cargo/bin/dh-cargo-vendored-sources dh_quilt_patch .PHONY: vendor # Maintainer-side target: regenerate debian/rust-vendor. Needs # cargo-vendor-filterer, which is not packaged in Debian: # cargo install cargo-vendor-filterer # Run it after every new upstream import, then commit the result. vendor: rm -rf $(CARGO_VENDOR_DIR) # Deliberately don't use the wrapper, as it expects the configure step # to have occurred already. # If you have to modify the path here, don't forget to change the # README.source doc as well. # PATH/HOME are kept so that a cargo-vendor-filterer installed with # 'cargo install' is found and can reach the registry cache; everything # else (CARGO_HOME, CARGO_VENDOR_DIR, ...) is deliberately cleared. env -i PATH="$$PATH" HOME="$$HOME" cargo-vendor-filterer --all-features --tier 2 --platform '*-*-linux-gnu' --platform '*-*-linux-gnueabi' $(CARGO_VENDOR_DIR) # Blank the checksum lists. Two reasons: it lets us patch the crates, and # dpkg-source drops VCS files (.gitmodules & co) from the .debian.tar, so a # crate shipping one would otherwise fail with "failed to calculate # checksum". Rewritten with json, not sed: cargo-vendor-filterer has since # added a "$comment" key and a line-anchored regexp silently skips those. @$(CURDIR)/debian/blank-vendor-checksums.py $(CARGO_VENDOR_DIR) # cargo-vendor-filterer keeps the crates' pre-publish Cargo.toml.orig; # cargo never reads it and lintian flags it as debian-adds-patch-failure-file. find $(CARGO_VENDOR_DIR) -name Cargo.toml.orig -delete # Cleanup temp files rm -rf $(CARGO_HOME) # Update include-binaries rm -f debian/source/include-binaries dpkg-source --include-binaries -b . # Update XS-Vendored-Sources-Rust field. Ubuntu generates it with # dh-cargo-vendored-sources; that helper is not in Debian's dh-cargo, so # read the crate names out of the vendor directory instead. python3 debian/update-vendored-sources-field.py # Commit changes git add -f $(CARGO_VENDOR_DIR) git commit -m "Update vendored rust crates" || true git add debian/source/ git commit -m "Update debian/source/include-binaries" || true git add debian/control git commit debian/control -m "Update XS-Vendored-Sources-Rust field" || true override_dh_auto_build: dh_auto_build ifeq ($(PGO),y) # Step 1: the instrumented binary, built with *exactly* the command that # builds the shipped one. A profile only applies to a matching build: with # a different feature set the symbols differ, -Cprofile-use finds no data # and PGO silently does nothing. Hence not the script's own step 1, which # builds "--features unix" (see d/p/pgo-use-prebuilt-binary.patch). CARGO_TARGET_DIR=$(PGO_DIR)/instrumented \ RUSTFLAGS="$(RUSTFLAGS) -C profile-generate=$(PGO_DIR)/profiles --cfg pgo_training" \ CARGO_HOME=$(CURDIR)/debian/cargo_home \ make SELINUX_ENABLED=1 PROFILE=release MULTICALL=$(MULTICALL) build-coreutils # Steps 2-4: corpus, training workloads, merge. The optimized build is the # package's own, via PGO_RUSTFLAGS. util/build-pgo.sh --train-only \ --target-dir $(PGO_DIR) \ --instrumented-binary $(PGO_DIR)/instrumented/release/coreutils \ --llvm-profdata $(LLVM_PROFDATA) test -f $(PGO_PROFDATA) # Several GB, and nothing downstream needs it. rm -rf $(PGO_DIR)/instrumented else @echo "PGO disabled on $(DEB_HOST_ARCH) (or by DEB_BUILD_OPTIONS=nopgo)" endif override_dh_auto_test: ifeq ($(DEB_HOST_ARCH),s390x) # The release test build (every util + every test) is what actually hits # the buildd inactivity timeout on s390x. Tests are non-gating here (||true) # anyway, so skip them and rely on the other arches for coverage. @echo "Skipping the test suite on s390x to stay under the buildd timeout" else # for now, don't fail the build if tests are failing RUSTFLAGS="$(RUSTFLAGS) $(PGO_RUSTFLAGS)" CARGO_HOME=$(CURDIR)/debian/cargo_home make PROFILE=release MULTICALL=$(MULTICALL) test||true endif override_dh_auto_install: # The vendor directory is prepared once in override_dh_auto_configure. # LTO/debuginfo/codegen are handled globally via CARGO_PROFILE_RELEASE_* env # overrides at the top of this file, so no Cargo.toml editing is needed here. RUSTFLAGS="$(RUSTFLAGS) $(PGO_RUSTFLAGS)" CARGO_HOME=$(CURDIR)/debian/cargo_home DESTDIR=$(CURDIR)/debian/tmp/ make SELINUX_ENABLED=1 PROFILE=release MULTICALL=$(MULTICALL) install # Create the symlink early to be able to generate the manpages cd debian/tmp/usr/share/zsh/site-functions && mkdir rust-coreutils && chmod -x _* && mv _* rust-coreutils cd debian/tmp/usr/share/bash-completion/completions/ && chmod -x rust-* cd debian/tmp/usr/share/fish/vendor_completions.d/ && chmod -x *.fish cd debian/tmp/usr/bin && mv rust-coreutils coreutils && rm rust-* # cd debian/tmp/usr/share/fish/vendor_completions.d && for f in *fish; do mv $$f rust-$$f; done dh_link override_dh_missing: dh_missing --fail-missing override_dh_fixperms: dh_fixperms # A shared library is not executable. chmod 0644 debian/rust-coreutils/usr/libexec/rust-coreutils/libstdbuf.so override_dh_dwz: # Don't do anything. fails because of the # https://github.com/rust-lang/rust/issues/66118 execute_after_dh_auto_configure: # Log the toolchain and linker up front, on every arch, so the build log # always records which linker was used - even if a later step times out # before any link runs. The leading '-' keeps the build going on the rare # arch where ld.lld is absent (we fall back to the default linker there). rustc --version --verbose -ld.lld --version -ld --version | head -n1 override_dh_clean: dh_quilt_unpatch rm -rf $(PGO_DIR) rm -f Cargo.toml.orig docs/tldr.zip dh_clean --exclude=Cargo.toml.orig --exclude=config.guess override_dh_update_autotools_config: # don't do anything - impact vendoring otherwise