# Copyright 1999-2026 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 EAPI=8 # PREBUILT PACKAGING NOTES -- READ BEFORE A VERSION BUMP. # # 1) Why a -bin at all, when ::gentoo already has sys-apps/uutils-coreutils: # the from-source ebuild pulls ~400 crates and a Rust toolchain. Upstream # publishes official binaries for every release, so users who only want the # utilities (containers, edge boxes, arm64 SBCs, machines with no Rust) # should not have to compile them. This package installs exactly the same # file layout as the from-source one, so the two are interchangeable. # # 2) Why musl builds on arm64/riscv but a glibc build on amd64/x86: # upstream ships NO aarch64-*-linux-gnu or riscv64-*-linux-gnu tarball -- # only *-linux-musl, which is statically linked and therefore runs fine on # a glibc system. On amd64/x86 the glibc build is preferred because a # statically linked musl binary resolves users and groups through musl's # own minimal NSS: it reads /etc/passwd and /etc/group directly and cannot # consult nsswitch.conf modules (LDAP, SSSD, systemd-userdb). That would # silently change the output of `uu-ls -l`, `uu-id` and `uu-chown` on hosts # with networked accounts. Verified glibc floors (objdump -T): # x86_64-unknown-linux-gnu -> GLIBC_2.39 # i686-unknown-linux-gnu -> GLIBC_2.18 # Re-check those on a bump; if the floor ever exceeds the oldest glibc in # ::gentoo, switch that arch over to its musl tarball. # # 3) Why the applet list is derived from the man pages and not from # `coreutils --list`: # running the payload at build time would break every cross-arch build. # docs.tar.zst is architecture independent and carries one man page per # applet, so it is the portable source of truth. Two names in it are NOT # multicall applets and are filtered out below: "coreutils" (the multicall # binary itself) and "stdbuf" (it needs libstdbuf.so in libexec, which the # release tarballs do not ship -- confirmed absent from `coreutils --list`). # # 4) Why the completion files are rewritten with sed: # upstream generates them for the unprefixed command name ("#compdef ls", # "complete -F _ls ... ls") and merely renames the file to uu-ls. That # registers the completion against GNU ls instead of uu-ls. The seds below # retarget them at the installed name. This is a deliberate improvement # over upstream's own install rule, not an oversight. # # 5) l10n: translations live in the source tree, not in the binary tarballs. # Release builds look them up at /share/locales/, i.e. the # very path the source ebuild installs to -- verified at runtime by running # the shipped binary against a synthetic prefix. en-US is compiled into the # binary, so only the extra locales are installed. 0.10.0 ships fr-FR only. # 6) Why src_unpack is overridden: # PMS does not list .tar.zst among the suffixes that unpack() understands, # not even in EAPI 8, so portage silently skips docs.tar.zst with a mere # "=== Skipping unpack" and the man pages never reach ${WORKDIR}. # unpacker.eclass knows the format. inherit bash-completion-r1 optfeature unpacker MY_PN="${PN%-bin}" MY_BASE="https://github.com/uutils/coreutils/releases/download/${PV}" DESCRIPTION="GNU coreutils rewritten in Rust (prebuilt upstream binaries)" HOMEPAGE="https://uutils.github.io/coreutils/ https://github.com/uutils/coreutils" SRC_URI=" amd64? ( elibc_glibc? ( ${MY_BASE}/coreutils-${PV}-x86_64-unknown-linux-gnu.tar.gz ) elibc_musl? ( ${MY_BASE}/coreutils-${PV}-x86_64-unknown-linux-musl.tar.gz ) ) arm64? ( ${MY_BASE}/coreutils-${PV}-aarch64-unknown-linux-musl.tar.gz ) riscv? ( ${MY_BASE}/coreutils-${PV}-riscv64gc-unknown-linux-musl.tar.gz ) x86? ( elibc_glibc? ( ${MY_BASE}/coreutils-${PV}-i686-unknown-linux-gnu.tar.gz ) elibc_musl? ( ${MY_BASE}/coreutils-${PV}-i686-unknown-linux-musl.tar.gz ) ) ${MY_BASE}/docs.tar.zst -> ${MY_PN}-${PV}-docs.tar.zst l10n_fr? ( https://github.com/uutils/coreutils/archive/refs/tags/${PV}.tar.gz -> ${MY_PN}-${PV}.tar.gz ) " S="${WORKDIR}" LICENSE="MIT" # Dependent crate licenses, statically linked into the payload. Kept in sync # with the from-source ebuild -- regenerate with pycargoebuild on a bump. LICENSE+=" Apache-2.0 BSD-2 BSD CC0-1.0 ISC MIT MPL-2.0 Unicode-3.0 ZLIB " SLOT="0" KEYWORDS="-* ~amd64 ~arm64 ~riscv ~x86" IUSE="l10n_fr" RDEPEND="!sys-apps/uutils-coreutils" BDEPEND="app-arch/zstd" RESTRICT="strip" QA_PREBUILT="usr/bin/uu-coreutils" src_unpack() { # See note 6. unpacker_src_unpack } src_install() { local target if use amd64 ; then target=x86_64-unknown-linux-$(usex elibc_musl musl gnu) elif use x86 ; then target=i686-unknown-linux-$(usex elibc_musl musl gnu) elif use arm64 ; then target=aarch64-unknown-linux-musl elif use riscv ; then target=riscv64gc-unknown-linux-musl else die "no upstream binary for this arch; use sys-apps/uutils-coreutils instead" fi local payload="${WORKDIR}/coreutils-${PV}-${target}" newbin "${payload}/coreutils" uu-coreutils dodoc "${payload}"/README.md # See note 3: the man page names are the portable applet list. local progs=() prog for prog in "${WORKDIR}"/share/man/man1/*.1 ; do prog=$(basename "${prog}" .1) [[ ${prog} == coreutils || ${prog} == stdbuf ]] && continue progs+=( "${prog}" ) done [[ ${#progs[@]} -ge 100 ]] || die "only ${#progs[@]} applets found in docs.tar.zst -- layout changed?" # The list already contains `[`, which ships its own man page. for prog in "${progs[@]}" ; do dosym uu-coreutils /usr/bin/"uu-${prog}" done doman "${WORKDIR}"/share/man/man1/coreutils.1 mv "${ED}"/usr/share/man/man1/{,uu-}coreutils.1 || die for prog in "${progs[@]}" ; do newman "${WORKDIR}/share/man/man1/${prog}.1" "uu-${prog}.1" done # See note 4: retarget the completions at the uu- prefixed command. local esc for prog in "${progs[@]}" ; do # `[` is a regex metacharacter; escape it for the seds below. esc=${prog//\[/\\[} if [[ -f ${WORKDIR}/share/bash-completion/completions/${prog}.bash ]] ; then sed -e "s/ ${esc}\$/ uu-${prog}/" \ "${WORKDIR}/share/bash-completion/completions/${prog}.bash" \ > "${T}/uu-${prog}" || die newbashcomp "${T}/uu-${prog}" "uu-${prog}" fi if [[ -f ${WORKDIR}/share/zsh/site-functions/_${prog} ]] ; then sed -e "s/^#compdef ${esc}\$/#compdef uu-${prog}/" \ -e "s/^\(\s*compdef _${esc}\) ${esc}\$/\1 uu-${prog}/" \ "${WORKDIR}/share/zsh/site-functions/_${prog}" \ > "${T}/_uu-${prog}" || die insinto /usr/share/zsh/site-functions doins "${T}/_uu-${prog}" fi if [[ -f ${WORKDIR}/share/fish/vendor_completions.d/${prog}.fish ]] ; then sed -e "s/^complete -c ${esc}\b/complete -c uu-${prog}/" \ "${WORKDIR}/share/fish/vendor_completions.d/${prog}.fish" \ > "${T}/uu-${prog}.fish" || die insinto /usr/share/fish/vendor_completions.d doins "${T}/uu-${prog}.fish" fi done # See note 5. uucore holds the strings shared by every applet; the rest # are per applet, and only the applets this binary actually carries are # installed (the source tree also has locales for stdbuf and runcon). if use l10n_fr ; then local dir for prog in "${progs[@]}" uucore ; do dir="${WORKDIR}/coreutils-${PV}/src/uu/${prog}/locales" [[ ${prog} == uucore ]] && dir="${WORKDIR}/coreutils-${PV}/src/uucore/locales" [[ -f ${dir}/fr-FR.ftl ]] || continue insinto "/usr/share/locales/${prog}" doins "${dir}"/fr-FR.ftl done fi } pkg_postinst() { elog "Every utility is installed with an 'uu-' prefix (uu-ls, uu-cp, ...)" elog "so this package does not shadow sys-apps/coreutils. The multicall" elog "binary itself is /usr/bin/uu-coreutils; run 'uu-coreutils --list'" elog "for the full set of applets." elog elog "'stdbuf' is not available here: it needs a helper library that" elog "upstream does not ship in the release tarballs. Build" elog "sys-apps/uutils-coreutils from source if you need it." if use elibc_glibc && ( use arm64 || use riscv ) ; then ewarn "Upstream publishes no glibc binary for this arch, so the" ewarn "statically linked musl build was installed. It resolves users" ewarn "and groups from /etc/passwd and /etc/group only -- NSS modules" ewarn "such as LDAP, SSSD or systemd-userdb are ignored by uu-ls -l," ewarn "uu-id and uu-chown. Build sys-apps/uutils-coreutils from source" ewarn "if your system uses networked accounts." fi optfeature "shell completions" app-shells/bash-completion }