summaryrefslogtreecommitdiff
path: root/eclass
diff options
context:
space:
mode:
Diffstat (limited to 'eclass')
-rw-r--r--eclass/ada.eclass2
-rw-r--r--eclass/dist-kernel-utils.eclass25
-rw-r--r--eclass/ecm.eclass193
-rw-r--r--eclass/elisp-common.eclass55
-rw-r--r--eclass/elisp.eclass2
-rw-r--r--eclass/frameworks.kde.org.eclass68
-rw-r--r--eclass/gear.kde.org.eclass15
-rw-r--r--eclass/gstreamer-meson.eclass20
-rw-r--r--eclass/guile-utils.eclass6
-rw-r--r--eclass/java-pkg-2.eclass6
-rw-r--r--eclass/java-pkg-simple.eclass4
-rw-r--r--eclass/kde.org.eclass10
-rw-r--r--eclass/kernel-build.eclass97
-rw-r--r--eclass/kernel-install.eclass86
-rw-r--r--eclass/latex-package.eclass16
-rw-r--r--eclass/linux-mod-r1.eclass6
-rw-r--r--eclass/llvm-r1.eclass2
-rw-r--r--eclass/llvm-r2.eclass476
-rw-r--r--eclass/llvm-utils.eclass27
-rw-r--r--eclass/llvm.org.eclass13
-rw-r--r--eclass/mono-env.eclass2
-rw-r--r--eclass/mount-boot-utils.eclass16
-rw-r--r--eclass/office-ext-r1.eclass28
-rw-r--r--eclass/plasma.kde.org.eclass11
-rw-r--r--eclass/qt6-build.eclass4
-rw-r--r--eclass/ruby-fakegem.eclass14
-rw-r--r--eclass/ruby-utils.eclass4
-rw-r--r--eclass/rust.eclass30
-rw-r--r--eclass/secureboot.eclass149
-rwxr-xr-xeclass/tests/llvm-r1.sh70
-rwxr-xr-xeclass/tests/llvm-r2.sh188
-rwxr-xr-xeclass/tests/zig-utils.sh320
-rw-r--r--eclass/texlive-module.eclass15
-rw-r--r--eclass/toolchain-funcs.eclass44
-rw-r--r--eclass/toolchain.eclass123
-rw-r--r--eclass/verify-sig.eclass34
-rw-r--r--eclass/xorg-3.eclass9
-rw-r--r--eclass/zig-utils.eclass559
-rw-r--r--eclass/zig.eclass559
39 files changed, 2917 insertions, 391 deletions
diff --git a/eclass/ada.eclass b/eclass/ada.eclass
index 9206bfcc42ca..3d22dd5d2a61 100644
--- a/eclass/ada.eclass
+++ b/eclass/ada.eclass
@@ -282,7 +282,7 @@ ada_export() {
debug-print "${FUNCNAME}: GNATBIND = ${GNATBIND}"
;;
GNATMAKE)
- export GNATMAKE=${EPREFIX}/usr/bin/gnatmake-${gcc_pv}
+ export GNATMAKE=${EPREFIX}/usr/bin/${CHOST}-gnatmake-${gcc_pv}
debug-print "${FUNCNAME}: GNATMAKE = ${GNATMAKE}"
;;
GNATLS)
diff --git a/eclass/dist-kernel-utils.eclass b/eclass/dist-kernel-utils.eclass
index 210c586c8c29..3d7315e9e94e 100644
--- a/eclass/dist-kernel-utils.eclass
+++ b/eclass/dist-kernel-utils.eclass
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 Gentoo Authors
+# Copyright 2020-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: dist-kernel-utils.eclass
@@ -82,12 +82,33 @@ dist-kernel_install_kernel() {
local success=
# not an actual loop but allows error handling with 'break'
while true; do
+ if [[ -n ${ROOT} ]] && in_iuse initramfs && use initramfs; then
+ if ! in_iuse generic-uki || ! use generic-uki; then
+ eerror
+ eerror "ROOT is set, and (re-)generation of an initramfs is requested"
+ eerror "via the USE=initramfs flag. However, this is currently not"
+ eerror "supported via the sys-kernel/installkernel mechanism."
+ eerror
+ if in_iuse generic-uki && ! use generic-uki; then
+ eerror "Generation and installation of a generic initramfs and/or"
+ eerror "Unified Kernel Image is possible via portage by enabling the"
+ eerror "USE=generic-uki flag. Please enable the generic-uki flag, or"
+ eerror "chroot into: ROOT=${ROOT}"
+ else
+ eerror "Please chroot into: ROOT=${ROOT}"
+ fi
+ break
+ fi
+ fi
+
nonfatal mount-boot_check_status || break
+ mkdir -p "${EROOT}/boot" || break
ebegin "Installing the kernel via installkernel"
# note: .config is taken relatively to System.map;
# initrd relatively to bzImage
- ARCH=$(tc-arch-kernel) installkernel "${version}" "${image}" "${map}" || break
+ ARCH=$(tc-arch-kernel) installkernel "${version}" "${image}" "${map}" \
+ "${EROOT}/boot" || break
eend ${?} || die -n "Installing the kernel failed"
success=1
diff --git a/eclass/ecm.eclass b/eclass/ecm.eclass
index fbe1a23cf205..e433952903e8 100644
--- a/eclass/ecm.eclass
+++ b/eclass/ecm.eclass
@@ -29,7 +29,7 @@ esac
if [[ -z ${_ECM_ECLASS} ]]; then
_ECM_ECLASS=1
-inherit cmake flag-o-matic toolchain-funcs
+inherit cmake flag-o-matic
if [[ ${EAPI} == 8 ]]; then
# @ECLASS_VARIABLE: VIRTUALX_REQUIRED
@@ -39,23 +39,18 @@ if [[ ${EAPI} == 8 ]]; then
# for tests you should proceed with setting VIRTUALX_REQUIRED=test.
: "${VIRTUALX_REQUIRED:=manual}"
-inherit virtualx
+inherit toolchain-funcs virtualx
fi
# @ECLASS_VARIABLE: ECM_NONGUI
-# @DEFAULT_UNSET
# @DESCRIPTION:
# By default, for all CATEGORIES except kde-frameworks, assume we are building
# a GUI application. Add dependency on kde-frameworks/breeze-icons or
-# kde-frameworks/oxygen-icons and run the xdg.eclass routines for pkg_preinst,
-# pkg_postinst and pkg_postrm. If set to "true", do nothing.
-if [[ ${CATEGORY} = kde-frameworks ]] ; then
- : "${ECM_NONGUI:=true}"
-fi
+# kde-frameworks/oxygen-icons. With KFMIN lower than 6.9.0, inherit xdg.eclass,
+# run pkg_preinst, pkg_postinst and pkg_postrm. If set to "true", do nothing.
: "${ECM_NONGUI:=false}"
-
-if [[ ${ECM_NONGUI} = false ]] ; then
- inherit xdg
+if [[ ${CATEGORY} == kde-frameworks ]]; then
+ ECM_NONGUI=true
fi
# @ECLASS_VARIABLE: ECM_KDEINSTALLDIRS
@@ -104,11 +99,25 @@ fi
: "${ECM_HANDBOOK_DIR:=doc}"
# @ECLASS_VARIABLE: ECM_PO_DIRS
+# @PRE_INHERIT
# @DESCRIPTION:
# Specifies directories of l10n files relative to ${S} to be processed by
# KF${_KFSLOT}I18n (ki18n_install). If IUSE nls exists and is disabled then
# disable build of these directories in CMakeLists.txt.
-: "${ECM_PO_DIRS:="po poqm"}"
+if [[ ${ECM_PO_DIRS} ]]; then
+ [[ ${ECM_PO_DIRS@a} == *a* ]] ||
+ die "ECM_PO_DIRS must be an array"
+else
+ ECM_PO_DIRS=( po poqm )
+fi
+
+# @ECLASS_VARIABLE: ECM_PYTHON_BINDINGS
+# @DESCRIPTION:
+# Default value is "false", which means do nothing.
+# If set to "off", pass -DBUILD_PYTHON_BINDINGS=OFF to mycmakeargs, and also
+# disable cmake finding Python3, PySide6 and Shiboken6 to make it quiet.
+# No other value is implemented as python bindings are not supported in Gentoo.
+: "${ECM_PYTHON_BINDINGS:=false}"
# @ECLASS_VARIABLE: ECM_QTHELP
# @DEFAULT_UNSET
@@ -155,16 +164,21 @@ fi
: "${ECM_TEST:=false}"
# @ECLASS_VARIABLE: KFMIN
+# @PRE_INHERIT
# @DEFAULT_UNSET
# @DESCRIPTION:
# Minimum version of Frameworks to require. Default value for kde-frameworks
-# is ${PV} and 5.106.0 baseline for everything else.
+# is ${PV} and 5.116.0 baseline for everything else.
# If set to >=5.240, KF6/Qt6 is assumed thus SLOT=6 dependencies added and
# -DQT_MAJOR_VERSION=6 added to cmake args.
if [[ ${CATEGORY} = kde-frameworks ]]; then
: "${KFMIN:=$(ver_cut 1-2)}"
fi
-: "${KFMIN:=5.106.0}"
+: "${KFMIN:=5.116.0}"
+
+if ver_test ${KFMIN} -lt 6.9 && [[ ${ECM_NONGUI} == false ]]; then
+ inherit xdg
+fi
# @ECLASS_VARIABLE: _KFSLOT
# @INTERNAL
@@ -175,15 +189,21 @@ fi
# prefixed cmake args.
: "${_KFSLOT:=5}"
if [[ ${CATEGORY} == kde-frameworks ]]; then
- if [[ ${PV} != 5.9999 ]] && $(ver_test ${KFMIN} -ge 5.240); then
- _KFSLOT=6
- fi
+ ver_test ${KFMIN} -ge 5.240 && _KFSLOT=6
else
if [[ ${KFMIN/.*} == 6 ]] || $(ver_test ${KFMIN} -ge 5.240); then
_KFSLOT=6
fi
fi
+# @ECLASS_VARIABLE: KDE_GCC_MINIMAL
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Minimum version of active GCC to require. This is checked in
+# ecm_pkg_pretend and ecm_pkg_setup.
+[[ ${KDE_GCC_MINIMAL} ]] && ver_test ${KFMIN} -ge 6.9 &&
+ die "KDE_GCC_MINIMAL has been banned with KFMIN >=6.9.0."
+
case ${ECM_NONGUI} in
true) ;;
false)
@@ -249,6 +269,15 @@ case ${ECM_HANDBOOK} in
;;
esac
+case ${ECM_PYTHON_BINDINGS} in
+ off|false) ;;
+ true) ;& # TODO if you really really want
+ *)
+ eerror "Unknown value for \${ECM_PYTHON_BINDINGS}"
+ die "Value ${ECM_PYTHON_BINDINGS} is not supported"
+ ;;
+esac
+
case ${ECM_QTHELP} in
true)
IUSE+=" doc"
@@ -305,30 +334,6 @@ DEPEND+=" ${COMMONDEPEND}"
RDEPEND+=" ${COMMONDEPEND}"
unset COMMONDEPEND
-# @ECLASS_VARIABLE: KDE_GCC_MINIMAL
-# @DEFAULT_UNSET
-# @DESCRIPTION:
-# Minimum version of active GCC to require. This is checked in
-# ecm_pkg_pretend and ecm_pkg_setup.
-
-# @FUNCTION: _ecm_check_gcc_version
-# @INTERNAL
-# @DESCRIPTION:
-# Determine if the current GCC version is acceptable, otherwise die.
-_ecm_check_gcc_version() {
- if [[ ${MERGE_TYPE} != binary && -v KDE_GCC_MINIMAL ]] && tc-is-gcc; then
-
- local version=$(gcc-version)
-
- debug-print "GCC version check activated"
- debug-print "Version detected: ${version}"
- debug-print "Version required: ${KDE_GCC_MINIMAL}"
-
- ver_test ${version} -lt ${KDE_GCC_MINIMAL} &&
- die "Sorry, but gcc-${KDE_GCC_MINIMAL} or later is required for this package (found ${version})."
- fi
-}
-
# @FUNCTION: _ecm_strip_handbook_translations
# @INTERNAL
# @DESCRIPTION:
@@ -339,7 +344,7 @@ _ecm_strip_handbook_translations() {
fi
local lang po
- for po in ${ECM_PO_DIRS}; do
+ for po in ${ECM_PO_DIRS[*]}; do
if [[ -d ${po} ]] ; then
pushd ${po} > /dev/null || die
for lang in *; do
@@ -474,22 +479,49 @@ ecm_punt_po_install() {
-i CMakeLists.txt || die
}
+if [[ ${EAPI} == 8 ]]; then
+# @FUNCTION: _ecm_deprecated_check_gcc_version
+# @INTERNAL
+# @DESCRIPTION:
+# Determine if the current GCC version is acceptable, otherwise die.
+_ecm_deprecated_check_gcc_version() {
+ if ver_test ${KFMIN} -ge 6.9; then
+ eqawarn "QA notice: ecm_pkg_${1} has become a no-op."
+ eqawarn "It is no longer being exported with KFMIN >=6.9.0."
+ return
+ fi
+ if [[ ${MERGE_TYPE} != binary && -v KDE_GCC_MINIMAL ]] && tc-is-gcc; then
+
+ local version=$(gcc-version)
+
+ debug-print "GCC version check activated"
+ debug-print "Version detected: ${version}"
+ debug-print "Version required: ${KDE_GCC_MINIMAL}"
+
+ ver_test ${version} -lt ${KDE_GCC_MINIMAL} &&
+ die "Sorry, but gcc-${KDE_GCC_MINIMAL} or later is required for this package (found ${version})."
+ fi
+}
+
# @FUNCTION: ecm_pkg_pretend
# @DESCRIPTION:
# Checks if the active compiler meets the minimum version requirements.
-# phase function is only exported if KDE_GCC_MINIMAL is defined.
+# Phase function is only exported if KFMIN is <6.9.0 and KDE_GCC_MINIMAL
+# is defined.
ecm_pkg_pretend() {
debug-print-function ${FUNCNAME} "$@"
- _ecm_check_gcc_version
+ _ecm_deprecated_check_gcc_version pretend
}
# @FUNCTION: ecm_pkg_setup
# @DESCRIPTION:
# Checks if the active compiler meets the minimum version requirements.
+# Phase function is only exported if KFMIN is <6.9.0.
ecm_pkg_setup() {
debug-print-function ${FUNCNAME} "$@"
- _ecm_check_gcc_version
+ _ecm_deprecated_check_gcc_version setup
}
+fi
# @FUNCTION: ecm_src_prepare
# @DESCRIPTION:
@@ -540,7 +572,7 @@ ecm_src_prepare() {
if [[ ${ECM_TEST} = forceoptional ]] ; then
[[ ${_KFSLOT} = 5 ]] && ecm_punt_qt_module Test
# if forceoptional, also cover non-kde categories
- cmake_comment_add_subdirectory autotests test tests
+ cmake_comment_add_subdirectory appiumtests autotests test tests
elif [[ ${ECM_TEST} = forceoptional-recursive ]] ; then
[[ ${_KFSLOT} = 5 ]] && ecm_punt_qt_module Test
local f pf="${T}/${P}"-tests-optional.patch
@@ -557,17 +589,17 @@ ecm_src_prepare() {
diff -Naur ${f}.old ${f} 1>>${pf}
rm ${f}.old || die "Failed to clean up"
done
- eqawarn "Build system was modified by ECM_TEST=forceoptional-recursive."
+ eqawarn "QA notice: Build system modified by ECM_TEST=forceoptional-recursive."
eqawarn "Unified diff file ready for pickup in:"
eqawarn " ${pf}"
eqawarn "Push it upstream to make this message go away."
- elif [[ ${CATEGORY} = kde-frameworks || ${CATEGORY} = kde-plasma || ${CATEGORY} = kde-apps ]] ; then
- cmake_comment_add_subdirectory autotests test tests
+ elif [[ -n ${_KDE_ORG_ECLASS} ]] ; then
+ cmake_comment_add_subdirectory appiumtests autotests test tests
fi
fi
# in frameworks, tests = manual tests so never build them
- if [[ ${CATEGORY} = kde-frameworks ]] && [[ ${PN} != extra-cmake-modules ]]; then
+ if [[ -n ${_FRAMEWORKS_KDE_ORG_ECLASS} ]] && [[ ${PN} != extra-cmake-modules ]]; then
cmake_comment_add_subdirectory tests
fi
}
@@ -605,6 +637,13 @@ ecm_src_configure() {
cmakeargs+=( -DBUILD_DESIGNERPLUGIN=$(usex designer) )
fi
+ if [[ ${ECM_PYTHON_BINDINGS} == off ]]; then
+ cmakeargs+=(
+ -DBUILD_PYTHON_BINDINGS=OFF
+ -DCMAKE_DISABLE_FIND_PACKAGE_{Python3,PySide6,Shiboken6}=ON
+ )
+ fi
+
if [[ ${ECM_QTHELP} = true ]]; then
cmakeargs+=( -DBUILD_QCH=$(usex doc) )
fi
@@ -731,52 +770,58 @@ ecm_src_install() {
done
}
+if [[ ${EAPI} == 8 ]]; then
+# @FUNCTION: _ecm_nongui_deprecated
+# @INTERNAL
+# @DESCRIPTION:
+# Carryall for ecm_pkg_preinst, ecm_pkg_postinst and ecm_pkg_postrm.
+_ecm_nongui_deprecated() {
+ if ver_test ${KFMIN} -ge 6.9; then
+ eqawarn "QA notice: ecm_pkg_${1} has become a no-op."
+ eqawarn "It is no longer being exported with KFMIN >=6.9.0."
+ else
+ case ${ECM_NONGUI} in
+ false) xdg_pkg_${1} ;;
+ *) ;;
+ esac
+ fi
+}
+
# @FUNCTION: ecm_pkg_preinst
# @DESCRIPTION:
# Sets up environment variables required in ecm_pkg_postinst.
+# Phase function is only exported if KFMIN is <6.9.0.
ecm_pkg_preinst() {
debug-print-function ${FUNCNAME} "$@"
-
- case ${ECM_NONGUI} in
- false) xdg_pkg_preinst ;;
- *) ;;
- esac
+ _ecm_nongui_deprecated preinst
}
# @FUNCTION: ecm_pkg_postinst
# @DESCRIPTION:
# Updates the various XDG caches (icon, desktop, mime) if necessary.
+# Phase function is only exported if KFMIN is <6.9.0.
ecm_pkg_postinst() {
debug-print-function ${FUNCNAME} "$@"
-
- case ${ECM_NONGUI} in
- false) xdg_pkg_postinst ;;
- *) ;;
- esac
-
- if [[ -n ${_KDE_ORG_ECLASS} ]] && [[ -z ${I_KNOW_WHAT_I_AM_DOING} ]] && [[ ${KDE_BUILD_TYPE} = live ]]; then
- einfo "WARNING! This is an experimental live ebuild of ${CATEGORY}/${PN}"
- einfo "Use it at your own risk."
- einfo "Do _NOT_ file bugs at bugs.gentoo.org because of this ebuild!"
- fi
+ _ecm_nongui_deprecated postinst
}
# @FUNCTION: ecm_pkg_postrm
# @DESCRIPTION:
# Updates the various XDG caches (icon, desktop, mime) if necessary.
+# Phase function is only exported if KFMIN is <6.9.0.
ecm_pkg_postrm() {
debug-print-function ${FUNCNAME} "$@"
-
- case ${ECM_NONGUI} in
- false) xdg_pkg_postrm ;;
- *) ;;
- esac
+ _ecm_nongui_deprecated postrm
}
+fi
fi
-if [[ -v ${KDE_GCC_MINIMAL} ]]; then
- EXPORT_FUNCTIONS pkg_pretend
+if ver_test ${KFMIN} -lt 6.9; then
+ EXPORT_FUNCTIONS pkg_setup pkg_preinst pkg_postinst pkg_postrm
+ if [[ -v ${KDE_GCC_MINIMAL} ]]; then
+ EXPORT_FUNCTIONS pkg_pretend
+ fi
fi
-EXPORT_FUNCTIONS pkg_setup src_prepare src_configure src_test src_install pkg_preinst pkg_postinst pkg_postrm
+EXPORT_FUNCTIONS src_prepare src_configure src_test src_install
diff --git a/eclass/elisp-common.eclass b/eclass/elisp-common.eclass
index ad9d3c7e60c6..117544e94b35 100644
--- a/eclass/elisp-common.eclass
+++ b/eclass/elisp-common.eclass
@@ -25,7 +25,7 @@
# When relying on the emacs USE flag, you need to add
#
# @CODE
-# emacs? ( >=app-editors/emacs-25.3:* )
+# emacs? ( >=app-editors/emacs-25.3:* )
# @CODE
#
# to your DEPEND/RDEPEND line and use the functions provided here to
@@ -39,7 +39,7 @@
# NEED_EMACS with the Emacs version, as in the following example:
#
# @CODE
-# NEED_EMACS=26.1
+# NEED_EMACS=26.1
# @CODE
#
# Please note that this should be done only for packages that are known
@@ -54,7 +54,7 @@
# are loadable.
#
# @CODE
-# elisp-compile *.el
+# elisp-compile *.el
# @CODE
#
# Function elisp-make-autoload-file() can be used to generate a file
@@ -75,7 +75,7 @@
# (see below) the change, as it defaults to ${PN}.
#
# @CODE
-# elisp-install ${PN} *.el *.elc
+# elisp-install ${PN} *.el *.elc
# @CODE
#
# To let the Emacs support be activated by Emacs on startup, you need
@@ -84,9 +84,9 @@
# Normally this would look like this:
#
# @CODE
-# (add-to-list 'load-path "@SITELISP@")
-# (add-to-list 'auto-mode-alist '("\\.csv\\'" . csv-mode))
-# (autoload 'csv-mode "csv-mode" "Major mode for csv files." t)
+# (add-to-list 'load-path "@SITELISP@")
+# (add-to-list 'auto-mode-alist '("\\.csv\\'" . csv-mode))
+# (autoload 'csv-mode "csv-mode" "Major mode for csv files." t)
# @CODE
#
# If your Emacs support files are installed in a subdirectory of
@@ -117,13 +117,13 @@
# your ebuild (e.g., right after S or RDEPEND):
#
# @CODE
-# SITEFILE="50${PN}-gentoo.el"
+# SITEFILE="50${PN}-gentoo.el"
# @CODE
#
# Which is then installed by
#
# @CODE
-# elisp-site-file-install "${FILESDIR}/${SITEFILE}"
+# elisp-site-file-install "${FILESDIR}/${SITEFILE}"
# @CODE
#
# in src_install(). Any characters after the "-gentoo" part and before
@@ -137,7 +137,7 @@
# and install a site-init file that does just that:
#
# @CODE
-# elisp-make-site-file "${SITEFILE}"
+# elisp-make-site-file "${SITEFILE}"
# @CODE
#
# Again, this must be called in src_install(). See the function's
@@ -153,7 +153,7 @@
# version. In this case, you can add an explicit check in pkg_setup:
#
# @CODE
-# elisp-check-emacs-version
+# elisp-check-emacs-version
# @CODE
#
# When having optional Emacs support, you should prepend "use emacs &&"
@@ -165,13 +165,13 @@
# emerging and unmerging by using
#
# @CODE
-# pkg_postinst() {
-# elisp-site-regen
-# }
+# pkg_postinst() {
+# elisp-site-regen
+# }
#
-# pkg_postrm() {
-# elisp-site-regen
-# }
+# pkg_postrm() {
+# elisp-site-regen
+# }
# @CODE
#
# Again, with optional Emacs support, you should prepend "use emacs &&"
@@ -260,7 +260,6 @@ elisp-emacs-version() {
}
# @FUNCTION: elisp-check-emacs-version
-# @USAGE: [version]
# @DESCRIPTION:
# Test if the eselected Emacs version is at least the version of
# GNU Emacs specified in the NEED_EMACS variable, or die otherwise.
@@ -356,8 +355,8 @@ elisp-make-autoload-file() {
#
# Example:
# @CODE
-# elisp-org-export-to texinfo README.org
-# mv README.texi ${PN}.texi || die
+# elisp-org-export-to texinfo README.org
+# mv README.texi ${PN}.texi || die
# @CODE
elisp-org-export-to() {
@@ -512,16 +511,16 @@ elisp-test-ert() {
#
# Example:
# @CODE
-# inherit elisp-common
+# inherit elisp-common
#
-# ...
+# ...
#
-# elisp-enable-tests --optional ert-runner "${S}"/elisp -t "!org"
+# elisp-enable-tests --optional ert-runner "${S}"/elisp -t "!org"
#
-# src_test() {
-# emake -C tests test
-# elisp-test
-# }
+# src_test() {
+# emake -C tests test
+# elisp-test
+# }
# @CODE
elisp-enable-tests() {
@@ -662,7 +661,7 @@ elisp-site-file-install() {
# this will add the package's SITELISP subdirectory to Emacs' load-path:
#
# @CODE
-# (add-to-list 'load-path "@SITELISP@")
+# (add-to-list 'load-path "@SITELISP@")
# @CODE
#
# Additional arguments are appended as lines to the destination file.
diff --git a/eclass/elisp.eclass b/eclass/elisp.eclass
index 1fa8aab29753..e2f629edf132 100644
--- a/eclass/elisp.eclass
+++ b/eclass/elisp.eclass
@@ -139,7 +139,7 @@ elisp_src_configure() { :; }
elisp_src_compile() {
elisp-compile *.el
if [[ -n ${ELISP_TEXINFO} ]]; then
- makeinfo ${ELISP_TEXINFO} || die
+ makeinfo --no-split ${ELISP_TEXINFO} || die
fi
}
diff --git a/eclass/frameworks.kde.org.eclass b/eclass/frameworks.kde.org.eclass
index 53811e339976..522211a23ab2 100644
--- a/eclass/frameworks.kde.org.eclass
+++ b/eclass/frameworks.kde.org.eclass
@@ -25,6 +25,13 @@ esac
if [[ -z ${_FRAMEWORKS_KDE_ORG_ECLASS} ]]; then
_FRAMEWORKS_KDE_ORG_ECLASS=1
+# @ECLASS_VARIABLE: KDE_CATV
+# @DESCRIPTION:
+# Holds main Frameworks release number (major.minor) for use on same-category
+# dependencies.
+KDE_CATV=$(ver_cut 1-2)
+readonly KDE_CATV
+
# @ECLASS_VARIABLE: KDE_PV_UNRELEASED
# @INTERNAL
# @DESCRIPTION:
@@ -39,15 +46,14 @@ SLOT=6
if ver_test ${PV} -lt 5.240; then
SLOT=5
fi
-if [[ ${PN} == extra-cmake-modules ]]; then
- SLOT=0
-else
- if [[ ${KDE_BUILD_TYPE} == release ]]; then
- SLOT=${SLOT}/$(ver_cut 1-2)
- else
- SLOT=${SLOT}/9999
- fi
-fi
+case ${PN} in
+ extra-cmake-modules|kapidox)
+ SLOT=0
+ ;;
+ *)
+ SLOT=${SLOT}/${KDE_CATV}
+ ;;
+esac
# @ECLASS_VARIABLE: KDE_ORG_SCHEDULE_URI
# @INTERNAL
@@ -61,32 +67,24 @@ KDE_ORG_SCHEDULE_URI+="/Frameworks"
# Helper variable to construct release group specific SRC_URI.
_KDE_SRC_URI="mirror://kde/"
-case ${KDE_BUILD_TYPE} in
- live)
- if [[ ${PV} == 5.239.9999 ]]; then
- EGIT_BRANCH="kf5"
- fi
- ;;
- *)
- if [[ -z ${KDE_ORG_COMMIT} ]]; then
- _KDE_SRC_URI+="stable/frameworks/$(ver_cut 1-2)/"
- case ${KDE_ORG_NAME} in
- kdelibs4support | \
- kdesignerplugin | \
- kdewebkit | \
- khtml | \
- kjs | \
- kjsembed | \
- kmediaplayer | \
- kross | \
- kxmlrpcclient)
- _KDE_SRC_URI+="portingAids/"
- ;;
- esac
+# TODO: Remove after last KF5 PortingAid treecleaned; bug 755956
+if [[ ${KDE_BUILD_TYPE} != live && -z ${KDE_ORG_COMMIT} ]]; then
+ _KDE_SRC_URI+="stable/frameworks/${KDE_CATV}/"
+ case ${KDE_ORG_NAME} in
+ kdelibs4support | \
+ kdesignerplugin | \
+ kdewebkit | \
+ khtml | \
+ kjs | \
+ kjsembed | \
+ kmediaplayer | \
+ kross | \
+ kxmlrpcclient)
+ _KDE_SRC_URI+="portingAids/"
+ ;;
+ esac
- SRC_URI="${_KDE_SRC_URI}${KDE_ORG_TAR_PN}-${PV}.tar.xz"
- fi
- ;;
-esac
+ SRC_URI="${_KDE_SRC_URI}${KDE_ORG_TAR_PN}-${PV}.tar.xz"
+fi
fi
diff --git a/eclass/gear.kde.org.eclass b/eclass/gear.kde.org.eclass
index 8089cbb53bf7..2ae40dfbc708 100644
--- a/eclass/gear.kde.org.eclass
+++ b/eclass/gear.kde.org.eclass
@@ -285,4 +285,19 @@ if $(ver_test -gt 24.07.75); then
esac
fi
+# list of applications ported to KF6 post-24.08 in SLOT=6 having to block SLOT=5
+if $(ver_test -gt 24.11.75); then
+ case ${PN} in
+ cantor | \
+ kalzium | \
+ kmix | \
+ kwave | \
+ marble | \
+ minuet | \
+ step)
+ RDEPEND+=" !${CATEGORY}/${PN}:5" ;;
+ *) ;;
+ esac
+fi
+
fi
diff --git a/eclass/gstreamer-meson.eclass b/eclass/gstreamer-meson.eclass
index 937c86a0f15b..15b0a6390a42 100644
--- a/eclass/gstreamer-meson.eclass
+++ b/eclass/gstreamer-meson.eclass
@@ -1,4 +1,4 @@
-# Copyright 1999-2024 Gentoo Authors
+# Copyright 1999-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: gstreamer-meson.eclass
@@ -38,11 +38,6 @@ esac
PYTHON_COMPAT=( python3_{10..12} )
[[ ${EAPI} == 8 ]] && inherit python-any-r1
-# TODO: Remove after all older versions are gone from tree
-if ver_test ${PV} -lt 1.22.10 ; then
- inherit virtualx
-fi
-
# multilib-minimal goes last
inherit meson multilib toolchain-funcs xdg-utils multilib-minimal
@@ -133,10 +128,7 @@ gstreamer_system_package() {
pc=${tuple#*:}-${SLOT}
sed -e "1i${dependency} = dependency('${pc}', required : true)" \
-i "${pdir}"/meson.build || die
- # TODO: Remove conditional applying once older versions are all gone
- if ver_test ${PV} -gt 1.22.5 ; then
- sed -e "/meson\.override_dependency[(]pkg_name, ${dependency}[)]/d" -i "${S}"/gst-libs/gst/*/meson.build || die
- fi
+ sed -e "/meson\.override_dependency[(]pkg_name, ${dependency}[)]/d" -i "${S}"/gst-libs/gst/*/meson.build || die
done
done
}
@@ -207,8 +199,14 @@ S="${WORKDIR}/${GST_ORG_MODULE}-${PV}"
LICENSE="GPL-2"
SLOT="1.0"
+if ver_test ${GST_ORG_PVP} -ge 1.24 ; then
+ GLIB_VERSION=2.64.0
+else
+ GLIB_VERSION=2.62.0
+fi
+
RDEPEND="
- >=dev-libs/glib-2.40.0:2[${MULTILIB_USEDEP}]
+ >=dev-libs/glib-${GLIB_VERSION}:2[${MULTILIB_USEDEP}]
"
BDEPEND="
virtual/pkgconfig
diff --git a/eclass/guile-utils.eclass b/eclass/guile-utils.eclass
index b0660dcfd1ce..d066013486ed 100644
--- a/eclass/guile-utils.eclass
+++ b/eclass/guile-utils.eclass
@@ -84,10 +84,14 @@ guile_check_compat
# @FUNCTION: guile_set_common_vars
# @DESCRIPTION:
# Sets common variables that apply to all Guile packages, namely,
-# QA_PREBUILT.
+# GUILE_AUTO_COMPILE and QA_PREBUILT.
guile_set_common_vars() {
debug-print-function ${FUNCNAME} "$@"
+ # We don't want Guile making decisions based on the system cache
+ # files. Always recompile so we're deterministic.
+ export GUILE_AUTO_COMPILE=fresh
+
# These aren't strictly speaking prebuilt. but they do generated a
# nonstandard ELF object.
if [[ -z ${QA_PREBUILT} ]]; then
diff --git a/eclass/java-pkg-2.eclass b/eclass/java-pkg-2.eclass
index eebdec584ccc..0b35490e0365 100644
--- a/eclass/java-pkg-2.eclass
+++ b/eclass/java-pkg-2.eclass
@@ -1,4 +1,4 @@
-# Copyright 2004-2024 Gentoo Authors
+# Copyright 2004-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: java-pkg-2.eclass
@@ -6,7 +6,7 @@
# java@gentoo.org
# @AUTHOR:
# Thomas Matthijs <axxo@gentoo.org>
-# @SUPPORTED_EAPIS: 7 8
+# @SUPPORTED_EAPIS: 8
# @PROVIDES: java-utils-2
# @BLURB: Eclass for Java Packages
# @DESCRIPTION:
@@ -17,7 +17,7 @@ if [[ -z ${_JAVA_PKG_2_ECLASS} ]] ; then
_JAVA_PKG_2_ECLASS=1
case ${EAPI} in
- 7|8) ;;
+ 8) ;;
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
esac
diff --git a/eclass/java-pkg-simple.eclass b/eclass/java-pkg-simple.eclass
index 5ed7e3e5b78e..ce4a62f048da 100644
--- a/eclass/java-pkg-simple.eclass
+++ b/eclass/java-pkg-simple.eclass
@@ -6,7 +6,7 @@
# java@gentoo.org
# @AUTHOR:
# Java maintainers <java@gentoo.org>
-# @SUPPORTED_EAPIS: 7 8
+# @SUPPORTED_EAPIS: 8
# @BLURB: Eclass for packaging Java software with ease.
# @DESCRIPTION:
# This class is intended to build pure Java packages from Java sources
@@ -17,7 +17,7 @@
# directory before calling the src_compile function of this eclass.
case ${EAPI} in
- 7|8) ;;
+ 8) ;;
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
esac
diff --git a/eclass/kde.org.eclass b/eclass/kde.org.eclass
index 9be501ce9e3f..47a52ef0234c 100644
--- a/eclass/kde.org.eclass
+++ b/eclass/kde.org.eclass
@@ -235,6 +235,14 @@ kde.org_src_unpack() {
esac
}
+kde.org_pkg_info() {
+ if [[ ${KDE_BUILD_TYPE} = live ]]; then
+ echo "WARNING! This is an experimental live ebuild of ${CATEGORY}/${PN}"
+ echo "Use it at your own risk."
+ echo "Only file bugs at bugs.gentoo.org if convinced that ebuild needs an update!"
+ fi
+}
+
fi
-EXPORT_FUNCTIONS pkg_nofetch src_unpack
+EXPORT_FUNCTIONS pkg_nofetch src_unpack pkg_info
diff --git a/eclass/kernel-build.eclass b/eclass/kernel-build.eclass
index 831027216321..65433d9fc9c0 100644
--- a/eclass/kernel-build.eclass
+++ b/eclass/kernel-build.eclass
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 Gentoo Authors
+# Copyright 2020-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: kernel-build.eclass
@@ -108,10 +108,14 @@ IUSE="+strip"
# @ECLASS_VARIABLE: KERNEL_GENERIC_UKI_CMDLINE
# @USER_VARIABLE
# @DESCRIPTION:
-# If KERNEL_IUSE_GENERIC_UKI is set, this variable allows setting the
-# built-in kernel command line for the UKI. If unset, the default is
-# root=/dev/gpt-auto-root ro
-: "${KERNEL_GENERIC_UKI_CMDLINE:="root=/dev/gpt-auto-root ro"}"
+# If KERNEL_IUSE_GENERIC_UKI is set, and this variable is not
+# empty, then the contents are used as the first kernel cmdline
+# option of the multi-profile generic UKI. Supplementing the four
+# standard options of:
+# - root=/dev/gpt-auto-root ro
+# - root=/dev/gpt-auto-root ro quiet splash
+# - root=/dev/gpt-auto-root ro lockdown=integrity
+# - root=/dev/gpt-auto-root ro quiet splash lockdown=integrity
if [[ ${KERNEL_IUSE_MODULES_SIGN} ]]; then
IUSE+=" modules-sign"
@@ -133,6 +137,9 @@ fi
kernel-build_pkg_setup() {
python-any-r1_pkg_setup
if [[ ${KERNEL_IUSE_MODULES_SIGN} && ${MERGE_TYPE} != binary ]]; then
+ # inherits linux-info to check config values for keys
+ # ensure KV_FULL will not be set globally, that breaks configure
+ local KV_FULL
secureboot_pkg_setup
if use modules-sign && [[ -n ${MODULES_SIGN_KEY} ]]; then
@@ -440,6 +447,11 @@ kernel-build_src_install() {
# Copy built key/certificate files
cp -p build/certs/* "${ED}${kernel_dir}/certs/" || die
+ # If a key was generated, exclude it from the binpkg
+ local generated_key=${ED}${kernel_dir}/certs/signing_key.pem
+ if [[ -r ${generated_key} ]]; then
+ mv "${generated_key}" "${T}/signing_key.pem" || die
+ fi
# building modules fails with 'vmlinux has no symtab?' if stripped
use ppc64 && dostrip -x "${kernel_dir}/${image_path}"
@@ -497,10 +509,10 @@ kernel-build_src_install() {
local dracut_modules=(
base bash btrfs cifs crypt crypt-gpg crypt-loop dbus dbus-daemon
- dm dmraid dracut-systemd fido2 i18n fs-lib kernel-modules
+ dm dmraid dracut-systemd drm fido2 i18n fs-lib kernel-modules
kernel-network-modules kernel-modules-extra lunmask lvm nbd
mdraid modsign network network-manager nfs nvdimm nvmf pcsc
- pkcs11 qemu qemu-net resume rngd rootfs-block shutdown
+ pkcs11 plymouth qemu qemu-net resume rngd rootfs-block shutdown
systemd systemd-ac-power systemd-ask-password systemd-initrd
systemd-integritysetup systemd-pcrphase systemd-sysusers
systemd-udevd systemd-veritysetup terminfo tpm2-tss udev-rules
@@ -526,7 +538,7 @@ kernel-build_src_install() {
--ro-mnt
--modules "${dracut_modules[*]}"
# Pulls in huge firmware files
- --omit-drivers "nfp"
+ --omit-drivers "amdgpu i915 nfp nouveau nvidia xe"
)
# Tries to update ld cache
@@ -534,29 +546,81 @@ kernel-build_src_install() {
dracut "${dracut_args[@]}" "${image%/*}/initrd" ||
die "Failed to generate initramfs"
+ # Note, we cannot use an associative array here because those are
+ # not ordered.
+ local profiles=()
+ local cmdlines=()
+
+ # If defined, make the user entry the first and default
+ if [[ -n ${KERNEL_GENERIC_UKI_CMDLINE} ]]; then
+ profiles+=(
+ $'TITLE=User specified at build time\nID=user'
+ )
+ cmdlines+=( "${KERNEL_GENERIC_UKI_CMDLINE}" )
+ fi
+
+ profiles+=(
+ $'TITLE=Default\nID=default'
+ $'TITLE=Default with splash\nID=splash'
+ $'TITLE=Default with lockdown\nID=lockdown'
+ $'TITLE=Default with splash and lockdown\nID=splash-lockdown'
+ )
+
+ cmdlines+=(
+ "root=/dev/gpt-auto-root ro"
+ "root=/dev/gpt-auto-root ro quiet splash"
+ "root=/dev/gpt-auto-root ro lockdown=integrity"
+ "root=/dev/gpt-auto-root ro quiet splash lockdown=integrity"
+ )
+
local ukify_args=(
--linux="${image}"
--initrd="${image%/*}/initrd"
- --cmdline="${KERNEL_GENERIC_UKI_CMDLINE}"
--uname="${KV_FULL}"
--output="${image%/*}/uki.efi"
- )
+ --profile="${profiles[0]}"
+ --cmdline="${cmdlines[0]}"
+ ) # 0th profile is default
+
+ # Additional profiles have to be added with --join-profile
+ local i
+ for (( i=1; i<"${#profiles[@]}"; i++ )); do
+ ukify build \
+ --profile="${profiles[i]}" \
+ --cmdline="${cmdlines[i]}" \
+ --output="${T}/profile${i}.efi" ||
+ die "Failed to create profile ${i}"
+
+ ukify_args+=( --join-profile="${T}/profile${i}.efi" )
+ done
if [[ ${KERNEL_IUSE_MODULES_SIGN} ]] && use secureboot; then
+ # --pcrpkey is appended as is. If the certificate and key
+ # are in the same file, we could accidentally leak the key
+ # into the UKI. Pass the certificate through openssl to ensure
+ # that it truly contains *only* the certificate.
+ openssl x509 \
+ -in "${SECUREBOOT_SIGN_CERT}" -inform PEM \
+ -out "${T}/pcrpkey.pem" -outform PEM ||
+ die "Failed to extract certificate"
ukify_args+=(
- --signtool=sbsign
--secureboot-private-key="${SECUREBOOT_SIGN_KEY}"
--secureboot-certificate="${SECUREBOOT_SIGN_CERT}"
+ --pcrpkey="${T}/pcrpkey.pem"
+ --measure
)
if [[ ${SECUREBOOT_SIGN_KEY} == pkcs11:* ]]; then
ukify_args+=(
--signing-engine="pkcs11"
+ --pcr-private-key="${SECUREBOOT_SIGN_KEY}"
+ --pcr-public-key="${SECUREBOOT_SIGN_CERT}"
+ --phases="enter-initrd"
+ --pcr-private-key="${SECUREBOOT_SIGN_KEY}"
+ --pcr-public-key="${SECUREBOOT_SIGN_CERT}"
+ --phases="enter-initrd:leave-initrd enter-initrd:leave-initrd:sysinit enter-initrd:leave-initrd:sysinit:ready"
)
else
- # Sytemd-measure does not currently support pkcs11
ukify_args+=(
- --measure
- --pcrpkey="${ED}${kernel_dir}/certs/signing_key.x509"
--pcr-private-key="${SECUREBOOT_SIGN_KEY}"
--phases="enter-initrd"
--pcr-private-key="${SECUREBOOT_SIGN_KEY}"
@@ -565,9 +629,7 @@ kernel-build_src_install() {
fi
fi
- # systemd<255 does not install ukify in /usr/bin
- PATH="${PATH}:${BROOT}/usr/lib/systemd:${BROOT}/lib/systemd" \
- ukify build "${ukify_args[@]}" || die "Failed to generate UKI"
+ ukify build "${ukify_args[@]}" || die "Failed to generate UKI"
# Overwrite unnecessary image types to save space
> "${image}" || die
@@ -597,7 +659,6 @@ kernel-build_pkg_postinst() {
ewarn "MODULES_SIGN_KEY was not set, this means the kernel build system"
ewarn "automatically generated the signing key. This key was installed"
ewarn "in ${EROOT}/usr/src/linux-${KV_FULL}/certs"
- ewarn "and will also be included in any binary packages."
ewarn "Please take appropriate action to protect the key!"
ewarn
ewarn "Recompiling this package causes a new key to be generated. As"
diff --git a/eclass/kernel-install.eclass b/eclass/kernel-install.eclass
index a341dd9426ff..cf34007844a8 100644
--- a/eclass/kernel-install.eclass
+++ b/eclass/kernel-install.eclass
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 Gentoo Authors
+# Copyright 2020-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: kernel-install.eclass
@@ -162,9 +162,10 @@ if [[ ${KERNEL_IUSE_GENERIC_UKI} ]]; then
["sys-apps/rng-tools"]="GPL-2"
["sys-apps/sed"]="GPL-3+"
["sys-apps/shadow"]="BSD GPL-2"
- ["sys-apps/systemd[boot(-),cryptsetup,pkcs11,policykit,tpm,ukify(-)]"]="GPL-2 LGPL-2.1 MIT public-domain"
+ [">=sys-apps/systemd-257[boot(-),cryptsetup,pkcs11,policykit,tpm,ukify(-)]"]="GPL-2 LGPL-2.1 MIT public-domain"
["sys-apps/util-linux"]="GPL-2 GPL-3 LGPL-2.1 BSD-4 MIT public-domain"
["sys-auth/polkit"]="LGPL-2"
+ ["sys-boot/plymouth[drm,systemd(+),udev]"]="GPL-2+"
["sys-block/nbd"]="GPL-2"
["sys-devel/gcc"]="GPL-3+ LGPL-3+ || ( GPL-3+ libgcc libstdc++ gcc-runtime-library-exception-3.1 ) FDL-1.3+"
["sys-fs/btrfs-progs"]="GPL-2"
@@ -190,6 +191,7 @@ if [[ ${KERNEL_IUSE_GENERIC_UKI} ]]; then
["sys-libs/readline"]="GPL-3+"
["sys-libs/zlib"]="ZLIB"
["sys-process/procps"]="GPL-2+ LGPL-2+ LGPL-2.1+"
+ ["x11-libs/libdrm"]="MIT"
["amd64? ( sys-firmware/intel-microcode )"]="amd64? ( intel-ucode )"
["x86? ( sys-firmware/intel-microcode )"]="x86? ( intel-ucode )"
)
@@ -202,6 +204,7 @@ if [[ ${KERNEL_IUSE_GENERIC_UKI} ]]; then
"
IDEPEND="
generic-uki? (
+ app-crypt/sbsigntools
>=sys-kernel/installkernel-14[-dracut(-),-ugrd(-),-ukify(-)]
)
!generic-uki? (
@@ -605,6 +608,15 @@ kernel-install_pkg_preinst() {
[[ ! -d ${kernel_dir} ]] &&
die "Kernel directory ${kernel_dir} not installed!"
+ # We moved this in order to omit it from the binpkg, move it back
+ if [[ -r "${T}/signing_key.pem" ]]; then
+ # cp instead of mv to set owner to root in one go
+ (
+ umask 066 &&
+ cp "${T}/signing_key.pem" "${kernel_dir}/certs/signing_key.pem"
+ ) || die
+ fi
+
# perform the version check for release ebuilds only
if [[ ${PV} != *9999 ]]; then
local expected_ver=$(dist-kernel_PV_to_KV "${PV}")
@@ -649,13 +661,65 @@ kernel-install_extract_from_uki() {
local extract_type=${1}
local uki=${2}
local out=${3}
+ local out_temp=${T}/${extract_type}-section-dumped
# objcopy overwrites input if there is no output, dump the output in T.
# We unfortunately cannot use /dev/null here
$(tc-getOBJCOPY) "${uki}" "${T}/dump.efi" \
- --dump-section ".${extract_type}=${out}" ||
- die "Failed to extract ${extract_type}"
- chmod 644 "${out}" || die
+ --dump-section ".${extract_type}=${out_temp}" ||
+ die "Failed to extract ${extract_type}"
+
+ # Sanity checks for kernel images
+ if [[ ${extract_type} == linux ]] &&
+ { ! in_iuse secureboot || use secureboot ;}
+ then
+ # Extract the used SECUREBOOT_SIGN_CERT to verify the kernel image
+ local cert=${T}/pcrpkey
+ kernel-install_extract_from_uki pcrpkey "${uki}" "${cert}"
+ if [[ $(head -n1 "${cert}") != "-----BEGIN CERTIFICATE-----" ]]; then
+ # This is a DER format certificate, convert it to PEM
+ openssl x509 \
+ -inform DER -in "${cert}" \
+ -outform PEM -out "${cert}" ||
+ die "Failed to convert pcrpkey to PEM format"
+ fi
+
+ # Check if the signature on the UKI is valid
+ sbverify --cert "${cert}" "${uki}" ||
+ die "ERROR: UKI signature is invalid"
+
+ # Check if the signature on the kernel image is valid
+ local sbverify_err=$(
+ sbverify --cert "${cert}" "${out_temp}" 2>&1 >/dev/null
+ )
+
+ # Check if there was a padding warning
+ if [[ ${sbverify_err} == "warning: data remaining"*": gaps between PE/COFF sections?"* ]]
+ then
+ # https://github.com/systemd/systemd/issues/35851
+ local proper_size=${sbverify_err#"warning: data remaining["}
+ proper_size=${proper_size%" vs"*}
+ # Strip the padding
+ head "${out_temp}" --bytes "${proper_size}" \
+ >"${out_temp}_trimmed" || die
+ # Check if the signature verifies now
+ sbverify_err=$(
+ sbverify --cert "${cert}" "${out_temp}_trimmed" 2>&1 >/dev/null
+ )
+ [[ -z ${sbverify_err} ]] && out_temp=${out_temp}_trimmed
+ fi
+
+ # Something has gone wrong, stop here to prevent installing a kernel
+ # with an invalid signature or a completely broken kernel image.
+ if [[ -n ${sbverify_err} ]]; then
+ eerror "${sbverify_err}"
+ die "ERROR: Kernel image signature is invalid"
+ else
+ einfo "Signature verification OK"
+ fi
+ fi
+
+ install -m 644 "${out_temp}" "${out}" || die
}
# @FUNCTION: kernel-install_install_all
@@ -714,9 +778,7 @@ kernel-install_pkg_postinst() {
dist-kernel_compressed_module_cleanup \
"${EROOT}/lib/modules/${KV_FULL}"
- if [[ -z ${ROOT} ]]; then
- kernel-install_install_all "${KV_FULL}"
- fi
+ kernel-install_install_all "${KV_FULL}"
if [[ ${KERNEL_IUSE_GENERIC_UKI} ]] && use generic-uki; then
ewarn "The prebuilt initramfs and unified kernel image are highly experimental!"
@@ -738,9 +800,9 @@ kernel-install_pkg_postinst() {
kernel-install_pkg_postrm() {
debug-print-function ${FUNCNAME} "$@"
- if [[ -z ${ROOT} && ! ${KERNEL_IUSE_GENERIC_UKI} ]]; then
- local kernel_dir=${EROOT}/usr/src/linux-${KV_FULL}
- local image_path=$(dist-kernel_get_image_path)
+ local kernel_dir=${EROOT}/usr/src/linux-${KV_FULL}
+ local image_path=$(dist-kernel_get_image_path)
+ if [[ ! ${KERNEL_IUSE_GENERIC_UKI} && -d ${kernel_dir} ]]; then
ebegin "Removing initramfs"
rm -f "${kernel_dir}/${image_path%/*}"/{initrd,uki.efi} &&
find "${kernel_dir}" -depth -type d -empty -delete
@@ -752,8 +814,6 @@ kernel-install_pkg_postrm() {
# @DESCRIPTION:
# Rebuild the initramfs and reinstall the kernel.
kernel-install_pkg_config() {
- [[ -z ${ROOT} ]] || die "ROOT!=/ not supported currently"
-
if [[ -z ${KV_FULL} ]]; then
KV_FULL=${PV}${KV_LOCALVERSION}
fi
diff --git a/eclass/latex-package.eclass b/eclass/latex-package.eclass
index 4082e161b843..dfef7fc2836f 100644
--- a/eclass/latex-package.eclass
+++ b/eclass/latex-package.eclass
@@ -137,11 +137,16 @@ latex-package_src_doinstall() {
continue
einfo "Making documentation: ${i}"
+ local mypdflatex=(
+ pdflatex
+ ${LATEX_DOC_ARGUMENTS}
+ --halt-on-error
+ --interaction=nonstopmode
+ "${i}"
+ )
# some macros need compiler called twice, do it here.
- set -- pdflatex ${LATEX_DOC_ARGUMENTS} \
- --halt-on-error --interaction=nonstopmode "${i}"
- if "${@}"; then
- "${@}"
+ if "${mypdflatex[@]}"; then
+ "${mypdflatex[@]}"
else
einfo "pdflatex failed, trying texi2dvi"
texi2dvi -q -c --language=latex "${i}" || die
@@ -195,6 +200,9 @@ latex-package_src_doinstall() {
"all")
latex-package_src_doinstall styles fonts bin doc
;;
+ *)
+ die "Unknown module: ${1}"
+ ;;
esac
shift
done
diff --git a/eclass/linux-mod-r1.eclass b/eclass/linux-mod-r1.eclass
index 4e5b17548b04..16c280219ef8 100644
--- a/eclass/linux-mod-r1.eclass
+++ b/eclass/linux-mod-r1.eclass
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 Gentoo Authors
+# Copyright 2023-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: linux-mod-r1.eclass
@@ -333,7 +333,7 @@ linux-mod-r1_pkg_setup() {
_MODULES_GLOBAL[ran:pkg_setup]=1
_modules_check_function ${#} 0 0 || return 0
- if [[ -z ${ROOT} && ${MODULES_INITRAMFS_IUSE} ]] &&
+ if [[ ${MODULES_INITRAMFS_IUSE} ]] &&
use dist-kernel && use ${MODULES_INITRAMFS_IUSE#+}
then
# Check, but don't die because we can fix the problem and then
@@ -508,7 +508,7 @@ linux-mod-r1_pkg_postinst() {
dist-kernel_compressed_module_cleanup "${EROOT}/lib/modules/${KV_FULL}"
_modules_update_depmod
- if [[ -z ${ROOT} && ${MODULES_INITRAMFS_IUSE} ]] &&
+ if [[ ${MODULES_INITRAMFS_IUSE} ]] &&
use dist-kernel && use ${MODULES_INITRAMFS_IUSE#+}
then
dist-kernel_reinstall_initramfs "${KV_DIR}" "${KV_FULL}"
diff --git a/eclass/llvm-r1.eclass b/eclass/llvm-r1.eclass
index 7326e3a6b271..e59bd9c317b9 100644
--- a/eclass/llvm-r1.eclass
+++ b/eclass/llvm-r1.eclass
@@ -14,8 +14,10 @@
# in a matching slot. To use the eclass:
#
# 1. Set LLVM_COMPAT to the list of supported LLVM slots.
+#
# 2. Use llvm_gen_dep and/or LLVM_USEDEP to add appropriate
# dependencies.
+#
# 3. Use llvm-r1_pkg_setup, get_llvm_prefix or LLVM_SLOT.
#
# The eclass sets IUSE and REQUIRED_USE. The flag corresponding
diff --git a/eclass/llvm-r2.eclass b/eclass/llvm-r2.eclass
new file mode 100644
index 000000000000..4dda9aedc7c6
--- /dev/null
+++ b/eclass/llvm-r2.eclass
@@ -0,0 +1,476 @@
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: llvm-r2.eclass
+# @MAINTAINER:
+# Michał Górny <mgorny@gentoo.org>
+# @AUTHOR:
+# Michał Górny <mgorny@gentoo.org>
+# @SUPPORTED_EAPIS: 8
+# @PROVIDES: llvm-utils
+# @BLURB: Provide LLVM_SLOT to build against slotted LLVM
+# @DESCRIPTION:
+# An eclass to reliably depend on a set of LLVM-related packages
+# in a matching slot. To use the eclass:
+#
+# 1. Set LLVM_COMPAT to the list of supported LLVM slots.
+#
+# 2. Use llvm_gen_dep and/or LLVM_USEDEP to add appropriate
+# dependencies.
+#
+# 3. Use llvm-r2_pkg_setup, llvm_chost_setup, llvm_cbuild_setup,
+# get_llvm_prefix or LLVM_SLOT.
+#
+# The eclass sets IUSE and REQUIRED_USE. The flag corresponding
+# to the newest supported stable LLVM slot (or the newest testing,
+# if no stable slots are supported) is enabled by default.
+#
+# Note that the eclass aims for a best-effort support of CHOST builds
+# (i.e. compiling/linking against LLVM) and CBUILD use (i.e. calling
+# LLVM tools at build time). You need to determine what the package
+# in question needs, and put the appropriate packages in DEPEND and/or
+# BDEPEND appropriately.
+#
+# Example:
+# @CODE
+# LLVM_COMPAT=( {16..18} )
+#
+# inherit llvm-r2
+#
+# DEPEND="
+# dev-libs/libfoo[${LLVM_USEDEP}]
+# $(llvm_gen_dep '
+# llvm-core/clang:${LLVM_SLOT}=
+# llvm-core/llvm:${LLVM_SLOT}=
+# ')
+# "
+# @CODE
+
+case ${EAPI} in
+ 8) ;;
+ *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+if [[ -z ${_LLVM_R2_ECLASS} ]]; then
+_LLVM_R2_ECLASS=1
+
+inherit llvm-utils
+
+# == internal control knobs ==
+
+# @ECLASS_VARIABLE: _LLVM_OLDEST_SLOT
+# @INTERNAL
+# @DESCRIPTION:
+# Oldest supported LLVM slot. This is used to automatically filter out
+# unsupported LLVM_COMPAT values.
+_LLVM_OLDEST_SLOT=15
+
+# @ECLASS_VARIABLE: _LLVM_NEWEST_STABLE
+# @INTERNAL
+# @DESCRIPTION:
+# The newest stable LLVM version. Versions newer than that won't
+# be automatically enabled via USE defaults.
+_LLVM_NEWEST_STABLE=19
+
+# == control variables ==
+
+# @ECLASS_VARIABLE: LLVM_COMPAT
+# @PRE_INHERIT
+# @REQUIRED
+# @DESCRIPTION:
+# A list of LLVM slots supported by the package, oldest to newest.
+#
+# Example:
+# @CODE
+# LLVM_COMPAT=( {15..17} )
+# @CODE
+
+# @ECLASS_VARIABLE: LLVM_OPTIONAL
+# @PRE_INHERIT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If set to a non-empty value, disables setting REQUIRED_USE
+# and exporting pkg_setup. You have to add LLVM_REQUIRED_USE and call
+# pkg_setup manually, with appropriate USE conditions.
+
+# == global metadata ==
+
+# @ECLASS_VARIABLE: LLVM_REQUIRED_USE
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# An eclass-generated REQUIRED_USE string that enforces selecting
+# exactly one slot. It LLVM_OPTIONAL is set, it needs to be copied
+# into REQUIRED_USE, under appropriate USE conditions. Otherwise,
+# it is added automatically.
+
+# @ECLASS_VARIABLE: LLVM_USEDEP
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# An eclass-generated USE dependency string that can be applied to other
+# packages using the same eclass, to enforce a LLVM slot match.
+
+_llvm_set_globals() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ if [[ ${LLVM_COMPAT@a} != *a* ]]; then
+ die "LLVM_COMPAT must be set to an array before inheriting ${ECLASS}"
+ fi
+
+ local stable=() unstable=()
+ local x
+ for x in "${LLVM_COMPAT[@]}"; do
+ if [[ ${x} -gt ${_LLVM_NEWEST_STABLE} ]]; then
+ unstable+=( "${x}" )
+ elif [[ ${x} -ge ${_LLVM_OLDEST_SLOT} ]]; then
+ stable+=( "${x}" )
+ fi
+ done
+
+ _LLVM_SLOTS=( "${stable[@]}" "${unstable[@]}" )
+ if [[ ! ${_LLVM_SLOTS[@]} ]]; then
+ die "LLVM_COMPAT does not contain any valid versions (all older than ${_LLVM_OLDEST_SLOT}?)"
+ fi
+
+ if [[ ${stable[@]} ]]; then
+ # If there is at least one stable slot supported, then enable
+ # the newest stable slot by default.
+ IUSE="+llvm_slot_${stable[-1]}"
+ unset 'stable[-1]'
+ else
+ # Otherwise, enable the "oldest" ~arch slot. We really only
+ # expect a single ~arch version, so this primarily prevents
+ # defaulting to non-keyworded slots.
+ IUSE="+llvm_slot_${unstable[0]}"
+ unset 'unstable[0]'
+ fi
+ local nondefault=( "${stable[@]}" "${unstable[@]}" )
+ IUSE+=" ${nondefault[*]/#/llvm_slot_}"
+
+ local flags=( "${_LLVM_SLOTS[@]/#/llvm_slot_}" )
+ LLVM_REQUIRED_USE="^^ ( ${flags[*]} )"
+ local usedep_flags=${flags[*]/%/(-)?}
+ LLVM_USEDEP=${usedep_flags// /,}
+ readonly LLVM_REQUIRED_USE LLVM_USEDEP
+
+ if [[ ! ${LLVM_OPTIONAL} ]]; then
+ REQUIRED_USE=${LLVM_REQUIRED_USE}
+ fi
+}
+_llvm_set_globals
+unset -f _llvm_set_globals
+
+# == metadata helpers ==
+
+# @FUNCTION: llvm_gen_dep
+# @USAGE: <dependency>
+# @DESCRIPTION:
+# Output a dependency block, repeating "<dependency>" conditionally
+# to all llvm_slot_* USE flags. Any occurences of '${LLVM_SLOT}'
+# within the block will be substituted for the respective slot.
+#
+# Example:
+# @CODE
+# DEPEND="
+# $(llvm_gen_dep '
+# llvm-core/clang:${LLVM_SLOT}=
+# llvm-core/llvm:${LLVM_SLOT}=
+# ')
+# "
+# @CODE
+llvm_gen_dep() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ [[ ${#} -ne 1 ]] && die "Usage: ${FUNCNAME} <dependency>"
+
+ local dep=${1}
+
+ local slot
+ for slot in "${_LLVM_SLOTS[@]}"; do
+ echo "llvm_slot_${slot}? ( ${dep//\$\{LLVM_SLOT\}/${slot}} )"
+ done
+}
+
+# == ebuild helpers ==
+
+# @FUNCTION: get_llvm_prefix
+# @USAGE: [-b|-d]
+# @DESCRIPTION:
+# Output the path to the selected LLVM slot.
+#
+# With no option or "-d", the path is prefixed by ESYSROOT. LLVM
+# dependencies should be in DEPEND then.
+#
+# With "-b" option, the path is prefixed by BROOT. LLVM dependencies
+# should be in BDEPEND then.
+get_llvm_prefix() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ [[ ${#} -gt 1 ]] && die "Usage: ${FUNCNAME} [-b|-d]"
+
+ local prefix
+ case ${1--d} in
+ -d)
+ prefix=${ESYSROOT}
+ ;;
+ -b)
+ prefix=${BROOT}
+ ;;
+ *)
+ die "${FUNCNAME}: invalid option: ${1}"
+ ;;
+ esac
+
+ echo "${prefix}/usr/lib/llvm/${LLVM_SLOT}"
+}
+
+# @FUNCTION: generate_llvm_config
+# @DESCRIPTION:
+# Output a llvm-config compatible script that yields paths specific
+# to the requested LLVM version.
+generate_llvm_config() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ local bindir=$(get_llvm_prefix -b)/bin
+ [[ ! -d ${bindir} ]] && bindir=
+
+ local prefix=$(get_llvm_prefix -d)
+ local includedir=${prefix}/include
+ local libdir=${prefix}/$(get_libdir)
+ local cmake_conf=${libdir}/cmake/llvm/LLVMConfig.cmake
+ if [[ ! -f ${cmake_conf} ]]; then
+ cat <<-EOF
+ #!/usr/bin/env sh
+ echo "LLVM ${LLVM_SLOT} not installed for ABI=${ABI}" >&2
+ exit 127
+ EOF
+ return
+ fi
+
+ local version=$(
+ sed -ne 's:set(LLVM_PACKAGE_VERSION \(.*\)):\1:p' "${cmake_conf}" || die
+ )
+ [[ -n ${version} ]] || die
+ local cppdefs=$(
+ sed -ne 's:set(LLVM_DEFINITIONS "\(.*\)"):\1:p' "${cmake_conf}" || die
+ )
+ [[ -n ${cppdefs} ]] || die
+ local targets=$(
+ sed -ne 's:set(LLVM_TARGETS_TO_BUILD \(.*\)):\1:p' "${cmake_conf}" || die
+ )
+ [[ -n ${targets} ]] || die
+ local libs=$(
+ sed -ne 's:set(LLVM_AVAILABLE_LIBS \(.*\)):\1:p' "${cmake_conf}" || die
+ )
+ [[ -n ${libs} ]] || die
+ local target_triple=$(
+ sed -ne 's:set(LLVM_TARGET_TRIPLE "\(.*\)"):\1:p' "${cmake_conf}" || die
+ )
+ [[ -n ${target_triple} ]] || die
+
+ readarray -d';' -t targets <<<"${targets}"
+ readarray -d';' -t libs <<<"${libs}"
+ # easier than parsing CMake booleans
+ local assertions=OFF
+ [[ ${cppdefs} == *-D_DEBUG* ]] && assertions=ON
+ # major + suffix
+ local shlib_name=LLVM-${version%%.*}
+ [[ ${version} == *git* ]] && shlib_name+="git${version##*git}"
+
+ local components=(
+ "${libs[@]#LLVM}" "${targets[@]}"
+ # special component groups (grep for add_llvm_component_group)
+ all all-targets engine native nativecodegen
+ )
+
+ cat <<-EOF
+ #!/usr/bin/env sh
+
+ echo "\${0} \${*}" >> "${T}/llvm-config-calls.txt"
+
+ do_echo() {
+ echo " \${*}" >> "${T}/llvm-config-calls.txt"
+ echo "\${@}"
+ }
+
+ for arg; do
+ case \${arg} in
+ --assertion-mode)
+ do_echo "${assertions}"
+ ;;
+ --bindir)
+ if [ -n "${bindir}" ]; then
+ do_echo "${bindir}"
+ else
+ do_echo "CBUILD LLVM not available" >&2
+ exit 1
+ fi
+ ;;
+ --build-mode)
+ do_echo RelWithDebInfo
+ ;;
+ --build-system)
+ do_echo cmake
+ ;;
+ --cflags|--cppflags)
+ do_echo "-I${includedir} ${cppdefs[*]}"
+ ;;
+ --cmakedir)
+ do_echo "${libdir}/cmake/llvm"
+ ;;
+ --components)
+ do_echo "${components[*],,}"
+ ;;
+ --cxxflags)
+ do_echo "-I${includedir} -std=c++17 ${cppdefs[*]}"
+ ;;
+ --has-rtti)
+ do_echo YES
+ ;;
+ --host-target)
+ do_echo "${target_triple}"
+ ;;
+ --ignore-libllvm)
+ # ignored
+ ;;
+ --includedir)
+ do_echo "${includedir}"
+ ;;
+ --ldflags)
+ do_echo "-L${libdir}"
+ ;;
+ --libdir)
+ do_echo "${libdir}"
+ ;;
+ --libfiles)
+ do_echo "${libdir}/lib${shlib_name}.so"
+ ;;
+ --libnames)
+ do_echo lib${shlib_name}.so
+ ;;
+ --libs)
+ do_echo "-l${shlib_name}"
+ ;;
+ --link-shared|--link-static)
+ # ignored
+ ;;
+ --obj-root|--prefix)
+ do_echo "${prefix}"
+ ;;
+ --shared-mode)
+ do_echo shared
+ ;;
+ --system-libs)
+ do_echo
+ ;;
+ --targets-built)
+ do_echo "${targets[*]}"
+ ;;
+ --version)
+ do_echo "${version}"
+ ;;
+ -*)
+ do_echo "Unsupported option: \${arg}" >&2
+ exit 1
+ ;;
+ *)
+ # ignore components, we always return the dylib
+ ;;
+ esac
+ done
+ EOF
+}
+# @FUNCTION: llvm_cbuild_setup
+# @DESCRIPTION:
+# Prepend the PATH for selected LLVM version in CBUILD.
+#
+# This function is meant to be used when the package in question uses
+# LLVM tools at build time. It is called automatically
+# by llvm-r2_pkg_setup if LLVM is found installed in BROOT.
+#
+# Note that llvm-config from this path must not be used to build against
+# LLVM, as that will break cross-compilation.
+llvm_cbuild_setup() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ local broot_prefix=$(get_llvm_prefix -b)
+ einfo "Using ${broot_prefix} for CBUILD LLVM ${LLVM_SLOT}"
+ [[ -d ${broot_prefix}/bin ]] ||
+ die "LLVM ${LLVM_SLOT} not found installed in BROOT (expected: ${broot_prefix}/bin)"
+
+ llvm_fix_clang_version CC CPP CXX
+ # keep in sync with profiles/features/llvm/make.defaults!
+ llvm_fix_tool_path ADDR2LINE AR AS LD NM OBJCOPY OBJDUMP RANLIB
+ llvm_fix_tool_path READELF STRINGS STRIP
+ llvm_prepend_path -b "${LLVM_SLOT}"
+}
+
+# @FUNCTION: llvm_chost_setup
+# @DESCRIPTION:
+# Set the environment for finding selected LLVM slot installed
+# for CHOST. Create llvm-config wrappers to satisfy legacy lookups.
+#
+# This function is meant to be used when the package in question uses
+# LLVM compiles against and links to LLVM. It is called automatically
+# by llvm-r2_pkg_setup if LLVM is found installed in ESYSROOT.
+#
+# Note that the generated llvm-config may refer to CBUILD installation
+# of LLVM via --bindir, if it is found available.
+llvm_chost_setup() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ local esysroot_prefix=$(get_llvm_prefix -d)
+ einfo "Using ${esysroot_prefix} for CHOST LLVM ${LLVM_SLOT}"
+ [[ -d ${esysroot_prefix} ]] ||
+ die "LLVM ${LLVM_SLOT} not found installed in ESYSROOT (expected: ${esysroot_prefix})"
+
+ # satisfies find_package() in CMake
+ export LLVM_ROOT="${esysroot_prefix}"
+ export Clang_ROOT="${esysroot_prefix}"
+ export LLD_ROOT="${esysroot_prefix}"
+ export MLIR_ROOT="${esysroot_prefix}"
+ export Polly_ROOT="${esysroot_prefix}"
+
+ # satisfies llvm-config calls, e.g. from meson
+ export PATH="${T}/llvm-bin:${PATH}"
+ mkdir "${T}"/llvm-bin || die
+ # we need to generate it per-ABI, since libdir changes
+ local ABI
+ for ABI in $(get_all_abis); do
+ local path="${T}/llvm-bin/$(get_abi_CHOST)-llvm-config"
+ generate_llvm_config > "${path}" || die
+ chmod +x "${path}" || die
+ done
+ ln -s "$(get_abi_CHOST)-llvm-config" "${T}/llvm-bin/llvm-config" || die
+}
+
+# @FUNCTION: llvm-r2_pkg_setup
+# @DESCRIPTION:
+# Handle all supported setup actions automatically. If LLVM is found
+# installed for CBUILD, call llvm_cbuild_setup. If it is found
+# installed for CHOST, call llvm_chost_setup.
+#
+# This function is a no-op when installing a binary package.
+#
+# Note that this function is not exported if LLVM_OPTIONAL is set.
+# In that case, it needs to be called manually.
+llvm-r2_pkg_setup() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ if [[ ${MERGE_TYPE} != binary ]]; then
+ [[ -z ${LLVM_SLOT} ]] && die "LLVM_SLOT unset (broken USE_EXPAND?)"
+
+ if [[ -d $(get_llvm_prefix -b)/bin ]]; then
+ llvm_cbuild_setup
+ fi
+
+ if [[ -d $(get_llvm_prefix -d) ]]; then
+ llvm_chost_setup
+ fi
+ fi
+}
+
+fi
+
+if [[ ! ${LLVM_OPTIONAL} ]]; then
+ EXPORT_FUNCTIONS pkg_setup
+fi
diff --git a/eclass/llvm-utils.eclass b/eclass/llvm-utils.eclass
index 1ae3295484c8..b105e169fbc4 100644
--- a/eclass/llvm-utils.eclass
+++ b/eclass/llvm-utils.eclass
@@ -113,17 +113,38 @@ llvm_fix_tool_path() {
}
# @FUNCTION: llvm_prepend_path
-# @USAGE: <slot>
+# @USAGE: [-b|-d] <slot>
# @DESCRIPTION:
# Prepend the path to the specified LLVM slot to PATH variable,
# and reexport it.
+#
+# With no option or "-d", the path is prefixed by ESYSROOT. LLVM
+# dependencies should be in DEPEND then.
+#
+# With "-b" option, the path is prefixed by BROOT. LLVM dependencies
+# should be in BDEPEND then.
llvm_prepend_path() {
debug-print-function ${FUNCNAME} "$@"
- [[ ${#} -ne 1 ]] && die "Usage: ${FUNCNAME} <slot>"
+ local prefix
+ case ${1--d} in
+ -d)
+ prefix=${ESYSROOT}
+ shift
+ ;;
+ -b)
+ prefix=${BROOT}
+ shift
+ ;;
+ -*)
+ die "${FUNCNAME}: invalid option: ${1}"
+ ;;
+ esac
+
+ [[ ${#} -ne 1 ]] && die "Usage: ${FUNCNAME} [-b|-d] <slot>"
local slot=${1}
- local llvm_path=${ESYSROOT}/usr/lib/llvm/${slot}/bin
+ local llvm_path=${prefix}/usr/lib/llvm/${slot}/bin
local IFS=:
local split_path=( ${PATH} )
local new_path=()
diff --git a/eclass/llvm.org.eclass b/eclass/llvm.org.eclass
index a7685a38575b..a810027f74f5 100644
--- a/eclass/llvm.org.eclass
+++ b/eclass/llvm.org.eclass
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 Gentoo Authors
+# Copyright 2019-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: llvm.org.eclass
@@ -72,11 +72,14 @@ if [[ -z ${_LLVM_SOURCE_TYPE+1} ]]; then
_LLVM_SOURCE_TYPE=snapshot
case ${PV} in
- 20.0.0_pre20241207)
- EGIT_COMMIT=32f7f0010bca99ee4bd917f57272733fb2bf3bd9
+ 20.0.0_pre20250111)
+ EGIT_COMMIT=8af4d206e0f979f68925a08f9dffd60a98ce97e2
;;
- 20.0.0_pre20241130)
- EGIT_COMMIT=a348f223cab54b21a7b1c38dec7bc6aa2f81c949
+ 20.0.0_pre20250104)
+ EGIT_COMMIT=2529a8df53af9bc6cecfd6c83404ffa5e89e3370
+ ;;
+ 20.0.0_pre20241227)
+ EGIT_COMMIT=ccfe0de0e1e37ed369c9bf89dd0188ba0afb2e9a
;;
*)
die "Unknown snapshot: ${PV}"
diff --git a/eclass/mono-env.eclass b/eclass/mono-env.eclass
index 5415a7043fed..2e19c0b744ee 100644
--- a/eclass/mono-env.eclass
+++ b/eclass/mono-env.eclass
@@ -4,7 +4,7 @@
# @ECLASS: mono-env.eclass
# @MAINTAINER:
# maintainer-needed@gentoo.org
-# @SUPPORTED_EAPIS: 7
+# @SUPPORTED_EAPIS: 7 8
# @BLURB: Set environment variables commonly used by dotnet packages.
# @DESCRIPTION:
# Set environment variables commonly used by dotnet packages.
diff --git a/eclass/mount-boot-utils.eclass b/eclass/mount-boot-utils.eclass
index e24b4e0c0826..72b4c9ccd14a 100644
--- a/eclass/mount-boot-utils.eclass
+++ b/eclass/mount-boot-utils.eclass
@@ -1,4 +1,4 @@
-# Copyright 1999-2024 Gentoo Authors
+# Copyright 1999-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: mount-boot-utils.eclass
@@ -16,6 +16,18 @@
# This eclass provides the functions used by mount-boot.eclass in an "inherit-
# safe" way. This allows these functions to be used in other eclasses cleanly.
+# @ECLASS_VARIABLE: DONT_MOUNT_BOOT
+# @USER_VARIABLE
+# @DESCRIPTION:
+# May be set by the user or an ebuild to completely disable mount checking
+# of the /boot partition and the EFI System Partition.
+
+# @ECLASS_VARIABLE: DONT_MOUNT_ESP
+# @USER_VARIABLE
+# @DESCRIPTION:
+# May be set by the user or an ebuild to disable mount checking of the
+# EFI System Partition only.
+
case ${EAPI} in
7|8) ;;
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
@@ -62,7 +74,7 @@ mount-boot_check_status() {
local candidates=( /boot )
# If system is booted with UEFI, check for ESP as well
- if [[ -d /sys/firmware/efi ]]; then
+ if [[ -d /sys/firmware/efi && -z ${DONT_MOUNT_ESP} ]]; then
# Use same candidates for ESP as installkernel and eclean-kernel
candidates+=( /efi /boot/efi /boot/EFI )
fi
diff --git a/eclass/office-ext-r1.eclass b/eclass/office-ext-r1.eclass
index 7e4d894483fe..9ee4561f0c11 100644
--- a/eclass/office-ext-r1.eclass
+++ b/eclass/office-ext-r1.eclass
@@ -1,4 +1,4 @@
-# Copyright 1999-2023 Gentoo Authors
+# Copyright 1999-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: office-ext-r1.eclass
@@ -6,13 +6,13 @@
# The office team <office@gentoo.org>
# @AUTHOR:
# Tomáš Chvátal <scarabeus@gentoo.org>
-# @SUPPORTED_EAPIS: 7
+# @SUPPORTED_EAPIS: 7 8
# @BLURB: Eclass for installing libreoffice extensions
# @DESCRIPTION:
# Eclass for easing maintenance of libreoffice extensions.
case ${EAPI} in
- 7) ;;
+ 7|8) ;;
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
esac
@@ -70,11 +70,13 @@ fi
# @CODE
: "${OFFICE_EXTENSIONS_LOCATION:=${DISTDIR}}"
-IUSE=""
-RDEPEND=""
+# Most projects actually do not provide any relevant sourcedir as they are oxt.
+S="${WORKDIR}"
+
+IUSE="$(printf 'office_implementation_%s ' ${OFFICE_IMPLEMENTATIONS[@]})"
+REQUIRED_USE="|| ( $(printf 'office_implementation_%s ' ${OFFICE_IMPLEMENTATIONS[@]}) )"
for i in ${OFFICE_IMPLEMENTATIONS[@]}; do
- IUSE+=" office_implementation_${i}"
if [[ ${i} == "libreoffice" ]]; then
RDEPEND+="
office_implementation_${i}? (
@@ -86,19 +88,7 @@ for i in ${OFFICE_IMPLEMENTATIONS[@]}; do
"
fi
done
-
-REQUIRED_USE="|| ( "
-for i in ${OFFICE_IMPLEMENTATIONS[@]}; do
- REQUIRED_USE+=" office_implementation_${i} "
-done
-REQUIRED_USE+=" )"
-
-DEPEND="${RDEPEND}
- app-arch/unzip
-"
-
-# Most projects actually do not provide any relevant sourcedir as they are oxt.
-S="${WORKDIR}"
+BDEPEND="app-arch/unzip"
# @FUNCTION: office-ext-r1_src_unpack
# @DESCRIPTION:
diff --git a/eclass/plasma.kde.org.eclass b/eclass/plasma.kde.org.eclass
index 1a626de37bfb..6612028e298b 100644
--- a/eclass/plasma.kde.org.eclass
+++ b/eclass/plasma.kde.org.eclass
@@ -25,6 +25,13 @@ esac
if [[ -z ${_PLASMA_KDE_ORG_ECLASS} ]]; then
_PLASMA_KDE_ORG_ECLASS=1
+# @ECLASS_VARIABLE: KDE_CATV
+# @DESCRIPTION:
+# Holds main Plasma release number (major.minor.micro) for use on same-category
+# dependencies.
+KDE_CATV=$(ver_cut 1-3)
+readonly KDE_CATV
+
# @ECLASS_VARIABLE: KDE_PV_UNRELEASED
# @INTERNAL
# @DESCRIPTION:
@@ -64,10 +71,10 @@ if [[ ${KDE_BUILD_TYPE} == live ]]; then
elif [[ -z ${KDE_ORG_COMMIT} ]]; then
case ${PV} in
5.??.[6-9][05]* | 6.?.[6-9][05]* )
- _KDE_SRC_URI+="unstable/plasma/$(ver_cut 1-3)/"
+ _KDE_SRC_URI+="unstable/plasma/${KDE_CATV}/"
RESTRICT+=" mirror"
;;
- *) _KDE_SRC_URI+="stable/plasma/$(ver_cut 1-3)/" ;;
+ *) _KDE_SRC_URI+="stable/plasma/${KDE_CATV}/" ;;
esac
SRC_URI="${_KDE_SRC_URI}${KDE_ORG_TAR_PN}-${PV}.tar.xz"
diff --git a/eclass/qt6-build.eclass b/eclass/qt6-build.eclass
index f8161447074a..ca6c63081053 100644
--- a/eclass/qt6-build.eclass
+++ b/eclass/qt6-build.eclass
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 Gentoo Authors
+# Copyright 2021-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: qt6-build.eclass
@@ -296,7 +296,7 @@ _qt6-build_sanitize_cpu_flags() {
# extras only needed by chromium in qtwebengine
# (see also chromium's ebuild wrt bug #530248,#544702,#546984,#853646)
[[ ${PN} == qtwebengine ]] && cpuflags+=(
- mmx xop
+ avx512vnni mmx xop
# unclear if these two are really needed given (current) chromium
# does not pass these flags, albeit it may side-disable something
diff --git a/eclass/ruby-fakegem.eclass b/eclass/ruby-fakegem.eclass
index eb6257a50cf9..c358015902bb 100644
--- a/eclass/ruby-fakegem.eclass
+++ b/eclass/ruby-fakegem.eclass
@@ -23,6 +23,8 @@ case ${EAPI} in
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
esac
+# flag-o-matic is only required for ruby31 support.
+inherit flag-o-matic
inherit ruby-ng
# @ECLASS_VARIABLE: RUBY_FAKEGEM_NAME
@@ -424,6 +426,16 @@ EOF
each_fakegem_configure() {
debug-print-function ${FUNCNAME} "$@"
+ # Ruby 3.1 has a varargs implementation that is not compatible with
+ # gnu23. Ruby 3.1 is EOL in March 2025 and will be removed shortly
+ # after that.
+ case ${RUBY} in
+ *ruby31)
+ append-flags -std=gnu17
+ filter-flags -std=gnu23
+ ;;
+ esac
+
tc-export PKG_CONFIG
for extension in "${RUBY_FAKEGEM_EXTENSIONS[@]}" ; do
CC=$(tc-getCC) ${RUBY} --disable=did_you_mean -C ${extension%/*} ${extension##*/} --with-cflags="${CFLAGS}" --with-ldflags="${LDFLAGS}" ${RUBY_FAKEGEM_EXTENSION_OPTIONS} || die
@@ -612,7 +624,7 @@ each_fakegem_install() {
ruby_fakegem_install_gemspec
local _gemlibdirs="${RUBY_FAKEGEM_EXTRAINSTALL}"
- for directory in "${RUBY_FAKEGEM_BINDIR}" lib; do
+ for directory in "${RUBY_FAKEGEM_BINDIR}" lib sig; do
[[ -d ${directory} ]] && _gemlibdirs="${_gemlibdirs} ${directory}"
done
diff --git a/eclass/ruby-utils.eclass b/eclass/ruby-utils.eclass
index 29b9ab396b87..4bd3e6ba1292 100644
--- a/eclass/ruby-utils.eclass
+++ b/eclass/ruby-utils.eclass
@@ -36,14 +36,14 @@ esac
RUBY_TARGETS_PREFERENCE="ruby32 ruby31 "
# All other active ruby targets
-RUBY_TARGETS_PREFERENCE+="ruby33"
+RUBY_TARGETS_PREFERENCE+="ruby33 ruby34"
_ruby_implementation_depend() {
local rubypn=
local rubyslot=
case $1 in
- ruby1[89]|ruby2[0-7]|ruby3[0-3])
+ ruby1[89]|ruby2[0-7]|ruby3[0-4])
rubypn="dev-lang/ruby"
rubyslot=":${1:4:1}.${1:5}"
;;
diff --git a/eclass/rust.eclass b/eclass/rust.eclass
index eb14ca2329b5..0630d5973854 100644
--- a/eclass/rust.eclass
+++ b/eclass/rust.eclass
@@ -1,4 +1,4 @@
-# Copyright 2024 Gentoo Authors
+# Copyright 2024-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: rust.eclass
@@ -67,6 +67,7 @@ fi
# @DESCRIPTION:
# Definitive list of Rust slots and the associated LLVM slot, newest first.
declare -A -g -r _RUST_LLVM_MAP=(
+ ["1.84.0"]=19
["1.83.0"]=19
["1.82.0"]=19
["1.81.0"]=18
@@ -88,6 +89,7 @@ declare -A -g -r _RUST_LLVM_MAP=(
# While _RUST_LLVM_MAP stores useful info about the relationship between Rust and LLVM slots,
# this array is used to store the Rust slots in a more convenient order for iteration.
declare -a -g -r _RUST_SLOTS_ORDERED=(
+ "1.84.0"
"1.83.0"
"1.82.0"
"1.81.0"
@@ -286,7 +288,8 @@ unset -f _rust_set_globals
# @USAGE: [-b|-d]
# @DESCRIPTION:
# Find the newest Rust install that is acceptable for the package,
-# and print its version number (i.e. SLOT) and type (source or bin[ary]).
+# and export its version (i.e. SLOT) and type (source or bin[ary])
+# as RUST_SLOT and RUST_TYPE.
#
# If -b is specified, the checks are performed relative to BROOT,
# and BROOT-path is returned. -b is the default.
@@ -363,10 +366,13 @@ _get_rust_slot() {
# If we're in LLVM mode we can skip any slots that don't match the selected USE
if [[ -n "${RUST_NEEDS_LLVM}" ]]; then
if [[ "${llvm_slot}" != "${llvm_r1_slot}" ]]; then
+ einfo "Skipping Rust ${slot} as it does not match llvm_slot_${llvm_r1_slot}"
continue
fi
fi
+ einfo "Checking whether Rust ${slot} is suitable ..."
+
if declare -f rust_check_deps >/dev/null; then
local RUST_SLOT="${slot}"
local LLVM_SLOT="${_RUST_LLVM_MAP[${slot}]}"
@@ -396,11 +402,13 @@ _get_rust_slot() {
esac
local _pkg
for _pkg in "${rust_pkgs[@]}"; do
+ einfo " Checking for ${_pkg} ..."
if has_version "${hv_switch}" "${_pkg}"; then
+ export RUST_SLOT="${slot}"
if [[ "${_pkg}" == "dev-lang/rust:${slot}${usedep}" ]]; then
- echo "${slot} source"
+ export RUST_TYPE="source"
else
- echo "${slot} binary"
+ export RUST_TYPE="binary"
fi
return
fi
@@ -418,7 +426,12 @@ _get_rust_slot() {
die "${FUNCNAME}: invalid max_slot=${max_slot}"
fi
- die "No Rust slot${1:+ <= ${1}} satisfying the package's dependencies found installed!"
+ local requirement_msg=""
+ [[ -n "${RUST_MAX_VER}" ]] && requirement_msg+="<= ${RUST_MAX_VER} "
+ [[ -n "${RUST_MIN_VER}" ]] && requirement_msg+=">= ${RUST_MIN_VER} "
+ [[ -n "${RUST_REQ_USE}" ]] && requirement_msg+="with USE=${RUST_REQ_USE}"
+ requirement_msg="${requirement_msg% }"
+ die "No Rust matching requirements${requirement_msg:+ (${requirement_msg})} found installed!"
}
# @FUNCTION: get_rust_path
@@ -460,9 +473,8 @@ get_rust_prefix() {
local prefix=${BROOT}
[[ ${1} == -d ]] && prefix=${ESYSROOT}
- local slot rust_type
- read -r slot rust_type <<< $(_get_rust_slot "$@")
- get_rust_path "${prefix}" "${slot}" "${rust_type}"
+ _get_rust_slot "$@"
+ get_rust_path "${prefix}" "${RUST_SLOT}" "${RUST_TYPE}"
}
# @FUNCTION: rust_prepend_path
@@ -500,7 +512,7 @@ rust_pkg_setup() {
debug-print-function ${FUNCNAME} "$@"
if [[ ${MERGE_TYPE} != binary ]]; then
- read -r RUST_SLOT RUST_TYPE <<< $(_get_rust_slot -b)
+ _get_rust_slot -b
rust_prepend_path "${RUST_SLOT}" "${RUST_TYPE}"
local prefix=$(get_rust_path "${BROOT}" "${RUST_SLOT}" "${RUST_TYPE}")
CARGO="${prefix}bin/cargo"
diff --git a/eclass/secureboot.eclass b/eclass/secureboot.eclass
index a854061719a9..7361465ee2d3 100644
--- a/eclass/secureboot.eclass
+++ b/eclass/secureboot.eclass
@@ -1,4 +1,4 @@
-# Copyright 1999-2024 Gentoo Authors
+# Copyright 1999-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: secureboot.eclass
@@ -57,6 +57,13 @@ BDEPEND="
# @DESCRIPTION:
# Used with USE=secureboot. Should be set to the path of the private
# key in PEM format to use, or a PKCS#11 URI.
+# If unspecified the following locations are tried in order:
+# - /etc/portage/secureboot.pem
+# - /var/lib/sbctl/keys/db/db.{key,pem} (from app-crypt/sbctl)
+# - the MODULES_SIGN_KEY (and MODULES_SIGN_CERT if set)
+# - the contents of CONFIG_MODULE_SIG_KEY in the current kernel
+# If none of these exist, a new key will be generated at
+# /etc/portage/secureboot.pem.
# @ECLASS_VARIABLE: SECUREBOOT_SIGN_CERT
# @USER_VARIABLE
@@ -64,36 +71,13 @@ BDEPEND="
# @DESCRIPTION:
# Used with USE=secureboot. Should be set to the path of the public
# key certificate in PEM format to use.
+# If unspecified the SECUREBOOT_SIGN_KEY is assumed to also contain the
+# certificate belonging to it.
if [[ -z ${_SECUREBOOT_ECLASS} ]]; then
_SECUREBOOT_ECLASS=1
-# @FUNCTION: _secureboot_die_if_unset
-# @INTERNAL
-# @DESCRIPTION:
-# If USE=secureboot is enabled die if the required user variables are unset
-# and die if the keys can't be found.
-_secureboot_die_if_unset() {
- debug-print-function ${FUNCNAME} "$@"
- use secureboot || return
-
- if [[ -z ${SECUREBOOT_SIGN_KEY} || -z ${SECUREBOOT_SIGN_CERT} ]]; then
- die "USE=secureboot enabled but SECUREBOOT_SIGN_KEY and/or SECUREBOOT_SIGN_CERT not set."
- fi
-
- # Sanity check: fail early if key/cert in DER format or does not exist
- local openssl_args=(
- -inform PEM -in "${SECUREBOOT_SIGN_CERT}"
- -noout -nocert
- )
- if [[ ${SECUREBOOT_SIGN_KEY} == pkcs11:* ]]; then
- openssl_args+=( -engine pkcs11 -keyform ENGINE -key "${SECUREBOOT_SIGN_KEY}" )
- else
- openssl_args+=( -keyform PEM -key "${SECUREBOOT_SIGN_KEY}" )
- fi
- openssl x509 "${openssl_args[@]}" ||
- die "Secure Boot signing certificate or key not found or not PEM format."
-}
+inherit linux-info
# @FUNCTION: secureboot_pkg_setup
# @DESCRIPTION:
@@ -105,7 +89,114 @@ secureboot_pkg_setup() {
# If we are merging a binary then the files in this binary
# are already signed, no need to check the variables.
if [[ ${MERGE_TYPE} != binary ]]; then
- _secureboot_die_if_unset
+ if [[ -z ${SECUREBOOT_SIGN_KEY} ]]; then
+ # No key specified, try some usual suspects
+ linux-info_pkg_setup
+ local module_sig_key=
+ if linux_config_exists MODULE_SIG_KEY; then
+ : "$(linux_chkconfig_string MODULE_SIG_KEY)"
+ module_sig_key=${_//\"}
+ # Convert to absolute path if required
+ if [[ ${module_sig_key} != pkcs11:* &&
+ ${module_sig_key} != /* ]]
+ then
+ module_sig_key=${KV_OUT_DIR}/${module_sig_key}
+ fi
+ fi
+
+ # Check both the SYSROOT and ROOT, like linux-info.eclass
+ ewarn "No Secure Boot signing key specified."
+ if [[ -r ${SYSROOT}/etc/portage/secureboot.pem ]]; then
+ ewarn "Using ${SYSROOT}/etc/portage/secureboot.pem as signing key"
+ export SECUREBOOT_SIGN_KEY=${SYSROOT}/etc/portage/secureboot.pem
+ export SECUREBOOT_SIGN_CERT=${SYSROOT}/etc/portage/secureboot.pem
+ elif [[ -r ${ROOT}/etc/portage/secureboot.pem ]]; then
+ ewarn "Using ${ROOT}/etc/portage/secureboot.pem as signing key"
+ export SECUREBOOT_SIGN_KEY=${ROOT}/etc/portage/secureboot.pem
+ export SECUREBOOT_SIGN_CERT=${ROOT}/etc/portage/secureboot.pem
+ elif [[ -r ${SYSROOT}/var/lib/sbctl/keys/db/db.key &&
+ -r ${SYSROOT}/var/lib/sbctl/keys/db/db.pem ]]
+ then
+ ewarn "Using keys maintained by app-crypt/sbctl"
+ export SECUREBOOT_SIGN_KEY=${SYSROOT}/var/lib/sbctl/keys/db/db.key
+ export SECUREBOOT_SIGN_CERT=${SYSROOT}/var/lib/sbctl/keys/db/db.pem
+ elif [[ -r ${ROOT}/var/lib/sbctl/keys/db/db.key &&
+ -r ${ROOT}/var/lib/sbctl/keys/db/db.pem ]]
+ then
+ ewarn "Using keys maintained by app-crypt/sbctl"
+ export SECUREBOOT_SIGN_KEY=${ROOT}/var/lib/sbctl/keys/db/db.key
+ export SECUREBOOT_SIGN_CERT=${ROOT}/var/lib/sbctl/keys/db/db.pem
+ elif [[ -r ${MODULES_SIGN_KEY} ]]; then
+ ewarn "Using the kernel module signing key"
+ export SECUREBOOT_SIGN_KEY=${MODULES_SIGN_KEY}
+ if [[ -r ${MODULES_SIGN_CERT} ]]; then
+ export SECUREBOOT_SIGN_CERT=${MODULES_SIGN_CERT}
+ else
+ export SECUREBOOT_SIGN_CERT=${MODULES_SIGN_KEY}
+ fi
+ elif [[ -r ${KV_OUT_DIR}/certs/signing_key.x509 ]] &&
+ [[ -r ${module_sig_key} || ${module_sig_key} == pkcs11:* ]]
+ then
+ ewarn "Using keys maintained by the kernel"
+ openssl x509 \
+ -in "${KV_OUT_DIR}/certs/signing_key.x509" -inform DER \
+ -out "${T}/secureboot.pem" -outform PEM ||
+ die "Failed to convert kernel certificate to PEM format"
+ export SECUREBOOT_SIGN_KEY=${module_sig_key}
+ export SECUREBOOT_SIGN_CERT=${T}/secureboot.pem
+ else
+ ewarn "No candidate keys found, generating a new key"
+ local openssl_gen_args=(
+ req -new -batch -nodes -utf8 -sha256 -days 36500 -x509
+ -outform PEM -out "${SYSROOT}/etc/portage/secureboot.pem"
+ -keyform PEM -keyout "${SYSROOT}/etc/portage/secureboot.pem"
+ )
+ if [[ -r ${KV_OUT_DIR}/certs/x509.genkey ]]; then
+ openssl_gen_args+=(
+ -config "${KV_OUT_DIR}/certs/x509.genkey"
+ )
+ elif [[ -r ${KV_OUT_DIR}/certs/default_x509.genkey ]]; then
+ openssl_gen_args+=(
+ -config "${KV_OUT_DIR}/certs/default_x509.genkey"
+ )
+ else
+ openssl_gen_args+=(
+ -subj '/CN=Build time autogenerated kernel key'
+ )
+ fi
+ (
+ umask 066
+ openssl "${openssl_gen_args[@]}" ||
+ die "Failed to generate new signing key"
+ # Generate DER format key as well for easy inclusion in
+ # either the UEFI dB or MOK list.
+ openssl x509 \
+ -in "${SYSROOT}/etc/portage/secureboot.pem" -inform PEM \
+ -out "${ROOT}/etc/portage/secureboot.x509" -outform DER ||
+ die "Failed to convert signing certificate to DER format"
+ )
+ export SECUREBOOT_SIGN_KEY=${SYSROOT}/etc/portage/secureboot.pem
+ export SECUREBOOT_SIGN_CERT=${SYSROOT}/etc/portage/secureboot.pem
+ fi
+ elif [[ -z ${SECUREBOOT_SIGN_CERT} ]]; then
+ ewarn "A SECUREBOOT_SIGN_KEY was specified but no SECUREBOOT_SIGN_CERT"
+ ewarn "was set. Assuming the certificate is in the same file as the key."
+ export SECUREBOOT_SIGN_CERT=${SECUREBOOT_SIGN_KEY}
+ fi
+
+ # Sanity check: fail early if key/cert in DER format or does not exist
+ local openssl_args=(
+ -inform PEM -in "${SECUREBOOT_SIGN_CERT}"
+ -noout -nocert
+ )
+ if [[ ${SECUREBOOT_SIGN_KEY} == pkcs11:* ]]; then
+ openssl_args+=( -engine pkcs11 -keyform ENGINE -key "${SECUREBOOT_SIGN_KEY}" )
+ else
+ openssl_args+=( -keyform PEM -key "${SECUREBOOT_SIGN_KEY}" )
+ fi
+
+ openssl x509 "${openssl_args[@]}" ||
+ die "Secure Boot signing certificate or key not found or not PEM format."
fi
}
@@ -123,8 +214,6 @@ secureboot_sign_efi_file() {
local input_file=${1}
local output_file=${2:-${1}}
- _secureboot_die_if_unset
-
ebegin "Signing ${input_file}"
local return=1
if sbverify "${input_file}" --cert "${SECUREBOOT_SIGN_CERT}" &> /dev/null; then
diff --git a/eclass/tests/llvm-r1.sh b/eclass/tests/llvm-r1.sh
index 892b773a08c9..d4657815465d 100755
--- a/eclass/tests/llvm-r1.sh
+++ b/eclass/tests/llvm-r1.sh
@@ -54,7 +54,7 @@ test_gen_dep() {
local value=$(llvm_gen_dep "${arg}")
if [[ ${value} != ${expected} ]]; then
- eerror "python_get_usedep ${arg}"
+ eerror "llvm_gen_dep ${arg}"
eerror "gave:"
eerror " ${value}"
eerror "expected:"
@@ -63,67 +63,9 @@ test_gen_dep() {
tend ${?}
}
-test_fix_clang_version() {
- local var=${1}
- local tool=${2}
- local version=${3}
- local expected=${4}
-
- eval "${tool}() {
- cat <<-EOF
- clang version ${version}
- Target: x86_64-pc-linux-gnu
- Thread model: posix
- InstalledDir: /usr/lib/llvm/17/bin
- Configuration file: /etc/clang/x86_64-pc-linux-gnu-clang.cfg
- EOF
- }"
-
- declare -g ${var}=${tool}
- tbegin "llvm_fix_clang_version ${var}=${tool} for ${version}"
- llvm_fix_clang_version "${var}"
- if [[ ${!var} != ${expected} ]]; then
- eerror "llvm_fix_clang_version ${var}"
- eerror " gave: ${!var}"
- eerror "expected: ${expected}"
- fi
- tend ${?}
-}
-
-test_fix_tool_path() {
- local var=${1}
- local tool=${2}
- local expected_subst=${3}
- local expected=${tool}
-
- tbegin "llvm_fix_tool_path ${1}=${2} (from llvm? ${expected_subst})"
-
- local matches=( "${BROOT}"/usr/lib/llvm/*/bin/"${tool}" )
- if [[ ${expected_subst} == 1 ]]; then
- if [[ ! -x ${matches[0]} ]]; then
- ewarn "- skipping, test requires ${tool}"
- return
- fi
-
- expected=${matches[0]}
- local -x PATH=${matches[0]%/*}
- else
- local -x PATH=
- fi
-
- declare -g ${var}=${tool}
- llvm_fix_tool_path "${var}"
- if [[ ${!var} != ${expected} ]]; then
- eerror "llvm_fix_tool_path ${var}"
- eerror " gave: ${!var}"
- eerror "expected: ${expected}"
- fi
- tend ${?}
-}
-
# full range
test_globals '14 15 16 17 18 19' \
- "+llvm_slot_18 llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_19" \
+ "+llvm_slot_19 llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18" \
"^^ ( llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18 llvm_slot_19 )" \
"llvm_slot_15(-)?,llvm_slot_16(-)?,llvm_slot_17(-)?,llvm_slot_18(-)?,llvm_slot_19(-)?"
test_globals '14 15 16 17 18' \
@@ -136,10 +78,10 @@ test_globals '14 15 16' \
"^^ ( llvm_slot_15 llvm_slot_16 )" \
"llvm_slot_15(-)?,llvm_slot_16(-)?"
# old + newer than current stable
-test_globals '15 19' \
- "+llvm_slot_15 llvm_slot_19" \
- "^^ ( llvm_slot_15 llvm_slot_19 )" \
- "llvm_slot_15(-)?,llvm_slot_19(-)?"
+test_globals '15 20' \
+ "+llvm_slot_15 llvm_slot_20" \
+ "^^ ( llvm_slot_15 llvm_slot_20 )" \
+ "llvm_slot_15(-)?,llvm_slot_20(-)?"
# newer than current stable
test_globals '19' \
"+llvm_slot_19" \
diff --git a/eclass/tests/llvm-r2.sh b/eclass/tests/llvm-r2.sh
new file mode 100755
index 000000000000..fde76d2d682e
--- /dev/null
+++ b/eclass/tests/llvm-r2.sh
@@ -0,0 +1,188 @@
+#!/bin/bash
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+source tests-common.sh || exit
+
+EAPI=8
+
+test_globals() {
+ local compat=${1}
+ local expected_iuse=${2}
+ local expected_required_use=${3}
+ local expected_usedep=${4}
+ local x
+
+ tbegin "LLVM_COMPAT=( ${compat} )"
+
+ (
+ local fail=0
+ local LLVM_COMPAT=( ${compat} )
+
+ inherit llvm-r2
+
+ if [[ ${IUSE%% } != ${expected_iuse} ]]; then
+ eerror " IUSE: ${IUSE%% }"
+ eerror "does not match: ${expected_iuse}"
+ fail=1
+ fi
+
+ if [[ ${REQUIRED_USE} != ${expected_required_use} ]]; then
+ eerror " REQUIRED_USE: ${REQUIRED_USE}"
+ eerror "does not match: ${expected_required_use}"
+ fail=1
+ fi
+
+ if [[ ${LLVM_USEDEP} != ${expected_usedep} ]]; then
+ eerror " LLVM_USEDEP: ${LLVM_USEDEP}"
+ eerror "does not match: ${expected_usedep}"
+ fail=1
+ fi
+
+ exit "${fail}"
+ )
+
+ tend "${?}"
+}
+
+test_gen_dep() {
+ local arg=${1}
+ local expected
+ read -r -d '' expected
+
+ tbegin "llvm_gen_dep ${arg}"
+ local value=$(llvm_gen_dep "${arg}")
+
+ if [[ ${value} != ${expected} ]]; then
+ eerror "llvm_gen_dep ${arg}"
+ eerror "gave:"
+ eerror " ${value}"
+ eerror "expected:"
+ eerror " ${expected}"
+ fi
+ tend ${?}
+}
+
+LLVM_CONFIG_OPTIONS=(
+ --assertion-mode
+ --bindir
+ --build-mode
+ --build-system
+ --cflags
+ --cmakedir
+ --components
+ --cppflags
+ --cxxflags
+ --has-rtti
+ --host-target
+ --ignore-libllvm
+ --includedir
+ --ldflags
+ --libdir
+ --libfiles
+ --libnames
+ --libs
+ --link-shared
+ --link-static
+ --obj-root
+ --prefix
+ --shared-mode
+ --system-libs
+ --targets-built
+ --version
+)
+
+normalize_list() {
+ "${@}" |
+ sed -e 's:\s\+:\n:g' |
+ sed -e '/^$/d' |
+ sort
+ local ps=${PIPESTATUS[*]}
+ [[ ${ps} == '0 0 0 0' ]] || die "normalize_list pipe failed: ${ps}"
+}
+
+test_llvm_config() {
+ einfo "llvm-config for slot ${LLVM_SLOT}, libdir ${LLVM_LIBDIR}"
+ eindent
+
+ generate_llvm_config > "${TMP}/llvm-config" || die
+ local triple=$(sh "${TMP}/llvm-config" --host-target || die)
+ local llvm_config=/usr/lib/llvm/${LLVM_SLOT}/bin/${triple}-llvm-config
+
+ local option res
+ for option in "${LLVM_CONFIG_OPTIONS[@]}"; do
+ tbegin "${option}"
+
+ normalize_list sh "${TMP}/llvm-config" "${option}" > "${TMP}/our"
+ normalize_list "${llvm_config}" "${option}" > "${TMP}/upstream"
+ case ${option} in
+ --components)
+ # our components are a superset of what llvm-config yields
+ res=$(comm -13 "${TMP}/our" "${TMP}/upstream")
+ ;;
+ *)
+ # expect all elements to match
+ res=$(comm -3 "${TMP}/our" "${TMP}/upstream")
+ ;;
+ esac
+
+ if [[ -z ${res} ]]; then
+ tend 0
+ else
+ eerror "$(diff -u "${TMP}/our" "${TMP}/upstream")"
+ tend 1
+ fi
+ done
+
+ eoutdent
+}
+
+# full range
+test_globals '14 15 16 17 18 19' \
+ "+llvm_slot_19 llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18" \
+ "^^ ( llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18 llvm_slot_19 )" \
+ "llvm_slot_15(-)?,llvm_slot_16(-)?,llvm_slot_17(-)?,llvm_slot_18(-)?,llvm_slot_19(-)?"
+test_globals '14 15 16 17 18' \
+ "+llvm_slot_18 llvm_slot_15 llvm_slot_16 llvm_slot_17" \
+ "^^ ( llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18 )" \
+ "llvm_slot_15(-)?,llvm_slot_16(-)?,llvm_slot_17(-)?,llvm_slot_18(-)?"
+# older than stable
+test_globals '14 15 16' \
+ "+llvm_slot_16 llvm_slot_15" \
+ "^^ ( llvm_slot_15 llvm_slot_16 )" \
+ "llvm_slot_15(-)?,llvm_slot_16(-)?"
+# old + newer than current stable
+test_globals '15 20' \
+ "+llvm_slot_15 llvm_slot_20" \
+ "^^ ( llvm_slot_15 llvm_slot_20 )" \
+ "llvm_slot_15(-)?,llvm_slot_20(-)?"
+# newer than current stable
+test_globals '19' \
+ "+llvm_slot_19" \
+ "^^ ( llvm_slot_19 )" \
+ "llvm_slot_19(-)?"
+
+LLVM_COMPAT=( {14..18} )
+inherit llvm-r2
+
+test_gen_dep 'llvm-core/llvm:${LLVM_SLOT} llvm-core/clang:${LLVM_SLOT}' <<-EOF
+ llvm_slot_15? ( llvm-core/llvm:15 llvm-core/clang:15 )
+ llvm_slot_16? ( llvm-core/llvm:16 llvm-core/clang:16 )
+ llvm_slot_17? ( llvm-core/llvm:17 llvm-core/clang:17 )
+ llvm_slot_18? ( llvm-core/llvm:18 llvm-core/clang:18 )
+EOF
+
+TMP=$(mktemp -d || die)
+trap 'rm -rf \"${TMP}\"' EXIT
+get_libdir() { echo "${LLVM_LIBDIR}"; }
+
+for installed_llvm_cmake in /usr/lib/llvm/*/lib*/cmake; do
+ installed_llvm_libdir=${installed_llvm_cmake%/*}
+ LLVM_LIBDIR=${installed_llvm_libdir##*/}
+ installed_llvm=${installed_llvm_libdir%/*}
+ LLVM_SLOT=${installed_llvm##*/}
+
+ test_llvm_config
+done
+
+texit
diff --git a/eclass/tests/zig-utils.sh b/eclass/tests/zig-utils.sh
new file mode 100755
index 000000000000..14af1d2105e3
--- /dev/null
+++ b/eclass/tests/zig-utils.sh
@@ -0,0 +1,320 @@
+#!/bin/bash
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+source tests-common.sh || exit
+
+inherit zig-utils
+
+# Set ZIG_TEST_COMPILATION env-var to "1" if you want to test binary
+# compilation and running under QEMU. Assumes "zig" is present in PATH
+# and qemu binfmt is enabled.
+#
+# If CPU is marked with ":no-run", it means program compiled for it
+# successfully but crashed when running under QEMU.
+if [[ "${ZIG_TEST_COMPILATION:-0}" -eq 1 ]]; then
+ MY_WORKDIR="$(mktemp -d)"
+ my_cleanup() {
+ popd > /dev/null
+ rm -rf "${MY_WORKDIR}"
+ }
+ trap 'my_cleanup' EXIT
+
+ pushd "${MY_WORKDIR}" > /dev/null || die
+ cat <<- _EOF_ > main.zig || die
+ const std = @import("std");
+
+ pub fn main() !void {
+ const stdout = std.io.getStdOut();
+ try stdout.writeAll("Hello, Gentoo!\n");
+ }
+ _EOF_
+
+ zig_test_compile_and_run() {
+ eindent
+ einfo "${1}: ${2}"
+ eoutdent
+
+ if [[ "${2}" == native* ]]; then
+ return 0
+ fi
+
+ if [[ "${1}" == arm* ]]; then
+ # Bunch of unimplemented Zig
+ # routines for more "bare-bone" arm.
+ case "${2}" in
+ # Some errors in inline assembly, likely too low baseline
+ generic-soft_float | generic+soft_float) return 0;;
+ # undefined symbol: __sync_fetch_and_add_1
+ # compiler-rt not implemented in upstream for it yet:
+ # https://github.com/ziglang/zig/issues/4959
+ generic+v5te-soft_float) return 0;;
+ *) ;;
+ esac
+ fi
+
+ local ret=0
+
+ local args=(
+ -target "${1}"
+ -mcpu "${2//:no-run/}"
+ main.zig
+ )
+ if ! zig build-exe "${args[@]}" > /dev/null; then
+ eerror "Failed to compile for: ${1}, ${2}"
+ ((++ret))
+ return ${ret}
+ fi
+
+ # Can't run macOS binaries in Linux user-mode QEMU emulators
+ if [[ "${1}" == *macos* || "${2}" == *":no-run" ]]; then
+ return ${ret}
+ fi
+
+ if ! ./main > /dev/null; then
+ eerror "Failed to run for: ${1}, ${2}"
+ ((++ret))
+ fi
+
+ return ${ret}
+ }
+else
+ zig_test_compile_and_run() { :; }
+fi
+
+test-convert_c_env_to_zig_tuple() {
+ local ret=0
+
+ local -n map=${1}
+
+ local c_tuple
+ for key in "${!map[@]}"; do
+ local expected="${map["${key}"]}"
+
+ local c_tuple
+ local c_flags
+ if [[ "${key}" == *:* ]]; then
+ c_tuple="${key%%:*}"
+ c_flags="${key##*:}"
+ else
+ c_tuple="${key}"
+ c_flags=""
+ fi
+
+ local actual="$(zig-utils_c_env_to_zig_target "${c_tuple}" "${c_flags}")"
+ if [[ "${expected}" != "${actual}" ]]; then
+ eerror "Translating ${c_tuple}: expected ${expected}, found ${actual}"
+ ((++ret))
+ continue
+ fi
+
+ local zig_cpu="$(zig-utils_c_env_to_zig_cpu "${c_tuple}" "${c_flags}")"
+ if ! zig_test_compile_and_run "${expected}" "${zig_cpu}"; then
+ ((++ret))
+ continue
+ fi
+ done
+
+ return ${ret}
+}
+
+test-convert_c_env_to_zig_cpu() {
+ local ret=0
+
+ local -n map=${1}
+ local chost=${2}
+
+ local c_flags
+ for c_flags in "${!map[@]}"; do
+ local expected="${map["${c_flags}"]}"
+ local actual="$(zig-utils_c_env_to_zig_cpu "${chost}" "${c_flags}")"
+ if [[ "${expected//:no-run/}" != "${actual}" ]]; then
+ eerror "Translating ${c_flags}: expected ${expected//:no-run/}, found ${actual}"
+ ((++ret))
+ continue
+ fi
+
+ local zig_target="$(zig-utils_c_env_to_zig_target "${chost}" "${c_flags}")"
+ if ! zig_test_compile_and_run "${zig_target}" "${expected}"; then
+ ((++ret))
+ continue
+ fi
+ done
+
+ return ${ret}
+}
+
+tbegin '"C tuple to Zig tuple"'
+declare -A c_to_zig_map=(
+ # Just remove "vendor" field
+ [aarch64-unknown-linux-gnu]=aarch64-linux-gnu
+ [arm-unknown-linux-musleabi]=arm-linux-musleabi
+ [x86_64-pc-linux-gnu]=x86_64-linux-gnu
+ [loongarch64-unknown-linux-gnu]=loongarch64-linux-gnu
+ [powerpc64le-unknown-linux-gnu]=powerpc64le-linux-gnu
+
+ # ARM big-endian
+ [armeb-unknown-linux-gnueabi]=armeb-linux-gnueabi
+
+ # https://bugs.gentoo.org/924920
+ [armv7a-unknown-linux-gnueabihf]=arm-linux-gnueabihf
+
+ # ARM to Thumb
+ [arm-unknown-linux-musleabi:"-march=armv7e-m"]=thumb-linux-musleabi
+
+ # ARM families
+ [armv6j-unknown-linux-gnueabihf]=arm-linux-gnueabihf
+ [armv6j-linux-gnueabihf]=arm-linux-gnueabihf
+ [armv7a-softfp-linux-gnueabi]=arm-linux-gnueabi
+ [armv7a-linux-gnueabi]=arm-linux-gnueabi
+
+ # X86 (32-bit) families
+ [i486-pc-linux-gnu]=x86-linux-gnu
+ [i686-linux-gnu]=x86-linux-gnu
+
+ # MacOS
+ [x86_64-apple-darwin15]=x86_64-macos-none
+ [arm64-apple-darwin24]=aarch64-macos-none
+)
+test-convert_c_env_to_zig_tuple c_to_zig_map
+tend ${?}
+
+tbegin '"CFLAGS to Zig CPU for ARM"'
+CHOST="armv7a-unknown-linux-musleabihf"
+c_to_zig_map=(
+ [" "]="generic-soft_float"
+ ["-mcpu=native"]="native-soft_float"
+ ["-mcpu=cortex-a9"]="cortex_a9-soft_float"
+
+ ["-mcpu=cortex-a9 -march=iwmmxt2"]="cortex_a9+iwmmxt2-soft_float"
+
+ ["-march=armv7e-m"]="generic+v7em-soft_float"
+ ["-march=armv5te"]="generic+v5te-soft_float"
+ ["-march=armv6j -mfpu=vfp"]="generic+v6j+vfp2-soft_float"
+ ["-march=armv7-a -mfpu=vfpv3-d16"]="generic+v7a+vfp3d16-soft_float"
+ ["-march=armv7-a -mfpu=crypto-neon-fp-armv8"]="generic+v7a+crypto+neon+fp_armv8-soft_float"
+
+ # https://bugs.gentoo.org/924920
+ ["-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard"]=generic+v7a+vfp3d16-soft_float
+)
+test-convert_c_env_to_zig_cpu c_to_zig_map "${CHOST}"
+tend ${?}
+
+tbegin '"CFLAGS to Zig CPU for AARCH64"'
+CHOST="aarch64-unknown-linux-gnu"
+c_to_zig_map=(
+ [" "]="generic"
+ ["-mcpu=native"]="native"
+ ["-mcpu=cortex-a78"]="cortex_a78"
+
+ ["-march=armv8.3-a"]="generic+v8_3a"
+ ["-mcpu=cortex-a78 -march=armv8.3-a"]="cortex_a78+v8_3a"
+)
+test-convert_c_env_to_zig_cpu c_to_zig_map "${CHOST}"
+tend ${?}
+
+tbegin '"CFLAGS to Zig CPU for X86"'
+CHOST="i686-pc-linux-gnu"
+c_to_zig_map=(
+ [" "]="i686"
+ ["-march=native"]="native"
+
+ ["-march=i486"]="i486"
+ ["-march=i586"]="i586"
+ ["-march=i686"]="i686"
+ ["-O2 -pipe -march=pentium-m"]="pentium_m"
+)
+test-convert_c_env_to_zig_cpu c_to_zig_map "${CHOST}"
+tend ${?}
+
+tbegin '"CFLAGS to Zig CPU for X86-64"'
+CHOST="x86_64-pc-linux-gnu"
+c_to_zig_map=(
+ [" "]="x86_64"
+ ["-march=native"]="native"
+
+ ["-march=x86-64-v2"]="x86_64_v2"
+ ["-march=x86-64"]="x86_64"
+ ["-march=znver2"]="znver2"
+)
+test-convert_c_env_to_zig_cpu c_to_zig_map "${CHOST}"
+tend ${?}
+
+tbegin '"CFLAGS to Zig CPU for RISCV32"'
+CHOST="riscv32-unknown-linux-gnu"
+c_to_zig_map=(
+ [" "]="generic_rv32"
+ ["-mcpu=native"]="native"
+ ["-mcpu=sifive-e31"]="sifive_e31"
+
+ ["-mabi=ilp32d -march=rv32imafdc"]="generic_rv32+i+m+a+f+d+c+d"
+ ["-mcpu=native -mabi=ilp32 -march=rv32imac"]="native+i+m+a+c"
+)
+test-convert_c_env_to_zig_cpu c_to_zig_map "${CHOST}"
+tend ${?}
+
+tbegin '"CFLAGS to Zig CPU for RISCV64"'
+CHOST="riscv64-unknown-linux-gnu"
+c_to_zig_map=(
+ [" "]="generic_rv64"
+ ["-mcpu=native"]="native"
+ ["-mcpu=sifive-u74"]="sifive_u74"
+
+ ["-mabi=lp64 -march=rv64imac"]="generic_rv64+i+m+a+c"
+ ["-mabi=lp64d -march=rv64gc"]="generic_rv64+i+m+a+f+d+zicsr+zifencei+c+d"
+ ["-march=rv64gcv"]="generic_rv64+i+m+a+f+d+zicsr+zifencei+c+v"
+ ["-march=rv64imafdc -mcpu=sifive-u74"]="sifive_u74+i+m+a+f+d+c"
+ ["-mcpu=native -mabi=lp64 -march=rv64imac"]="native+i+m+a+c"
+)
+test-convert_c_env_to_zig_cpu c_to_zig_map "${CHOST}"
+tend ${?}
+
+tbegin '"CFLAGS to Zig CPU for LoongArch64"'
+CHOST="loongarch64-unknown-linux-gnu"
+c_to_zig_map=(
+ [" "]="generic_la64"
+ ["-march=native"]="native"
+ ["-march=la664"]="la664"
+
+ ["-march=loongarch64 -mabi=lp64d"]="loongarch64+d"
+ ["-mabi=lp64f"]="generic_la64+f"
+)
+test-convert_c_env_to_zig_cpu c_to_zig_map "${CHOST}"
+tend ${?}
+
+tbegin '"CFLAGS to Zig CPU for PowerPC"'
+CHOST="powerpc-unknown-linux-gnu"
+c_to_zig_map=(
+ [" "]="ppc"
+ ["-mcpu=native"]="native"
+
+ ["-mcpu=G5"]="g5"
+
+ # qemu: uncaught target signal 4 (Illegal instruction) - core dumped
+ ["-mcpu=power7"]="pwr7:no-run"
+ ["-mcpu=power8"]="pwr8:no-run"
+
+ ["-mcpu=powerpc"]="ppc"
+ ["-mcpu=powerpcle"]="ppc"
+)
+test-convert_c_env_to_zig_cpu c_to_zig_map "${CHOST}"
+tend ${?}
+
+tbegin '"CFLAGS to Zig CPU for PowerPC64"'
+CHOST="powerpc64-unknown-linux-gnu"
+c_to_zig_map=(
+ [" "]="ppc64"
+ ["-mcpu=native"]="native"
+
+ # qemu: uncaught target signal 4 (Illegal instruction) - core dumped
+ ["-mcpu=power10"]="pwr10:no-run"
+
+ ["-mcpu=power9"]="pwr9"
+ ["-mcpu=powerpc64"]="ppc64"
+ ["-mcpu=powerpc64le"]="ppc64le"
+)
+test-convert_c_env_to_zig_cpu c_to_zig_map "${CHOST}"
+tend ${?}
+
+texit
diff --git a/eclass/texlive-module.eclass b/eclass/texlive-module.eclass
index f8b6f0858cd6..15dcdea5df20 100644
--- a/eclass/texlive-module.eclass
+++ b/eclass/texlive-module.eclass
@@ -79,7 +79,7 @@ esac
if [[ -z ${_TEXLIVE_MODULE_ECLASS} ]]; then
_TEXLIVE_MODULE_ECLASS=1
-inherit texlive-common
+inherit eapi9-pipestatus texlive-common
HOMEPAGE="https://www.tug.org/texlive/"
@@ -537,16 +537,15 @@ texlive-module_src_install() {
grep_expressions+=(-e "/${f//./\\.}\$")
done
+ local status
+ # "success-status aware grep", returning exit status 0 instead of 1.
+ _tl_sgrep() { grep "$@"; return "$(( $? <= 1 ? 0 : $? ))"; }
ebegin "Installing man pages"
find texmf-dist/doc/man -type f -name '*.[0-9n]' -print |
- grep -v "${grep_expressions[@]}" |
+ _tl_sgrep -v "${grep_expressions[@]}" |
xargs -d '\n' --no-run-if-empty nonfatal doman
- local pipestatus="${PIPESTATUS[*]}"
- # The grep in the middle of the pipe may return 1 in case
- # everything from the input is dropped.
- # See https://bugs.gentoo.org/931994
- [[ ${pipestatus} == "0 "[01]" 0" ]]
- eend $? || die "error installing man pages (pipestatus: ${pipestatus})"
+ status=$(pipestatus -v)
+ eend $? || die "error installing man pages (PIPESTATUS: ${status})"
# Delete all man pages under texmf-dist/doc/man
find texmf-dist/doc/man -type f -name '*.[0-9n]' -delete ||
diff --git a/eclass/toolchain-funcs.eclass b/eclass/toolchain-funcs.eclass
index 2911ed66e63c..0abed5b8d75e 100644
--- a/eclass/toolchain-funcs.eclass
+++ b/eclass/toolchain-funcs.eclass
@@ -647,6 +647,50 @@ _tc-has-openmp() {
return ${ret}
}
+# @FUNCTION: tc-check-min_ver
+# @USAGE: <gcc or clang> <minimum version>
+# @DESCRIPTION:
+# Minimum version of active GCC or Clang to require.
+#
+# You should test for any necessary minimum version in pkg_pretend in order to
+# warn the user of required toolchain changes. You must still check for it at
+# build-time, e.g.
+# @CODE
+# pkg_pretend() {
+# [[ ${MERGE_TYPE} != binary ]] && tc-check-min_ver gcc 13.2.0
+# }
+#
+# pkg_setup() {
+# [[ ${MERGE_TYPE} != binary ]] && tc-check-min_ver gcc 13.2.0
+# }
+# @CODE
+tc-check-min_ver() {
+ do_check() {
+ debug-print "Compiler version check for ${1}"
+ debug-print "Detected: ${2}"
+ debug-print "Required: ${3}"
+ if ver_test ${2} -lt ${3}; then
+ eerror "Your current compiler is too old for this package!"
+ die "Active compiler is too old for this package (found ${1} ${2})."
+ fi
+ }
+
+ case ${1} in
+ gcc)
+ tc-is-gcc || return
+ do_check GCC $(gcc-version) ${2}
+ ;;
+ clang)
+ tc-is-clang || return
+ do_check Clang $(clang-version) ${2}
+ ;;
+ *)
+ eerror "Unknown first parameter for ${FUNCNAME} - must be gcc or clang"
+ die "${FUNCNAME}: Parameter ${1} unknown"
+ ;;
+ esac
+}
+
# @FUNCTION: tc-check-openmp
# @DESCRIPTION:
# Test for OpenMP support with the current compiler and error out with
diff --git a/eclass/toolchain.eclass b/eclass/toolchain.eclass
index d72047e891d1..d85994855704 100644
--- a/eclass/toolchain.eclass
+++ b/eclass/toolchain.eclass
@@ -1,4 +1,4 @@
-# Copyright 1999-2024 Gentoo Authors
+# Copyright 1999-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: toolchain.eclass
@@ -411,16 +411,29 @@ if tc_has_feature valgrind ; then
fi
if [[ ${PN} != gnat-gpl ]] && tc_has_feature ada ; then
- BDEPEND+="
- ada? (
- || (
- sys-devel/gcc:${SLOT}[ada]
- <sys-devel/gcc-${SLOT}[ada]
- <dev-lang/ada-bootstrap-${SLOT}
- dev-lang/gnat-gpl[ada]
+ if tc_use_major_version_only ; then
+ BDEPEND+="
+ ada? (
+ || (
+ sys-devel/gcc:${SLOT}[ada]
+ <sys-devel/gcc-${SLOT}[ada]
+ <dev-lang/ada-bootstrap-$((${SLOT} + 1))
+ dev-lang/gnat-gpl[ada]
+ )
)
- )
- "
+ "
+ else
+ BDEPEND+="
+ ada? (
+ || (
+ sys-devel/gcc:${SLOT}[ada]
+ <sys-devel/gcc-${SLOT}[ada]
+ <dev-lang/ada-bootstrap-${SLOT}
+ dev-lang/gnat-gpl[ada]
+ )
+ )
+ "
+ fi
fi
# TODO: Add a pkg_setup & pkg_pretend check for whether the active compiler
@@ -675,6 +688,11 @@ toolchain_src_prepare() {
eapply_user
+ # Workaround -march=native not working for stage1 with non-GCC (bug #933772).
+ if ! tc-is-gcc && [[ "${CFLAGS}${CXXFLAGS}" == *-march=native* ]] ; then
+ CLANG_DISABLE_CET_HACK=1
+ fi
+
if ! use vanilla ; then
tc_enable_hardened_gcc
fi
@@ -703,7 +721,7 @@ toolchain_src_prepare() {
gnuconfig_update
- if ! use prefix-guest && [[ -n ${EPREFIX} ]] ; then
+ if ! is_crosscompile && ! use prefix-guest && [[ -n ${EPREFIX} ]] ; then
einfo "Prefixifying dynamic linkers..."
for f in gcc/config/*/*linux*.h ; do
ebegin " Updating ${f}"
@@ -970,13 +988,22 @@ toolchain_setup_ada() {
# As a penultimate resort, try dev-lang/ada-bootstrap.
if ver_test ${ada_bootstrap} -gt ${PV} || [[ -z ${ada_bootstrap} ]] ; then
ebegin "Testing fallback dev-lang/ada-bootstrap for Ada"
- if has_version -b "<dev-lang/ada-bootstrap-${SLOT}" ; then
- # TODO: Figure out ada-bootstrap versioning/slots
+ # XXX: This can be cleaned up like BDEPEND for tc_use_major_version_only
+ # once we only support such versions.
+ if has_version -b "=dev-lang/ada-bootstrap-${SLOT}*" || has_version -b "<dev-lang/ada-bootstrap-${SLOT}" ; then
+ # Workaround the old scheme
+ if has_version -b "=dev-lang/ada-bootstrap-0_p2021*" ; then
+ ada_bootstrap=10
+ else
+ local latest_ada_bootstrap=$(best_version -b "<dev-lang/ada-bootstrap-${SLOT}")
+ latest_ada_bootstrap="${latest_ada_bootstrap#dev-lang/ada-bootstrap-}"
+ latest_ada_bootstrap=$(ver_cut 1 ${latest_ada_bootstrap})
+ ada_bootstrap="${latest_ada_bootstrap}"
+
+ export ADA_INCLUDE_PATH="${BROOT}/usr/lib/ada-bootstrap/usr/lib/gcc/${CHOST}/${ada_bootstrap}/adainclude::${ADA_INCLUDE_PATH}"
+ export ADA_OBJECTS_PATH="${BROOT}/usr/lib/ada-bootstrap/usr/lib/gcc/${CHOST}/${ada_bootstrap}/adalib:${ADA_OBJECTS_PATH}"
+ fi
- #local latest_ada_bootstrap=$(best_version -b "<dev-lang/ada-bootstrap-${SLOT}")
- #latest_ada_bootstrap="${latest_ada_bootstrap#dev-lang/ada-bootstrap-}"
- #latest_ada_bootstrap=$(ver_cut 1 ${latest_ada_bootstrap})
- ada_bootstrap="10"
ada_bootstrap_type=ada-bootstrap
ada_bootstrap_bin_dir="${BROOT}/usr/lib/ada-bootstrap/bin"
@@ -1085,19 +1112,26 @@ toolchain_setup_ada() {
# Create bin wrappers because not all of the build system respects
# GNATBIND or GNATMAKE.
- mkdir "${T}"/ada-wrappers || die
- local tool
- for tool in gnat{,bind,chop,clean,kr,link,ls,make,name,prep} ; do
- cat <<-EOF > "${T}"/ada-wrappers/${tool} || die
- #!/bin/sh
- exec "${ada_bootstrap_bin_dir}"/${CHOST}-${tool} "\$@"
- EOF
+ _toolchain_make_gnat_wrappers() {
+ mkdir "${T}"/ada-wrappers || die
+ local tool
+ for tool in gnat{,bind,chop,clean,kr,link,ls,make,name,prep} ; do
+ cat <<-EOF > "${T}"/ada-wrappers/${tool} || die
+ #!/bin/sh
+ exec "${ada_bootstrap_bin_dir}"/${CHOST}-${tool} "\$@"
+ EOF
+
+ export "${tool^^}"="${T}"/ada-wrappers/${tool}
+ done
+ chmod +x "${T}"/ada-wrappers/gnat{,bind,chop,clean,kr,link,ls,make,name,prep} || die
- export "${tool^^}"="${T}"/ada-wrappers/${tool}
- done
- chmod +x "${T}"/ada-wrappers/gnat{,bind,chop,clean,kr,link,ls,make,name,prep} || die
+ export PATH="${T}/ada-wrappers:${old_path}"
+ }
+
+ # Only make the wrappers for native builds. For cross, we can't
+ # do it as CBUILD vs CHOST will get mixed up then.
+ ! tc-is-cross-compiler && _toolchain_make_gnat_wrappers
- export PATH="${T}/ada-wrappers:${old_path}"
export CC="$(tc-getCC) -specs=${T}/ada.spec"
}
@@ -1149,11 +1183,6 @@ toolchain_src_configure() {
export ac_cv_std_swap_in_utility=no
fi
- # Workaround -march=native not working for stage1 with non-GCC (bug #933772).
- if ! tc-is-gcc && [[ "${CFLAGS}${CXXFLAGS}" == *-march=native* ]] ; then
- CLANG_DISABLE_CET_HACK=1
- fi
-
local flag
for flag in $(all-flag-vars) ; do
einfo "${flag}=\"${!flag}\""
@@ -1309,8 +1338,13 @@ toolchain_src_configure() {
confgcc+=( --enable-lto )
# Build compiler itself using LTO
- if tc_version_is_at_least 9.1 && _tc_use_if_iuse lto ; then
- BUILD_CONFIG_TARGETS+=( bootstrap-lto )
+ if _tc_use_if_iuse lto ; then
+ # GCC 11 at least has a -Wlto-type-mismatch issue with Ada
+ if ! tc_version_is_at_least 12.1 && is_ada ; then
+ :;
+ elif tc_version_is_at_least 9.1 ; then
+ BUILD_CONFIG_TARGETS+=( bootstrap-lto )
+ fi
fi
if tc_version_is_at_least 12 && _tc_use_if_iuse cet && [[ -z ${CLANG_DISABLE_CET_HACK} && ${CTARGET} == x86_64-*-gnu* ]] ; then
@@ -1635,8 +1669,9 @@ toolchain_src_configure() {
[[ ${CTARGET} == *-darwin* ]] && \
confgcc+=( --enable-version-specific-runtime-libs )
+ # Linux specifically here for bug #946397.
# TODO: amdgcn-amdhsa?
- [[ ${CTARGET} == x86_64* ]] && confgcc+=(
+ [[ ${CTARGET} == x86_64*-*-linux-* ]] && confgcc+=(
--enable-offload-defaulted
--enable-offload-targets=nvptx-none
)
@@ -1769,7 +1804,7 @@ toolchain_src_configure() {
fi
case ${CBUILD}-${CHOST}-${CTARGET} in
- *i686-w64-mingw32*|*x86_64-w64-mingw32*)
+ *-w*-mingw*)
# config/i386/t-cygming requires fixincludes (bug #925204)
GCC_RUN_FIXINCLUDES=1
;;
@@ -2606,7 +2641,7 @@ toolchain_src_install() {
# - "${D}${LIBPATH}"
# As dostrip does not specify host to override ${CHOST} tools just skip
# non-native binary stripping.
- is_crosscompile && dostrip -x "${LIBPATH}"
+ is_crosscompile && dostrip -x "${LIBPATH#"${EPREFIX}"}"
cd "${S}" || die
if is_crosscompile; then
@@ -2770,8 +2805,10 @@ gcc_movelibs() {
mv "${ED}"/usr/nvptx-none/lib/mgomp/mptx-3.1/*.{a,spec} "${ED}"/usr/lib/gcc/${CHOST}/${GCCMAJOR}/accel/nvptx-none/mgomp/mptx-3.1/
mv "${ED}"/usr/lib/gcc/nvptx-none/${GCCMAJOR}/*.{a,spec} "${ED}"/usr/lib/gcc/${CHOST}/${GCCMAJOR}/accel/nvptx-none/ || die
mv "${ED}"/usr/lib/gcc/nvptx-none/${GCCMAJOR}/mgomp/*.{a,spec} "${ED}"/usr/lib/gcc/${CHOST}/${GCCMAJOR}/accel/nvptx-none/mgomp/ || die
- mv "${ED}"/usr/lib/gcc/nvptx-none/${GCCMAJOR}/mptx-3.1/*.{a,spec} "${ED}"/usr/lib/gcc/${CHOST}/${GCCMAJOR}/accel/nvptx-none/mptx-3.1/ || die
- mv "${ED}"/usr/lib/gcc/nvptx-none/${GCCMAJOR}/mgomp/mptx-3.1/*.{a,spec} "${ED}"/usr/lib/gcc/${CHOST}/${GCCMAJOR}/accel/nvptx-none/mgomp/mptx-3.1/ || die
+ # Nonfatal because the multilib variants change: see r15-5975-g86b3a7532d56f7 and r15-6029-gd4e1f7cfdb8375
+ # TODO: Should we enable all of them unconditionally? Expose it somehow (USE_EXPAND?)?
+ mv "${ED}"/usr/lib/gcc/nvptx-none/${GCCMAJOR}/mptx-3.1/*.{a,spec} "${ED}"/usr/lib/gcc/${CHOST}/${GCCMAJOR}/accel/nvptx-none/mptx-3.1/
+ mv "${ED}"/usr/lib/gcc/nvptx-none/${GCCMAJOR}/mgomp/mptx-3.1/*.{a,spec} "${ED}"/usr/lib/gcc/${CHOST}/${GCCMAJOR}/accel/nvptx-none/mgomp/mptx-3.1/
fi
# We remove directories separately to avoid this case:
@@ -2924,6 +2961,12 @@ toolchain_pkg_postrm() {
rm -f "${EROOT}"/usr/bin/${CTARGET}-{gcc,{g,c}++}{,32,64}
fi
return 0
+ else
+ # Removed the last GCC installed (bug #906040)
+ if ! has_version "sys-devel/gcc" && has_version "sys-devel/clang" ; then
+ einfo "Last GCC version removed. Cleaning up ${EROOT}/etc/clang/gentoo-gcc-install.cfg."
+ echo > "${EROOT}"/etc/clang/gentoo-gcc-install.cfg
+ fi
fi
# gcc stopped installing .la files fixer in June 2020.
diff --git a/eclass/verify-sig.eclass b/eclass/verify-sig.eclass
index 0e6b9b43e557..12b689f0f4b2 100644
--- a/eclass/verify-sig.eclass
+++ b/eclass/verify-sig.eclass
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 Gentoo Authors
+# Copyright 2020-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: verify-sig.eclass
@@ -48,6 +48,8 @@ esac
if [[ -z ${_VERIFY_SIG_ECLASS} ]]; then
_VERIFY_SIG_ECLASS=1
+inherit eapi9-pipestatus
+
IUSE="verify-sig"
# @ECLASS_VARIABLE: VERIFY_SIG_METHOD
@@ -423,6 +425,36 @@ verify-sig_verify_signed_checksums() {
esac
}
+# @FUNCTION: verify-sig_uncompress_verify_unpack
+# @USAGE: <compressed-tar> <sig-file> [<key-file>]
+# @DESCRIPTION:
+# Uncompress the <compressed-tar> tarball, verify the uncompressed
+# archive against the signature in <sig-file> and unpack it. This is
+# useful for kernel.org packages that sign the uncompressed tarball
+# instead of the compressed archive. <key-file> can either be passed
+# directly, or it defaults to VERIFY_SIG_OPENPGP_KEY_PATH. The function
+# dies if verification or any of the unpacking steps fail.
+verify-sig_uncompress_verify_unpack() {
+ local file=${1}
+ local unpacker
+
+ # TODO: integrate with unpacker.eclass somehow?
+ case ${file} in
+ *.tar.xz)
+ unpacker=( xz -cd )
+ ;;
+ *)
+ die "${FUNCNAME}: only .tar.xz archives are supported at the moment"
+ ;;
+ esac
+
+ einfo "Unpacking ${file} ..."
+ verify-sig_verify_detached - "${@:2}" < <(
+ "${unpacker[@]}" "${file}" | tee >(tar -xf - || die)
+ pipestatus || die
+ )
+}
+
# @FUNCTION: verify-sig_src_unpack
# @DESCRIPTION:
# Default src_unpack override that verifies signatures for all
diff --git a/eclass/xorg-3.eclass b/eclass/xorg-3.eclass
index ee4038533bfd..2ca5959dd1e7 100644
--- a/eclass/xorg-3.eclass
+++ b/eclass/xorg-3.eclass
@@ -8,7 +8,7 @@
# Author: Tomáš Chvátal <scarabeus@gentoo.org>
# Author: Donnie Berkholz <dberkholz@gentoo.org>
# Author: Matt Turner <mattst88@gentoo.org>
-# @SUPPORTED_EAPIS: 7 8
+# @SUPPORTED_EAPIS: 8
# @PROVIDES: multilib-minimal
# @BLURB: Reduces code duplication in the modularized X11 ebuilds.
# @DESCRIPTION:
@@ -23,7 +23,7 @@
# everything else should be automatic.
case ${EAPI} in
- 7|8) ;;
+ 8) ;;
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
esac
@@ -111,9 +111,8 @@ HOMEPAGE="https://www.x.org/wiki/ https://gitlab.freedesktop.org/xorg/${XORG_MOD
# @ECLASS_VARIABLE: XORG_TARBALL_SUFFIX
# @PRE_INHERIT
# @DESCRIPTION:
-# Most X11 projects provide tarballs as tar.bz2 or tar.xz. This eclass defaults
-# to bz2.
-: "${XORG_TARBALL_SUFFIX:="bz2"}"
+# Most X11 projects provide tarballs as tar.xz. This eclass defaults to xz.
+: "${XORG_TARBALL_SUFFIX:="xz"}"
if [[ ${PV} == *9999* ]]; then
: "${EGIT_REPO_URI:="https://gitlab.freedesktop.org/xorg/${XORG_MODULE}${XORG_PACKAGE_NAME}.git"}"
diff --git a/eclass/zig-utils.eclass b/eclass/zig-utils.eclass
new file mode 100644
index 000000000000..5502d997935e
--- /dev/null
+++ b/eclass/zig-utils.eclass
@@ -0,0 +1,559 @@
+# Copyright 2024-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: zig-utils.eclass
+# @MAINTAINER:
+# Eric Joldasov <bratishkaerik@landless-city.net>
+# @AUTHOR:
+# Eric Joldasov <bratishkaerik@landless-city.net>
+# @SUPPORTED_EAPIS: 8
+# @BLURB: Prepare Zig toolchain and set global variables
+# @DESCRIPTION:
+# Prepare Zig toolchain and set global variables.
+# Supports Zig 0.13+.
+# Does not set any default function, ebuilds must call them manually.
+# Generally, only "zig-utils_setup" is needed.
+#
+# Intended to be used by ebuilds that call "zig build-exe/lib/obj"
+# or "zig test" directly and by "dev-lang/zig".
+# For ebuilds with ZBS (Zig Build System), it's usually better
+# to inherit zig.eclass instead, as it has default phases-functions.
+
+if [[ -z ${_ZIG_UTILS_ECLASS} ]]; then
+_ZIG_UTILS_ECLASS=1
+
+case ${EAPI} in
+ 8) ;;
+ *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+inherit edo flag-o-matic linux-info
+
+# @ECLASS_VARIABLE: ZIG_SLOT
+# @PRE_INHERIT
+# @REQUIRED
+# @DESCRIPTION:
+# Zig slot that will be used in "ezig" function. Also, if
+# ZIG_OPTIONAL is empty, adds dev-lang/zig and dev-lang/zig-bin
+# dependency to BDEPEND. Must be >= "0.13".
+#
+# Example:
+# @CODE
+# ZIG_SLOT="0.13"
+# @CODE
+#
+# When a new Zig release occurs, it is advisable for maintainers to
+# check whether their ebuild supports that new version. If yes, they
+# they should bump ZIG_SLOT to the latest version; if not supported,
+# they need to patch any issues with new version and again bump
+# ZIG_SLOT. This helps to reduce dependencies on outdated Zig
+# versions.
+#
+# This policy of "1 exclusive Zig slot" will work until it
+# stabilizes enough (probably near 1.0), then it will be re-evaluated
+# and most likely changed to more common in other eclasses ZIG_MIN/
+# ZIG_MAX form.
+
+# @ECLASS_VARIABLE: ZIG_NEEDS_LLVM
+# @PRE_INHERIT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If set to a non-empty value, the package will BDEPEND on a Zig package
+# with LLVM enabled. This is currently required for packages that require
+# C/C++ source files to be compiled with Zig.
+
+# @ECLASS_VARIABLE: ZIG_OPTIONAL
+# @PRE_INHERIT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If set to a non-empty value, all logic in zig-utils and
+# zig eclasses will be considered optional. No dependencies
+# will be added and no phase functions will be exported.
+#
+# For zig-utils.eclass users:
+# You have to add Zig dependency in your BDEPEND manually and call
+# at least "zig-utils_setup" before using "ezig".
+#
+# For zig.eclass users: see documentation in zig.eclass
+# instead.
+if [[ ! ${ZIG_OPTIONAL} ]]; then
+ _ZIG_USEDEP=""
+ if [[ ${ZIG_NEEDS_LLVM} ]]; then
+ _ZIG_USEDEP="[llvm(+)]"
+ fi
+
+ # NOTE: zig-bin is always built with LLVM support, so no USE needed.
+ BDEPEND="
+ || (
+ dev-lang/zig:${ZIG_SLOT}${_ZIG_USEDEP}
+ dev-lang/zig-bin:${ZIG_SLOT}
+ )
+ "
+fi
+
+# @ECLASS_VARIABLE: ZIG_TARGET
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Zig target tuple to use. Has the following format:
+# arch-os[.os_version_range]-abi[.abi_version]
+# Can be passed as:
+# * "-target " option in "zig test" or "zig build-exe/lib/obj",
+# * "-Dtarget=" option in "zig build"
+# (if project uses "std.Build.standardTargetOptions").
+#
+# Can be set by user in make.conf. If not set, then auto-generated by
+# "zig-utils_setup".
+#
+# Example:
+# @CODE
+# # Autodetected by Zig:
+# ZIG_TARGET="native"
+# # Machine running Linux x86_64 system, with glibc:
+# ZIG_TARGET="x86_64-linux-gnu"
+# # Similar to above, but versions are passed explicitly:
+# ZIG_TARGET="x86_64-linux.6.1.12...6.6.16-gnu.2.38"
+# # Machine running Linux PPC64 little-endian system, with musl
+# ZIG_TARGET="powerpc64le-linux-musl"
+# @CODE
+#
+# Note for eclass users: it is discouraged to overwrite ZIG_TARGET
+# value by ebuilds. In most cases, if you need to hardcode value for
+# -Dtarget, it's better to change "build.zig" code instead to use
+# appropriate values. For example, if some build-time executable
+# intented for host is compiled for cross-platform target, change in
+# build.zig "target" for that executable to be "b.graph.host".
+#
+# In rare cases, if you really need to hardcode ZIG_TARGET, use this
+# syntax before calling `zig-utils_setup` (or `zig_pkg_setup`) to
+# allow user override:
+# @CODE
+# pkg_setup() {
+# : "${ZIG_TARGET:=aarch64-freestanding-none}"
+# zig_pkg_setup
+# }
+# @CODE
+
+# @ECLASS_VARIABLE: ZIG_CPU
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Zig target CPU and features to use. Has the following format:
+# family_name(\+enable_feature|\-disable_feature)*
+# Can be passed as:
+# * "-mcpu " option in "zig test" or "zig build-exe/lib/obj",
+# * "-Dcpu=" option in "zig build"
+# (if project uses "std.Build.standardTargetOptions").
+#
+# Can be set by user in make.conf. If not set, then auto-generated by
+# "zig-utils_setup".
+#
+# Example:
+# @CODE
+# # Autodetected by Zig:
+# ZIG_CPU="native"
+# # AMD Zen 2 processor
+# ZIG_CPU="znver2"
+# # x86_64 processor, X87 support enabled, SSE2 support disabled
+# ZIG_CPU="x86_64+x87-sse2"
+# @CODE
+#
+# Note for eclass users: it is discouraged to overwrite ZIG_CPU
+# value by ebuilds. In most cases, if you need to hardcode value for
+# -Dcpu, it's better to change "build.zig" code instead to use
+# appropriate values. For example, if some build-time executable
+# intented for host is compiled for cross-platform target, change in
+# build.zig "target" for that executable to be "b.graph.host".
+#
+# In rare cases, if you really need to hardcode ZIG_CPU, use this
+# syntax before calling `zig-utils_setup` (or `zig_pkg_setup`) to
+# allow user override:
+# @CODE
+# pkg_setup() {
+# : "${ZIG_CPU:=apple_m1}"
+# zig_pkg_setup
+# }
+# @CODE
+
+# @ECLASS_VARIABLE: ZIG_EXE
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# Absolute path to the used Zig executable.
+# Set by "zig-utils_setup"/"zig-utils_find_installation".
+#
+# Please note that when passing one flag several times with different
+# values:
+# * (only "zig build") in "-Dbar=false -Dbar" form:
+# errors due to conflict of flags,
+# * (only "zig build") in "-Dbar=false -Dbar=true" form:
+# "bar" becomes a list, which is likely not what you want,
+# * in "-fbar -fno-bar" form:
+# latest value overwrites values before.
+# Example above shows only boolean option, but it is same with other
+# types of options (enums, "std.zig.BuildId", "std.SemanticVersion",
+# integers, strings, etc.).
+
+# @ECLASS_VARIABLE: ZIG_VER
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# Zig version as reported in dev-lang/zig-${PV} PV part.
+# Set by "zig-utils_setup"/"zig-utils_find_installation".
+#
+# Example:
+# @CODE
+# 0.13.0
+# @CODE
+
+# @FUNCTION: zig-utils_c_env_to_zig_target
+# @USAGE: <C-style target tuple> <CFLAGS>
+# @DESCRIPTION:
+# Translates C-style target tuple (like CHOST) and CFLAGS to Zig-style
+# target tuple. For full information "zig-utils_c_env_to_zig_cpu" is
+# needed, because some information is located in different places in C
+# and Zig, for example:
+# * Moved from C target to Zig CPU: x86 and ARM families,
+# * Moved from CFLAGS to Zig tuple: ARM Thumb mode.
+#
+# Mostly used during cross-compilation to get target triple if user
+# did not set ZIG_TARGET variable, and always during bootstraping Zig.
+#
+# See ZIG_TARGET description for more information.
+zig-utils_c_env_to_zig_target() {
+ if [[ ${#} -ne 2 ]]; then
+ die "${FUNCNAME[0]}: expected 2 arguments, got ${#}"
+ fi
+ local c_tuple="${1}"
+ local c_arch="${c_tuple%%-*}"
+ local c_abi="${c_tuple##*-}"
+
+ local c_flags="${2}"
+ local c_flags_march="$(CFLAGS="${c_flags}" get-flag march)"
+
+ local arch os abi
+
+ case "${c_arch}" in
+ i?86) arch=x86;;
+ arm64) arch=aarch64;;
+ arm*)
+ if [[ "${c_flags_march}" == *-m ]]; then
+ arch=thumb
+ else
+ arch=arm
+ fi
+
+ if [[ "${c_arch}" == *eb ]]; then
+ arch+="eb"
+ fi
+ ;;
+ *) arch="${c_arch}";;
+ esac
+
+ case "${c_tuple}" in
+ *-linux*) os=linux;;
+ *-apple*) os=macos;;
+ esac
+
+ case "${c_abi}" in
+ darwin*) abi=none;;
+ *) abi="${c_abi}";;
+ esac
+
+ echo "${arch}-${os}-${abi}"
+}
+
+# @FUNCTION: zig-utils_c_env_to_zig_cpu
+# @USAGE: <C-style target tuple> <CFLAGS>
+# @DESCRIPTION:
+# Translates C-style target tuple (like CHOST) and CFLAGS to Zig-style
+# target CPU and features. For full information
+# "zig-utils_c_env_to_zig_target" is needed, because some information
+# is located in different places in C and Zig, for example:
+# * Moved from C target to Zig CPU: x86 and ARM families,
+# * Moved from CFLAGS to Zig tuple: ARM Thumb mode.
+#
+# Used to get target CPU if user did not set ZIG_CPU variable.
+#
+# See ZIG_CPU description for more information.
+zig-utils_c_env_to_zig_cpu() {
+ if [[ ${#} -ne 2 ]]; then
+ die "${FUNCNAME[0]}: expected 2 arguments, got ${#}"
+ fi
+ local c_tuple="${1}"
+ local c_arch="${c_tuple%%-*}"
+
+ local c_flags="${2}"
+ local c_flags_mabi="$(CFLAGS="${c_flags}" get-flag mabi)"
+ local c_flags_march="$(CFLAGS="${c_flags}" get-flag march)"
+ local c_flags_mcpu="$(CFLAGS="${c_flags}" get-flag mcpu)"
+ local c_flags_mfpu="$(CFLAGS="${c_flags}" get-flag mfpu)"
+
+ local base_cpu features=""
+
+ case "${c_arch}" in
+ x86_64 | i?86)
+ local c_cpu="${c_flags_march}"
+ case "${c_cpu}" in
+ "") base_cpu="${c_arch}";;
+ *) base_cpu="${c_cpu//[-.]/_}";;
+ esac
+ ;;
+ aarch64 | aarch64_be | arm*)
+ local c_cpu="${c_flags_mcpu}"
+ case "${c_cpu}" in
+ "") base_cpu=generic;;
+ *) base_cpu="${c_cpu//[-.]/_}";;
+ esac
+
+ case "${c_flags_march}" in
+ "") ;;
+ armv*)
+ local c_arm_family="${c_flags_march##arm}"
+ c_arm_family="${c_arm_family//./_}"
+ c_arm_family="${c_arm_family//-/}"
+ features+="+${c_arm_family}"
+ ;;
+ *) features+="+${c_flags_march}";;
+ esac
+
+ if [[ "${c_arch}" != aarch64* && "${c_arch}" != arm64 ]]; then
+ if [[ "${c_flags_mfpu}" == crypto-* ]]; then
+ c_flags_mfpu="${c_flags_mfpu##crypto-}"
+ features+="+crypto"
+ fi
+ if [[ "${c_flags_mfpu}" == neon-* ]]; then
+ c_flags_mfpu="${c_flags_mfpu##neon-}"
+ features+="+neon"
+ fi
+
+ case "${c_flags_mfpu}" in
+ "" | auto) ;;
+ neon) features+="+neon";;
+ fp16) features+="+fp16";;
+ fp-armv8) features+="+fp_armv8";;
+
+ vfp | vfpv2) features+="+vfp2";;
+
+ vfp3 | vfpv3) features+="+vfp3";;
+ vfpv3-fp16) features+="+vfp3sp";;
+ vfpv3-d16) features+="+vfp3d16";;
+ vfpv3-d16-fp16) features+="+vfp3d16sp";;
+ vfpv3xd) features+="+vfp3d16sp";;
+ vfpv3xd-fp16) features+="+vfp3d16sp+fp16";;
+
+ vfpv4) features+="+vfp4";;
+ vfpv4-fp16) features+="+vfp4sp";;
+ vfpv4-d16) features+="+vfp4d16";;
+ fpv4-sp-fp16) features+="+vfp4d16sp";;
+
+ fpv5-d16) features+="+fp_armv8d16+fp64";;
+ *) die -n "Unknown ARM FPU: ${c_flags_mfpu}";;
+ esac
+
+ local is_softfloat="$(CTARGET="${c_tuple}" tc-tuple-is-softfloat)"
+ case "${is_softfloat}" in
+ only | yes) features+="+soft_float";;
+ softfp | no) features+="-soft_float";;
+ *) die -n "tc-tuple-is-softfloat returned unexpected value: ${is_softfloat}"
+ esac
+ fi
+ ;;
+ riscv32 | riscv64)
+ local c_cpu="${c_flags_mcpu}"
+ case "${c_cpu}" in
+ "")
+ case "${c_arch}" in
+ riscv32) base_cpu=generic_rv32;;
+ riscv64) base_cpu=generic_rv64;;
+ esac
+ ;;
+ *) base_cpu="${c_cpu//[-.]/_}";;
+ esac
+
+ local base_isa="${c_flags_march:0:4}"
+ local extensions="${c_flags_march:4}"
+
+ case "${base_isa}" in
+ "" | rv32 | rv64) ;;
+ *) die -n "Unknown RISC-V architecture: ${base_isa}";;
+ esac
+
+ local extension
+ while read -n 1 extension; do
+ case "${extension}" in
+ "") ;;
+ g) features+="+i+m+a+f+d+zicsr+zifencei";;
+ _) die -n "Can't translate multi-letter RISC-V extensions yet";;
+ *) features+="+${extension}";;
+ esac
+ done <<< "${extensions}"
+
+ case "${c_flags_mabi}" in
+ ilp32d | lp64d) features+="+d";;
+ ilp32e | lp64e) features+="+e";;
+ ilp32f | lp64f) features+="+f";;
+ "" | ilp32 | lp64) ;;
+ *) die -n "Unknown RISC-V ABI: ${c_flags_mabi}";;
+ esac
+ ;;
+ loongarch64)
+ local c_cpu="${c_flags_march}"
+ case "${c_cpu}" in
+ "") base_cpu=generic_la64;;
+ *) base_cpu="${c_cpu//[-.]/_}";;
+ esac
+
+ case "${c_flags_mabi}" in
+ lp64d) features+="+d";;
+ lp64f) features+="+f";;
+ lp64s | "") ;;
+ *) die -n "Unknown LoongArch ABI: ${c_flags_mabi}";;
+ esac
+ ;;
+ powerpc | powerpcle | powerpc64 | powerpc64le)
+ local c_cpu="${c_flags_mcpu}"
+ case "${c_cpu}" in
+ "")
+ case "${c_arch}" in
+ powerpc | powerpcle) base_cpu=ppc;;
+ powerpc64 | powerpc64le) base_cpu=ppc64;;
+ esac
+ ;;
+ G*) base_cpu="${c_cpu//G/g}";;
+ powerpcle) base_cpu=ppc;;
+ powerpc*) base_cpu="${c_cpu//powerpc/ppc}";;
+ power*) base_cpu="${c_cpu//power/pwr}";;
+ *) base_cpu="${c_cpu//[-.]/_}";;
+ esac
+ ;;
+ *) base_cpu=generic;;
+ esac
+
+ echo "${base_cpu}${features}"
+}
+
+# @FUNCTION: zig-utils_find_installation
+# @DESCRIPTION:
+# Detects suitable Zig installation and sets ZIG_VER and ZIG_EXE
+# variables.
+#
+# See ZIG_EXE and ZIG_VER descriptions for more information.
+zig-utils_find_installation() {
+ # Adapted from https://github.com/gentoo/gentoo/pull/28986
+ # Many thanks to Florian Schmaus (Flowdalic)!
+
+ [[ -n "${ZIG_SLOT}" ]] || die "${FUNCNAME[0]}: ZIG_SLOT must be set"
+ if ver_test "${ZIG_SLOT}" -lt "0.13"; then
+ die "${ECLASS}: ZIG_SLOT must be >= 0.13, found ${ZIG_SLOT}"
+ fi
+
+ einfo "Searching Zig ${ZIG_SLOT}..."
+
+ local zig_supported_versions=(
+ "9999"
+ "0.13.1"
+ "0.13.0"
+ )
+
+ local base_path="${BROOT}/usr/bin"
+
+ local -x ZIG_GLOBAL_CACHE_DIR="${T}/zig-detect"
+ mkdir -p "${ZIG_GLOBAL_CACHE_DIR}" || die
+ touch "${ZIG_GLOBAL_CACHE_DIR}/empty.zig" || die
+
+ local selected_path selected_ver
+ for selected_ver in "${zig_supported_versions[@]}"; do
+ # Check if candidate satisfies ZIG_SLOT condition.
+ if [[ "${selected_ver}" != "${ZIG_SLOT}"* ]]; then
+ continue
+ fi
+
+ # Prefer "dev-lang/zig" over "dev-lang/zig-bin"
+ local candidate_path
+ for candidate_path in "${base_path}"/zig{,-bin}-"${selected_ver}"; do
+ if [[ -x "${candidate_path}" ]]; then
+ if [[ ${ZIG_NEEDS_LLVM} ]]; then
+ "${candidate_path}" test -fllvm -OReleaseSmall "${ZIG_GLOBAL_CACHE_DIR}/empty.zig" &> /dev/null || continue
+ fi
+ selected_path="${candidate_path}"
+ break 2
+ fi
+ done
+ done
+
+ if [[ -z "${selected_path}" ]]; then
+ die "Could not find (suitable) Zig at \"${base_path}\""
+ fi
+
+ declare -g ZIG_EXE="${selected_path}"
+ declare -g ZIG_VER="${selected_ver}"
+ # Sanity check, comment from upstream:
+ # > Check libc++ linkage to make sure Zig was built correctly,
+ # > but only for "env" and "version" to avoid affecting the
+ # > startup time for build-critical commands
+ # > (check takes about ~10 μs)
+ "${ZIG_EXE}" version > /dev/null ||
+ die "Sanity check failed for \"${ZIG_EXE}\""
+}
+
+# @FUNCTION: zig-utils_setup
+# @DESCRIPTION:
+# Checks if running Linux kernel version is supported by Zig.
+# Populates ZIG_TARGET, ZIG_CPU, ZIG_EXE and ZIG_VER global
+# variables with detected values, or, if user set them already,
+# leaves as-is.
+zig-utils_setup() {
+ # Should be first because it sets ZIG_VER which might be used
+ # in the future when setting ZIG_TARGET and ZIG_CPU variables
+ # for incompatible versions.
+ if [[ -z "${ZIG_EXE}" ]]; then
+ zig-utils_find_installation
+ fi
+
+ : "${ZIG_CPU:=$(zig-utils_c_env_to_zig_cpu "${CHOST}" "${CFLAGS}")}"
+ if tc-is-cross-compiler; then
+ : "${ZIG_TARGET:=$(zig-utils_c_env_to_zig_target "${CHOST}" "${CFLAGS}")}"
+ else
+ : "${ZIG_TARGET:=native}"
+ fi
+ declare -g ZIG_CPU ZIG_TARGET
+
+ einfo "ZIG_EXE: \"${ZIG_EXE}\""
+ einfo "ZIG_VER: ${ZIG_VER}"
+ einfo "ZIG_TARGET: ${ZIG_TARGET}"
+ einfo "ZIG_CPU: ${ZIG_CPU}"
+}
+
+# @FUNCTION: ezig
+# @USAGE: [<args>...]
+# @DESCRIPTION:
+# Runs ZIG_EXE with supplied arguments. Dies if ZIG_EXE is not set or
+# if command exits with error. Respects `nonfatal`.
+#
+# Always disables progress tree. By default enables ANSI escape codes
+# (colors, etc.), user can set NO_COLOR environment variable to
+# disable them.
+#
+# Note that color support also determines how compile errors will be
+# printed: source code lines and reference traces are not available
+# when colors are disabled.
+ezig() {
+ # Sync description above and comments below with upstream's
+ # "std.io.tty.detectConfig".
+ debug-print-function "${FUNCNAME[0]}" "${@}"
+
+ if [[ -z "${ZIG_EXE}" ]] ; then
+ die "${FUNCNAME[0]}: ZIG_EXE is not set. Was 'zig-utils_setup' called before using ezig?"
+ fi
+
+ # Progress tree is helpful indicator in TTY, but unfortunately
+ # they make Portage logs harder to read in plaintext.
+ #
+ # We don't have global toggle for all Zig commands to disable
+ # progress tree, however we can emulate this using 2 steps.
+
+ # Disable progress tree and colors. Errors are now less detailed.
+ local -x TERM=dumb
+ # Re-enable colors. Errors are now yet again detailed for reading.
+ local -x CLICOLOR_FORCE=1
+ # User's NO_COLOR has more priority and can disable colors again.
+ "${ZIG_EXE}" "${@}" || die -n "Failed to run command: ${ZIG_EXE} ${@}"
+}
+fi
diff --git a/eclass/zig.eclass b/eclass/zig.eclass
new file mode 100644
index 000000000000..2a0178e66d71
--- /dev/null
+++ b/eclass/zig.eclass
@@ -0,0 +1,559 @@
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: zig.eclass
+# @MAINTAINER:
+# Eric Joldasov <bratishkaerik@landless-city.net>
+# @AUTHOR:
+# Alfred Wingate <parona@protonmail.com>
+# Violet Purcell <vimproved@inventati.org>
+# Eric Joldasov <bratishkaerik@landless-city.net>
+# @SUPPORTED_EAPIS: 8
+# @PROVIDES: zig-utils
+# @BLURB: Functions for working with ZBS (Zig Build System)
+# @DESCRIPTION:
+# Functions for working with Zig build system and package manager.
+# Supports Zig 0.13+. Exports default functions for convenience.
+#
+# Note that zig.eclass is mostly tailored for projects that:
+# 1) Install something in build.zig steps: "artifacts" (executable,
+# libraries, objects), source codes, assets, tests, scripts etc. But
+# many authors also use it to write Zig "modules", build logic
+# and/or bindings/wrappers for C/C++ libraries. They install nothing
+# and are only used at build-time, so it's unneccessary and mostly
+# useless to make ebuilds for them.
+# 2) Have required `target`, `cpu` and optional `optimize` options in
+# build.zig that accept standard Zig-style target and optimize mode.
+# They are usually created by calling `b.standardTargetOptions` and
+# `b.standardOptimizeOption` functions.
+#
+# For end-user executables, usually it's recommended to patch to call
+# these options and upstream it, but in some cases authors have good
+# reasons to not have them, f.e. if it is built only for WASM
+# platform with ReleaseSmall, and is not intended to run in /usr/bin/.
+# In this case, declare dummy options using `b.option` and ignore
+# their values, or else eclass wouldn't work.
+#
+# Another case is when upstream has `target` option but it has
+# custom format and does not accept usual Zig targets, but rather
+# something specific to the project like "linux-baseline-lts", or
+# combine CPU and target in one option.
+# In this case, it's best to rename that option to something like
+# `target-custom`, then declare `target` option and make converter
+# from one value to other.
+#
+# For non-executable binaries like C libraries, objects etc. our
+# policy is stricter, all 3 options are required and should not
+# be ignored, with no exceptions.
+
+if [[ -z ${_ZIG_ECLASS} ]]; then
+_ZIG_ECLASS=1
+
+case ${EAPI} in
+ 8) ;;
+ *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+inherit multiprocessing zig-utils
+
+# @ECLASS_VARIABLE: ZIG_OPTIONAL
+# @PRE_INHERIT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If set to a non-empty value, all logic in zig-utils and
+# zig eclasses will be considered optional. No dependencies
+# will be added and no phase functions will be exported.
+#
+# For zig.eclass users:
+# You need to add Zig and pkgconfig dependencies in your BDEPEND, set
+# QA_FLAGS_IGNORED and call all phase functions manually. If you want
+# to use "ezig build" directly, call "zig_pkg_setup" before it.
+#
+# For zig-utils.eclass users: see documentation in
+# zig-utils.eclass instead.
+if [[ ! ${ZIG_OPTIONAL} ]]; then
+ BDEPEND="virtual/pkgconfig"
+
+ # See https://github.com/ziglang/zig/issues/3382
+ # Zig Build System does not support CFLAGS/LDFLAGS/etc.
+ QA_FLAGS_IGNORED=".*"
+fi
+
+# @ECLASS_VARIABLE: ZBS_DEPENDENCIES
+# @PRE_INHERIT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Bash associative array with all tarballs that will be fetched by
+# "ezig fetch" in zig_src_unpack phase. Value is URL where
+# tarball is located, key is name under which it would be downloaded
+# and renamed. So generally it has effect of "value -> key".
+#
+# Note: if Zig Build System dependency can't be represented in SRC_URI
+# (like direct Git commit URIs), you should do the following
+# (zig-ebuilder does archiving automatically for you):
+# 1. Archive each folder with dependency content in some tarball,
+# so f.e. if you have 2 Git dependencies, create 2 tarballs.
+# 2. Archive all previous tarballs into one combined tarball (also
+# called tarball-tarball from now on), no subdirs, so that eclass
+# can firstly unpack this tarball with "unpack",
+# and secondly unpack its content with "zig fetch".
+# 3. (zig-ebuilder can't do this) Host this tarball somewhere
+# and put URL of this tarball in SRC_URI, and archives in
+# ZBS_DEPENDENCIES, keys must be names of archives, values empty.
+#
+# Example:
+# @CODE
+# declare -r -A ZBS_DEPENDENCIES=(
+# [tarball_a-<long-hash>.tar.gz]='URL_A'
+# [tarball_b-<long-hash>.tar.gz]='URL_B'
+#
+# # If there are Git dependencies:
+# [git_c-<long-hash>.tar.gz]=''
+# # Tarball-tarball should contain inside above tarball flatly.
+# )
+# @CODE
+
+# @ECLASS_VARIABLE: ZBS_DEPENDENCIES_SRC_URI
+# @OUTPUT_VARIABLE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Content of ZBS_DEPENDENCIES converted at inherit-time, to be used in
+# SRC_URI. Note that elements with empty keys will be skipped.
+# Example:
+# @CODE
+# SRC_URI="
+# <URL to project sources, patches, non-Zig resources etc.>
+#
+# # If there are Git dependencies:
+# # <URL to tarball-tarball>
+#
+# ${ZBS_DEPENDENCIES_SRC_URI}
+# "
+# @CODE
+
+# @FUNCTION: _zig_set_zbs_uris
+# @INTERNAL
+# @DESCRIPTION:
+# Sets ZBS_DEPENDENCIES_SRC_URI variable based on ZBS_DEPENDENCIES.
+_zig_set_zbs_uris() {
+ # Thanks to Alfred Wingate "parona" for inspiration here:
+ # https://gitlab.com/Parona/parona-overlay/-/blob/874dcfe03116574a33ed51f469cc993e98db1fa2/eclass/zig.eclass
+
+ ZBS_DEPENDENCIES_SRC_URI=
+
+ local dependency
+ for dependency in "${!ZBS_DEPENDENCIES[@]}"; do
+ local uri="${ZBS_DEPENDENCIES[${dependency}]}"
+ if [[ -n "${uri}" ]]; then
+ ZBS_DEPENDENCIES_SRC_URI+=" ${uri} -> ${dependency}"
+ fi
+ done
+}
+_zig_set_zbs_uris
+
+# @ECLASS_VARIABLE: my_zbs_args
+# @DESCRIPTION:
+# Bash array with ebuild-specified arguments to pass to the
+# "zig build" after "src_configure".
+# It's appended to the ZBS_ARGS during "src_configure". Note: if you
+# need to override default optimize mode of this eclass (ReleaseSafe)
+# with your default, please use "--release=small" etc. syntax so that
+# user can still override it in ZBS_ARGS_EXTRA.
+#
+# Example:
+# @CODE
+# src_configure() {
+# local my_zbs_args=(
+# -Dpie=true
+# )
+#
+# zig_src_configure
+# }
+# @CODE
+: "${my_zbs_args:=}"
+
+# @ECLASS_VARIABLE: ZBS_ARGS_EXTRA
+# @USER_VARIABLE
+# @DESCRIPTION:
+# Bash string with user-specified arguments to pass to the "zig build"
+# after "src_configure".
+# It's appended to the ZBS_ARGS during "zig_src_configure".
+#
+# If this does not have amount of jobs, eclass will try to take amount
+# of jobs from MAKEOPTS, and if it also does not have them, it will
+# default to $(nproc).
+#
+# Example:
+# @CODE
+# ZBS_ARGS_EXTRA="-j8 --release=small"
+# @CODE
+: "${ZBS_ARGS_EXTRA:=}"
+
+# @ECLASS_VARIABLE: ZBS_VERBOSE
+# @USER_VARIABLE
+# @DESCRIPTION:
+# If enabled, eclass will add "--summary all --verbose" options to
+# "ezig build", so that it prints every command before executing,
+# and summarry tree at the end of step. If not, will do nothing.
+# Enabled by default. Set to OFF to disable these verbose messages.
+#
+# Note: this variable does not control other options starting with
+# "--verbose-", such as "--verbose-link" or "--verbose-cimport". If
+# you need them, add them manually to ZBS_ARGS_EXTRA.
+: "${ZBS_VERBOSE:=ON}"
+
+# @ECLASS_VARIABLE: BUILD_DIR
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Directory where all "ezig build" calls will be proceeded.
+# Defaults to "${WORKDIR}/${P}-build" if not set.
+: "${BUILD_DIR:=${WORKDIR}/${P}-build}"
+
+# @ECLASS_VARIABLE: ZBS_ECLASS_DIR
+# @DESCRIPTION:
+# Directory where various files used by this eclass are stored.
+# They can be supplied by the ebuild or by eclass.
+# Currently, it's used only for Zig packages, which are stored in "p/"
+# subdirectory.
+# Defaults to "${WORKDIR}/zig-eclass" if not set.
+# Should be set before calling "zig_src_unpack" or
+# "zig_live_fetch".
+: "${ZBS_ECLASS_DIR:=${WORKDIR}/zig-eclass}"
+
+# @FUNCTION: zig_get_jobs
+# @DESCRIPTION:
+# Returns number of jobs from ZBS_ARGS_EXTRA or MAKEOPTS.
+# If there is none, defaults to number of available processing units.
+zig_get_jobs() {
+ local all_args="${MAKEOPTS} ${ZBS_ARGS_EXTRA}"
+ local default_jobs="$(get_nproc)"
+ local jobs="$(makeopts_jobs "${all_args}" "${default_jobs}")"
+
+ if [[ "${jobs}" == "0" ]]; then
+ # Zig build system does not allow "-j0", and does not have
+ # option for unlimited parallelism. Pass our default number
+ # of jobs here.
+ echo "${default_jobs}"
+ else
+ echo "${jobs}"
+ fi
+}
+
+# @FUNCTION: zig_init_base_args
+# @DESCRIPTION:
+# Stores basic args for future "ezig build" calls in ZBS_ARGS_BASE.
+# Package manager option is managed by "zig_src_prepare",
+# ebuild and user options are added by "zig_src_configure".
+#
+# This function is used by "zig_pkg_setup", and it is neccessary
+# that args are available as early as possible, so that ebuilds
+# could use them in steps like "src_unpack" if neccessary, while
+# still having verbosity and amount of jobs from user respected.
+#
+#
+# TODO: currently this function enables "--search-prefix" (1) and
+# "--sysroot" (2) only when cross-compiling, should be fixed to
+# unconditionally enabling it.
+#
+# For solving (1) this patch should be reworked and upstreamed:
+# https://paste.sr.ht/~bratishkaerik/2ddffe2bf0f8f9d6dfb60403c2e9560334edaa88
+#
+# (2)
+# "--sysroot" should be passed together with "--search-prefix" above,
+# if we pass only "--sysroot" it gives these errors:
+# @CODE
+# error: unable to find dynamic system library 'zstd' using strategy 'paths_first'. searched paths: none
+# @CODE
+zig_init_base_args() {
+ [[ "${ZBS_ARGS_BASE}" ]] && return
+
+ # Sync with the output format of `zig libc`.
+ # TODO maybe add to upstream to use ZON format instead...
+ # Will also help "https://github.com/ziglang/zig/issues/20327",
+ # and hopefully will respect our settings too.
+ cat <<- _EOF_ > "${T}/zig_libc.txt" || die "Failed to provide Zig libc info"
+ # Note: they are not prepended by "--sysroot" value,
+ # so repeat it here.
+ # Also, no quotes here, they are interpreted verbatim.
+ include_dir=${ESYSROOT}/usr/include/
+ sys_include_dir=${ESYSROOT}/usr/include/
+ crt_dir=${ESYSROOT}/usr/$(get_libdir)/
+ # Windows with MSVC only.
+ msvc_lib_dir=
+ # Windows with MSVC only.
+ kernel32_lib_dir=
+ # Haiku only.
+ gcc_dir=
+ _EOF_
+
+ declare -g -a ZBS_ARGS_BASE=(
+ -j$(zig_get_jobs)
+
+ -Dtarget="${ZIG_TARGET}"
+ -Dcpu="${ZIG_CPU}"
+ --release=safe
+
+ --prefix-exe-dir bin/
+ --prefix-lib-dir "$(get_libdir)/"
+ --prefix-include-dir include/
+
+ # Should be relative path to make other calls easier,
+ # so remove leading slash here.
+ --prefix "${EPREFIX:+${EPREFIX#/}/}usr/"
+
+ --libc "${T}/zig_libc.txt"
+ )
+ if [[ "${ZBS_VERBOSE}" != OFF ]]; then
+ ZBS_ARGS_BASE+=( --summary all --verbose )
+ fi
+
+ if tc-is-cross-compiler; then
+ ZBS_ARGS_BASE+=(
+ --search-prefix "${ESYSROOT}/usr/"
+ --sysroot "${ESYSROOT}/"
+ )
+ fi
+}
+
+# @FUNCTION: zig_pkg_setup
+# @DESCRIPTION:
+# Sets up environmental variables for Zig toolchain
+# and basic args for Zig Build System.
+zig_pkg_setup() {
+ [[ "${MERGE_TYPE}" != binary ]] || return 0
+
+ zig-utils_setup
+ zig_init_base_args
+
+ mkdir "${T}/zig-cache/" || die
+
+ # Environment variables set by this eclass.
+
+ # Used by Zig Build System to find `pkg-config`.
+ # UPSTREAM Used only by 9999 for now, should land in future
+ # 0.14 release.
+ export PKG_CONFIG="${PKG_CONFIG:-"$(tc-getPKG_CONFIG)"}"
+ # Used by whole Zig toolchain (most of the sub-commands)
+ # to find local and global cache directories.
+ export ZIG_LOCAL_CACHE_DIR="${T}/zig-cache/local/"
+ export ZIG_GLOBAL_CACHE_DIR="${T}/zig-cache/global/"
+}
+
+# @FUNCTION: zig_live_fetch
+# @USAGE: [<args>...]
+# @DESCRIPTION:
+# Fetches packages, if they exist, to the "ZBS_ECLASS_DIR/p/".
+# Adds build file path to ZBS_BASE_ARGS.
+# If you have some lazy dependency which is not triggered in default
+# configuration, pass options like you would pass them for regular
+# "ezig build". Try to cover all of them before "src_configure".
+# **Note**: this function will be deprecated once/if
+# https://github.com/ziglang/zig/pull/19975 lands.
+#
+# Example:
+# @CODE
+# src_unpack() {
+# # If there are no lazy dependency:
+# zig_live_fetch
+#
+# # If there are lazy dependencies that can be triggered together:
+# zig_live_fetch -Denable-wayland -Denable-xwayland
+#
+# # If there are 2 lazy dependencies that can't be triggered
+# # together in one call because they conflict:
+# zig_live_fetch -Dmain-backend=opengl
+# zig_live_fetch -Dmain-backend=vulkan
+# }
+# @CODE
+zig_live_fetch() {
+ # This function will likely be called in src_unpack,
+ # before [zig_]src_prepare, so this directory might not
+ # exist yet.
+ mkdir -p "${BUILD_DIR}" > /dev/null || die
+ pushd "${BUILD_DIR}" > /dev/null || die
+
+ ZBS_ARGS_BASE+=( --build-file "${S}/build.zig" )
+
+ local args=(
+ "${ZBS_ARGS_BASE[@]}"
+
+ --global-cache-dir "${ZBS_ECLASS_DIR}/"
+
+ # Function arguments
+ "${@}"
+ )
+
+ einfo "ZBS: live-fetching with:"
+ einfo "${args[@]}"
+ ezig build --help "${args[@]}" > /dev/null
+
+ popd > /dev/null || die
+}
+
+# @FUNCTION: zig_src_unpack
+# @DESCRIPTION:
+# Unpacks every archive in SRC_URI and ZBS_DEPENDENCIES,
+# in that order. Adds build file path to ZBS_BASE_ARGS.
+zig_src_unpack() {
+ # Thanks to Alfred Wingate "parona" for inspiration here:
+ # https://gitlab.com/Parona/parona-overlay/-/blob/874dcfe03116574a33ed51f469cc993e98db1fa2/eclass/zig.eclass
+
+ ZBS_ARGS_BASE+=( --build-file "${S}/build.zig" )
+
+ if [[ "${#ZBS_DEPENDENCIES_SRC_URI}" -eq 0 ]]; then
+ default_src_unpack
+ return
+ fi
+
+ local zig_deps=()
+ for dependency in "${!ZBS_DEPENDENCIES[@]}"; do
+ zig_deps+=("${dependency}")
+ done
+
+ # First unpack non-Zig dependencies, so that
+ # tarball with all Git dependencies tarballs is unpacked early.
+ local dist
+ for dist in ${A}; do
+ if ! has "${dist}" "${zig_deps[@]}"; then
+ unpack "${dist}"
+ fi
+ done
+
+ # Now unpack all Zig dependencies, including those that are
+ # now unpacked from tarball-tarball.
+ local zig_dep
+ for zig_dep in "${zig_deps[@]}"; do
+ # Hide now-spammy hash from stdout
+ ezig fetch --global-cache-dir "${ZBS_ECLASS_DIR}/" \
+ "${DISTDIR}/${zig_dep}" > /dev/null
+ done
+ einfo "ZBS: ${#zig_deps[@]} dependencies unpacked"
+}
+
+# @FUNCTION: zig_src_prepare
+# @DESCRIPTION:
+# Calls default "src_prepare" function, creates BUILD_DIR directory
+# and enables system mode (by adding to ZBS_BASE_ARGS).
+#
+# System mode is toggled here and not in "src_unpack" because they
+# could have been fetched by "live_fetch" in live ebuilds instead.
+zig_src_prepare() {
+ default_src_prepare
+
+ mkdir -p "${BUILD_DIR}" || die
+ einfo "BUILD_DIR: \"${BUILD_DIR}\""
+
+ local system_dir="${ZBS_ECLASS_DIR}/p/"
+ mkdir -p "${system_dir}" || die
+ ZBS_ARGS_BASE+=(
+ # Disable network access after ensuring all dependencies
+ # are unpacked (by "src_unpack" or "live_fetch")
+ --system "${system_dir}"
+ )
+}
+
+# @FUNCTION: zig_src_configure
+# @DESCRIPTION:
+# Creates ZBS_ARGS array which can be used in all future phases,
+# by combining ZBS_ARGS_BASE set previously, my_zbs_args from ebuild,
+# and ZBS_ARGS_EXTRA by user, in this order.
+#
+# Specific flags currently only add support for the cross-compilation.
+# They are likely to be extended in the future.
+zig_src_configure() {
+ # Handle quoted whitespace.
+ eval "local -a ZBS_ARGS_EXTRA=( ${ZBS_ARGS_EXTRA} )"
+
+ # Since most arguments in array are also cached by ZBS, we
+ # want to reuse array as much as possible, so prevent
+ # modification of it.
+ declare -g -a -r ZBS_ARGS=(
+ # Base arguments from pkg_setup/setup_base_args
+ "${ZBS_ARGS_BASE[@]}"
+
+ # Arguments from ebuild
+ "${my_zbs_args[@]}"
+
+ # Arguments from user
+ "${ZBS_ARGS_EXTRA[@]}"
+ )
+
+ einfo "ZBS: configured with:"
+ einfo "${ZBS_ARGS[@]}"
+}
+
+# @FUNCTION: zig_src_compile
+# @USAGE: [<args>...]
+# @DESCRIPTION:
+# Calls "ezig build" with previously set ZBS_ARGS.
+# Args passed to this function will be passed after ZBS_ARGS.
+zig_src_compile() {
+ pushd "${BUILD_DIR}" > /dev/null || die
+
+ local args=( "${ZBS_ARGS[@]}" "${@}" )
+ einfo "ZBS: compiling with: ${args[@]}"
+ nonfatal ezig build "${args[@]}" || die "ZBS: compilation failed"
+
+ popd > /dev/null || die
+}
+
+# @FUNCTION: zig_src_test
+# @USAGE: [<args>...]
+# @DESCRIPTION:
+# If "test" step exist, calls "ezig build test" with previously set
+# ZBS_ARGS.
+# Args passed to this function will be passed after ZBS_ARGS.
+# Note: currently step detection might give false positives in
+# very rare cases, it will be improved in the future.
+zig_src_test() {
+ pushd "${BUILD_DIR}" > /dev/null || die
+
+ local args=( "${ZBS_ARGS[@]}" "${@}" )
+
+ # UPSTREAM std.testing.tmpDir and a lot of other functions
+ # do not respect --cache-dir or ZIG_LOCAL_CACHE_DIR:
+ # https://github.com/ziglang/zig/issues/19874
+ mkdir ".zig-cache/" || die
+
+ # UPSTREAM Currently, step name can have any characters in it,
+ # including whitespaces, so splitting names and descriptions
+ # by whitespaces is not enough for some cases.
+ # We probably need something like "--list-steps names_only".
+ # In practice, almost nobody sets such names.
+ # Ignore failures like rare random "error.BrokenPipe" here.
+ # If they are real, they would appear in "ezig build test" anyway.
+ if grep -q '^[ ]*test[ ]' < <(
+ nonfatal ezig build --list-steps "${args[@]}"
+ ); then
+ einfo "ZBS: testing with: ${args[@]}"
+ nonfatal ezig build test "${args[@]}" ||
+ die "ZBS: tests failed"
+ else
+ einfo "Test step not found, skipping."
+ fi
+
+ popd > /dev/null || die
+}
+
+# @FUNCTION: zig_src_install
+# @USAGE: [<args>...]
+# @DESCRIPTION:
+# Calls "ezig build" with DESTDIR and previously set ZBS_ARGS.
+# Args passed to this function will be passed after ZBS_ARGS.
+# Also installs documentation via "einstalldocs".
+zig_src_install() {
+ pushd "${BUILD_DIR}" > /dev/null || die
+ local args=( "${ZBS_ARGS[@]}" "${@}" )
+ einfo "ZBS: installing with: ${args[@]}"
+ DESTDIR="${D}" nonfatal ezig build "${args[@]}" ||
+ die "ZBS: installing failed"
+ popd > /dev/null || die
+
+ einstalldocs
+}
+
+fi
+
+if [[ ! ${ZIG_OPTIONAL} ]]; then
+ EXPORT_FUNCTIONS pkg_setup src_unpack src_prepare src_configure src_compile src_test src_install
+fi