From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 5468915815E for ; Fri, 9 Feb 2024 23:50:01 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 163F9E2ABA; Fri, 9 Feb 2024 23:49:56 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id B771AE2AB4 for ; Fri, 9 Feb 2024 23:49:55 +0000 (UTC) References: <20240207203515.17640-6-mgorny@gentoo.org> <20240209170024.161215-2-mgorny@gentoo.org> User-agent: mu4e 1.10.8; emacs 30.0.50 From: Sam James To: gentoo-dev@lists.gentoo.org Cc: =?utf-8?B?TWljaGHFgiBHw7Nybnk=?= Subject: Re: [gentoo-dev] [PATCH v3] llvm-r1.eclass: Initial version Date: Fri, 09 Feb 2024 23:49:29 +0000 Organization: Gentoo In-reply-to: <20240209170024.161215-2-mgorny@gentoo.org> Message-ID: <87y1btryef.fsf@gentoo.org> Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Archives-Salt: 35ba4def-2156-4671-ba9c-780c79185eec X-Archives-Hash: e216eb8562509da693b696e682598ddf --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Micha=C5=82 G=C3=B3rny writes: > See-Also: https://bugs.gentoo.org/923228 > See-Also: https://bugs.gentoo.org/880671 s/See-Also/Bug/. LGTM otherwise. Thanks for working on this, it's a great improvement. > Closes: https://bugs.gentoo.org/821955 > Closes: https://bugs.gentoo.org/919150 > Signed-off-by: Micha=C5=82 G=C3=B3rny > --- > eclass/llvm-r1.eclass | 250 ++++++++++++++++++++++++++++++++++++++++ > eclass/tests/llvm-r1.sh | 151 ++++++++++++++++++++++++ > 2 files changed, 401 insertions(+) > create mode 100644 eclass/llvm-r1.eclass > create mode 100755 eclass/tests/llvm-r1.sh > > Changed in v3: added LLVM_OPTIONAL to avoid unconditionally setting > REQUIRED_USE when the ebuild doesn't require LLVM unconditionally. > It also controls pkg_setup export. > > diff --git a/eclass/llvm-r1.eclass b/eclass/llvm-r1.eclass > new file mode 100644 > index 000000000000..658946a1ecbd > --- /dev/null > +++ b/eclass/llvm-r1.eclass > @@ -0,0 +1,250 @@ > +# Copyright 2024 Gentoo Authors > +# Distributed under the terms of the GNU General Public License v2 > + > +# @ECLASS: llvm-r1.eclass > +# @MAINTAINER: > +# Micha=C5=82 G=C3=B3rny > +# @AUTHOR: > +# Micha=C5=82 G=C3=B3rny > +# @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-r1_pkg_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. > +# > +# Example: > +# @CODE > +# LLVM_COMPAT=3D( {16..18} ) > +# > +# inherit llvm-r1 > +# > +# DEPEND=3D" > +# dev-libs/libfoo[${LLVM_USEDEP}] > +# $(llvm_gen_dep ' > +# sys-devel/clang:${LLVM_SLOT} > +# sys-devel/llvm:${LLVM_SLOT} > +# ') > +# " > +# @CODE > + > +case ${EAPI} in > + 8) ;; > + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; > +esac > + > +if [[ ! ${_LLVM_R1_ECLASS} ]]; then > +_LLVM_R1_ECLASS=3D1 > + > +inherit llvm-utils > + > +# =3D=3D internal control knobs =3D=3D > + > +# @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=3D15 > + > +# @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=3D17 > + > +# =3D=3D control variables =3D=3D > + > +# @ECLASS_VARIABLE: LLVM_COMPAT > +# @PRE_INHERIT > +# @REQUIRED > +# @DESCRIPTION: > +# A list of LLVM slots supported by the package, oldest to newest. > +# > +# Example: > +# @CODE > +# LLVM_COMPAT=3D( {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. > + > +# =3D=3D global metadata =3D=3D > + > +# @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} !=3D *a* ]]; then > + die "LLVM_COMPAT must be set to an array before inheriting ${ECLASS}" > + fi > + > + local stable=3D() unstable=3D() > + local x > + for x in "${LLVM_COMPAT[@]}"; do > + if [[ ${x} -gt ${_LLVM_NEWEST_STABLE} ]]; then > + unstable+=3D( "${x}" ) > + elif [[ ${x} -ge ${_LLVM_OLDEST_SLOT} ]]; then > + stable+=3D( "${x}" ) > + fi > + done > + > + _LLVM_SLOTS=3D( "${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 > + IUSE=3D"+llvm_slot_${stable[-1]}" > + unset 'stable[-1]' > + else > + IUSE=3D"+llvm_slot_${unstable[-1]}" > + unset 'unstable[-1]' > + fi > + local nondefault=3D( "${stable[@]}" "${unstable[@]}" ) > + IUSE+=3D" ${nondefault[*]/#/llvm_slot_}" > + > + local flags=3D( "${_LLVM_SLOTS[@]/#/llvm_slot_}" ) > + LLVM_REQUIRED_USE=3D"^^ ( ${flags[*]} )" > + local usedep_flags=3D${flags[*]/%/(-)?} > + LLVM_USEDEP=3D${usedep_flags// /,} > + readonly LLVM_REQUIRED_USE LLVM_USEDEP > + > + if [[ ! ${LLVM_OPTIONAL} ]]; then > + REQUIRED_USE=3D${LLVM_REQUIRED_USE} > + fi > +} > +_llvm_set_globals > +unset -f _llvm_set_globals > + > +# =3D=3D metadata helpers =3D=3D > + > +# @FUNCTION: llvm_gen_dep > +# @USAGE: > +# @DESCRIPTION: > +# Output a dependency block, repeating "" 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=3D" > +# $(llvm_gen_dep ' > +# sys-devel/clang:${LLVM_SLOT} > +# sys-devel/llvm:${LLVM_SLOT} > +# ') > +# " > +# @CODE > +llvm_gen_dep() { > + debug-print-function ${FUNCNAME} "${@}" > + > + [[ ${#} -ne 1 ]] && die "Usage: ${FUNCNAME} " > + > + local dep=3D${1} > + > + local slot > + for slot in "${_LLVM_SLOTS[@]}"; do > + echo "llvm_slot_${slot}? ( ${dep//\$\{LLVM_SLOT\}/${slot}} )" > + done > +} > + > +# =3D=3D ebuild helpers =3D=3D > + > +# @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=3D${ESYSROOT} > + ;; > + -b) > + prefix=3D${BROOT} > + ;; > + *) > + die "${FUNCNAME}: invalid option: ${1}" > + ;; > + esac > + > + echo "${prefix}/usr/lib/llvm/${LLVM_SLOT}" > +} > + > +# @FUNCTION: llvm-r1_pkg_setup > +# @DESCRIPTION: > +# Prepend the appropriate executable directory for the selected LLVM > +# slot to PATH. > +# > +# The PATH manipulation is only done for source builds. The function > +# is a no-op when installing a binary package. > +# > +# If any other behavior is desired, the contents of the function > +# should be inlined into the ebuild and modified as necessary. > +# > +# Note that this function is not exported if LLVM_OPTIONAL is set. > +# In that case, it needs to be called manually. > +llvm-r1_pkg_setup() { > + debug-print-function ${FUNCNAME} "${@}" > + > + if [[ ${MERGE_TYPE} !=3D binary ]]; then > + [[ -z ${LLVM_SLOT} ]] && die "LLVM_SLOT unset (broken USE_EXPAND?)" > + > + 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 > + > + # Set LLVM_CONFIG to help Meson (bug #907965) but only do it > + # for empty ESYSROOT (as a proxy for "are we cross-compiling?"). > + if [[ -z ${ESYSROOT} ]] ; then > + llvm_fix_tool_path LLVM_CONFIG > + fi > + > + llvm_prepend_path "${LLVM_SLOT}" > + fi > +} > + > +fi > + > +if [[ ! ${LLVM_OPTIONAL} ]]; then > + EXPORT_FUNCTIONS pkg_setup > +fi > diff --git a/eclass/tests/llvm-r1.sh b/eclass/tests/llvm-r1.sh > new file mode 100755 > index 000000000000..9958f5bba420 > --- /dev/null > +++ b/eclass/tests/llvm-r1.sh > @@ -0,0 +1,151 @@ > +#!/bin/bash > +# Copyright 2024 Gentoo Authors > +# Distributed under the terms of the GNU General Public License v2 > + > +source tests-common.sh || exit > + > +EAPI=3D8 > + > +test_globals() { > + local compat=3D${1} > + local expected_iuse=3D${2} > + local expected_required_use=3D${3} > + local expected_usedep=3D${4} > + local x > + > + tbegin "LLVM_COMPAT=3D( ${compat} )" > + > + ( > + local fail=3D0 > + local LLVM_COMPAT=3D( ${compat} ) > + > + inherit llvm-r1 > + > + if [[ ${IUSE%% } !=3D ${expected_iuse} ]]; then > + eerror " IUSE: ${IUSE%% }" > + eerror "does not match: ${expected_iuse}" > + fail=3D1 > + fi > + > + if [[ ${REQUIRED_USE} !=3D ${expected_required_use} ]]; then > + eerror " REQUIRED_USE: ${REQUIRED_USE}" > + eerror "does not match: ${expected_required_use}" > + fail=3D1 > + fi > + > + if [[ ${LLVM_USEDEP} !=3D ${expected_usedep} ]]; then > + eerror " LLVM_USEDEP: ${LLVM_USEDEP}" > + eerror "does not match: ${expected_usedep}" > + fail=3D1 > + fi > + > + exit "${fail}" > + ) > + > + tend "${?}" > +} > + > +test_gen_dep() { > + local arg=3D${1} > + local expected > + read -r -d '' expected > + > + tbegin "llvm_gen_dep ${arg}" > + local value=3D$(llvm_gen_dep "${arg}") > + > + if [[ ${value} !=3D ${expected} ]]; then > + eerror "python_get_usedep ${arg}" > + eerror "gave:" > + eerror " ${value}" > + eerror "expected:" > + eerror " ${expected}" > + fi > + tend ${?} > +} > + > +test_fix_clang_version() { > + local var=3D${1} > + local tool=3D${2} > + local version=3D${3} > + local expected=3D${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}=3D${tool} > + tbegin "llvm_fix_clang_version ${var}=3D${tool} for ${version}" > + llvm_fix_clang_version "${var}" > + if [[ ${!var} !=3D ${expected} ]]; then > + eerror "llvm_fix_clang_version ${var}" > + eerror " gave: ${!var}" > + eerror "expected: ${expected}" > + fi > + tend ${?} > +} > + > +test_fix_tool_path() { > + local var=3D${1} > + local tool=3D${2} > + local expected_subst=3D${3} > + local expected=3D${tool} > + > + tbegin "llvm_fix_tool_path ${1}=3D${2} (from llvm? ${expected_subst})" > + > + local matches=3D( "${BROOT}"/usr/lib/llvm/*/bin/"${tool}" ) > + if [[ ${expected_subst} =3D=3D 1 ]]; then > + if [[ ! -x ${matches[0]} ]]; then > + ewarn "- skipping, test requires ${tool}" > + return > + fi > + > + expected=3D${matches[0]} > + local -x PATH=3D${matches[0]%/*} > + else > + local -x PATH=3D > + fi > + > + declare -g ${var}=3D${tool} > + llvm_fix_tool_path "${var}" > + if [[ ${!var} !=3D ${expected} ]]; then > + eerror "llvm_fix_tool_path ${var}" > + eerror " gave: ${!var}" > + eerror "expected: ${expected}" > + fi > + tend ${?} > +} > + > +test_globals '14 15 16 17 18' \ > + "+llvm_slot_17 llvm_slot_15 llvm_slot_16 llvm_slot_18" \ > + "^^ ( llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18 )" \ > + "llvm_slot_15(-)?,llvm_slot_16(-)?,llvm_slot_17(-)?,llvm_slot_18(-)?" > +test_globals '14 15 16' \ > + "+llvm_slot_16 llvm_slot_15" \ > + "^^ ( llvm_slot_15 llvm_slot_16 )" \ > + "llvm_slot_15(-)?,llvm_slot_16(-)?" > +test_globals '15 18' \ > + "+llvm_slot_15 llvm_slot_18" \ > + "^^ ( llvm_slot_15 llvm_slot_18 )" \ > + "llvm_slot_15(-)?,llvm_slot_18(-)?" > +test_globals '18' \ > + "+llvm_slot_18" \ > + "^^ ( llvm_slot_18 )" \ > + "llvm_slot_18(-)?" > + > +LLVM_COMPAT=3D( {14..18} ) > +inherit llvm-r1 > + > +test_gen_dep 'sys-devel/llvm:${LLVM_SLOT} sys-devel/clang:${LLVM_SLOT}' = <<-EOF > + llvm_slot_15? ( sys-devel/llvm:15 sys-devel/clang:15 ) > + llvm_slot_16? ( sys-devel/llvm:16 sys-devel/clang:16 ) > + llvm_slot_17? ( sys-devel/llvm:17 sys-devel/clang:17 ) > + llvm_slot_18? ( sys-devel/llvm:18 sys-devel/clang:18 ) > +EOF > + > +texit --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOUEARYKAI0WIQQlpruI3Zt2TGtVQcJzhAn1IN+RkAUCZca6GV8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0MjVB NkJCODhERDlCNzY0QzZCNTU0MUMyNzM4NDA5RjUyMERGOTE5MA8cc2FtQGdlbnRv by5vcmcACgkQc4QJ9SDfkZDRnQEAuXpF34ofdopbh/h193GOEb90PAJuVgjywe3g YZUV7gsA/jomQqckf+Pyy9SumW+xrFgXOxRvG4qGvUTO7LlDHggK =k9jh -----END PGP SIGNATURE----- --=-=-=--