public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess
@ 2024-02-07 20:11 Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 1/8] llvm-utils.eclass: Introduce an eclass for common helpers Michał Górny
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Michał Górny @ 2024-02-07 20:11 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Hi,

TL;DR: here's a series of patches adding llvm-r1.eclass that tries
to sort out LLVM dependency mess via using USE_EXPAND flags LLVM_SLOT.


Roughly, the problems with LLVM are that:

1. Every half a year there's a major release that's doing major breaking
   API changes.

2. Reverse dependencies are usually slow to adapt.

3. Often multiple packages in a depchain end up linking to LLVM,
   and you really shouldn't link more than one version at a time.

Because of the first two, we've started slotting LLVM.  However, our
current approach of combining || blocks with := deps turned out to be
messy.  It is inconvenient, it can't properly dep on two leaf LLVM
packages and it can't enforce linked slot match.

So I've figured out it's time to give in and switch to a USE flag-based
approach.  Funny enough, this makes both the eclass and the ebuilds
using it simpler.  This patch series does, in order:

1. Split out a llvm-utils.eclass that carries code from llvm.eclass
   that will be shared by llvm-r1.eclass, but also used by some LLVM
   ebuilds directly (they currently depend on llvm.eclass but they
   don't really need to).  This also involves splitting out the PATH
   mangling logic, fixing it and adding more tests for all
   the functions.

2. Add a USE_EXPAND="LLVM_SLOT" along with some initial masks.  We'll
   probably need to play with masks a bit more before llvm-r1.eclass
   is used in stable ebuilds.

3. Add a llvm-r1.eclass.  More design details below.

4. Convert some example ebuilds to the new eclasses.


The new eclass uses an approach that's a hybrid between python-single-r1
and slots.  It expects LLVM_COMPAT to declare supported LLVM versions,
and gives llvm_gen_dep to depend on slotted packages, and LLVM_USEDEP
to depend on non-slotted packages.  It sets IUSE, REQUIRED_USE
and exports pkg_setup() that takes care of tool adjustment and setting
PATH, similarly to what the old eclass did -- except it uses whatever
LLVM_SLOT was selected by the user rather than using a horribly
convoluted logic to guess one.

One original idea is that we don't set default LLVM_SLOT in profiles.
Instead, the eclass uses IUSE defaults to select the "newest stable"
slot that's supported by the package.  The rationale is that we have
too wide a span of LLVM versions supported by various packages to be
able to conveniently select just one.


A rough idea of how an ebuild using the eclass could look like:

  LLVM_COMPAT=( {15..18} )

  inherit llvm-r1

  IUSE="llvm"

  DEPEND="
    llvm? (
      dev-libs/my-dependency[${LLVM_USEDEP}]
      $(llvm_gen_dep '
        sys-devel/clang:${LLVM_SLOT}
        sys-devel/llvm:${LLVM_SLOT}
      ')
    )
  "

  pkg_setup() {
    use llvm && llvm-r1_pkg_setup
  }

  src_configure() {
    econf --if-path-doesnt-work="$(get_llvm_prefix)"
  }



Michał Górny (8):
  llvm-utils.eclass: Introduce an eclass for common helpers
  llvm-utils.eclass: Split out PATH prepending logic
  llvm-utils.eclass: Fix llvm_prepend_path to avoid duplicates
  profiles: Introduce LLVM_SLOT USE_EXPAND variable
  llvm-r1.eclass: Initial version
  dev-util/intel_clc: Migrate to llvm-r1
  media-libs/mesa: Migrate to llvm-r1
  sys-devel/lld: Migrate to llvm-utils.eclass

 dev-util/intel_clc/intel_clc-24.0.0.ebuild  |  48 +----
 dev-util/intel_clc/intel_clc-9999.ebuild    |  48 +----
 eclass/llvm-r1.eclass                       | 226 ++++++++++++++++++++
 eclass/llvm-utils.eclass                    | 151 +++++++++++++
 eclass/llvm.eclass                          | 117 +---------
 eclass/tests/llvm-r1.sh                     | 151 +++++++++++++
 eclass/tests/llvm-utils.sh                  | 112 ++++++++++
 media-libs/mesa/mesa-24.0.0.ebuild          |  53 +----
 media-libs/mesa/mesa-9999.ebuild            |  53 +----
 profiles/arch/base/use.mask                 |   5 +
 profiles/arch/loong/use.mask                |   6 +-
 profiles/base/make.defaults                 |   2 +-
 profiles/desc/llvm_slot.desc                |   8 +
 profiles/embedded/make.defaults             |   4 +-
 sys-devel/lld/lld-18.1.0_rc2.ebuild         |   5 +-
 sys-devel/lld/lld-19.0.0.9999.ebuild        |   5 +-
 sys-devel/lld/lld-19.0.0_pre20240203.ebuild |   5 +-
 17 files changed, 714 insertions(+), 285 deletions(-)
 create mode 100644 eclass/llvm-r1.eclass
 create mode 100644 eclass/llvm-utils.eclass
 create mode 100755 eclass/tests/llvm-r1.sh
 create mode 100755 eclass/tests/llvm-utils.sh
 create mode 100644 profiles/desc/llvm_slot.desc

-- 
2.43.0



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH 1/8] llvm-utils.eclass: Introduce an eclass for common helpers
  2024-02-07 20:11 [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess Michał Górny
@ 2024-02-07 20:11 ` Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 2/8] llvm-utils.eclass: Split out PATH prepending logic Michał Górny
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Michał Górny @ 2024-02-07 20:11 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Move some reusable functions from llvm.eclass to llvm-utils.eclass.
This is with minimal modifications so far (only argument checks were
cleaned up).

Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 eclass/llvm-utils.eclass   | 115 +++++++++++++++++++++++++++++++++++++
 eclass/llvm.eclass         |  92 +----------------------------
 eclass/tests/llvm-utils.sh |  82 ++++++++++++++++++++++++++
 3 files changed, 200 insertions(+), 89 deletions(-)
 create mode 100644 eclass/llvm-utils.eclass
 create mode 100755 eclass/tests/llvm-utils.sh

diff --git a/eclass/llvm-utils.eclass b/eclass/llvm-utils.eclass
new file mode 100644
index 000000000000..43988f6f88c7
--- /dev/null
+++ b/eclass/llvm-utils.eclass
@@ -0,0 +1,115 @@
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: llvm-utils.eclass
+# @MAINTAINER:
+# Michał Górny <mgorny@gentoo.org>
+# @AUTHOR:
+# Michał Górny <mgorny@gentoo.org>
+# @SUPPORTED_EAPIS: 7 8
+# @BLURB: Common utility functions for building against installed LLVM
+# @DESCRIPTION:
+# The utility eclass providing shared functions reused between
+# llvm.eclass and llvm-r1.eclass.  It may also be used directly
+# in ebuilds.
+
+case ${EAPI} in
+	7|8) ;;
+	*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+if [[ ! ${_LLVM_UTILS_ECLASS} ]]; then
+_LLVM_UTILS_ECLASS=1
+
+# @FUNCTION: llvm_tuple_to_target
+# @USAGE: [<tuple>]
+# @DESCRIPTION:
+# Translate a tuple into a target suitable for LLVM_TARGETS.
+# Defaults to ${CHOST} if not specified.
+llvm_tuple_to_target() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	[[ ${#} -gt 1 ]] && die "Usage: ${FUNCNAME} [<tuple>]"
+
+	case ${1:-${CHOST}} in
+		aarch64*) echo "AArch64";;
+		amdgcn*) echo "AMDGPU";;
+		arc*) echo "ARC";;
+		arm*) echo "ARM";;
+		avr*) echo "AVR";;
+		bpf*) echo "BPF";;
+		csky*) echo "CSKY";;
+		loong*) echo "LoongArch";;
+		m68k*) echo "M68k";;
+		mips*) echo "Mips";;
+		msp430*) echo "MSP430";;
+		nvptx*) echo "NVPTX";;
+		powerpc*) echo "PowerPC";;
+		riscv*) echo "RISCV";;
+		sparc*) echo "Sparc";;
+		s390*) echo "SystemZ";;
+		x86_64*|i?86*) echo "X86";;
+		xtensa*) echo "Xtensa";;
+		*) die "Unknown LLVM target for tuple ${1:-${CHOST}}"
+	esac
+}
+
+# @FUNCTION: llvm_fix_clang_version
+# @USAGE: <variable-name>...
+# @DESCRIPTION:
+# Fix the clang compiler name in specified variables to include
+# the major version, to prevent PATH alterations from forcing an older
+# clang version being used.
+llvm_fix_clang_version() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	local shopt_save=$(shopt -p -o noglob)
+	set -f
+	local var
+	for var; do
+		local split=( ${!var} )
+		case ${split[0]} in
+			*clang|*clang++|*clang-cpp)
+				local version=()
+				read -r -a version < <("${split[0]}" --version)
+				local major=${version[-1]%%.*}
+				if [[ -n ${major//[0-9]} ]]; then
+					die "${var}=${!var} produced invalid --version: ${version[*]}"
+				fi
+
+				split[0]+=-${major}
+				if ! type -P "${split[0]}" &>/dev/null; then
+					die "${split[0]} does not seem to exist"
+				fi
+				declare -g "${var}=${split[*]}"
+				;;
+		esac
+	done
+	${shopt_save}
+}
+
+# @FUNCTION: llvm_fix_tool_path
+# @USAGE: <variable-name>...
+# @DESCRIPTION:
+# Fix the LLVM tools referenced in the specified variables to their
+# current location, to prevent PATH alterations from forcing older
+# versions being used.
+llvm_fix_tool_path() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	local shopt_save=$(shopt -p -o noglob)
+	set -f
+	local var
+	for var; do
+		local split=( ${!var} )
+		local path=$(type -P ${split[0]} 2>/dev/null)
+		# if it resides in one of the LLVM prefixes, it's an LLVM tool!
+		if [[ ${path} == "${BROOT}/usr/lib/llvm"* ]]; then
+			split[0]=${path}
+			declare -g "${var}=${split[*]}"
+		fi
+	done
+	${shopt_save}
+}
+
+fi
diff --git a/eclass/llvm.eclass b/eclass/llvm.eclass
index 91cc68d966fe..05ffcfd7cc6d 100644
--- a/eclass/llvm.eclass
+++ b/eclass/llvm.eclass
@@ -7,6 +7,7 @@
 # @AUTHOR:
 # Michał Górny <mgorny@gentoo.org>
 # @SUPPORTED_EAPIS: 7 8
+# @PROVIDES: llvm-utils
 # @BLURB: Utility functions to build against slotted LLVM
 # @DESCRIPTION:
 # The llvm.eclass provides utility functions that can be used to build
@@ -64,6 +65,8 @@ esac
 if [[ ! ${_LLVM_ECLASS} ]]; then
 _LLVM_ECLASS=1
 
+inherit llvm-utils
+
 # make sure that the versions installing straight into /usr/bin
 # are uninstalled
 DEPEND="!!sys-devel/llvm:0"
@@ -174,95 +177,6 @@ get_llvm_prefix() {
 	echo "${prefix}/usr/lib/llvm/$(get_llvm_slot "${@}")"
 }
 
-# @FUNCTION: llvm_tuple_to_target
-# @USAGE: [<tuple>]
-# @DESCRIPTION:
-# Translate a tuple into a target suitable for LLVM_TARGETS.
-# Defaults to ${CHOST} if not specified.
-llvm_tuple_to_target() {
-	debug-print-function ${FUNCNAME} "${@}"
-
-	case ${1:-${CHOST}} in
-		aarch64*) echo "AArch64";;
-		amdgcn*) echo "AMDGPU";;
-		arc*) echo "ARC";;
-		arm*) echo "ARM";;
-		avr*) echo "AVR";;
-		bpf*) echo "BPF";;
-		csky*) echo "CSKY";;
-		loong*) echo "LoongArch";;
-		m68k*) echo "M68k";;
-		mips*) echo "Mips";;
-		msp430*) echo "MSP430";;
-		nvptx*) echo "NVPTX";;
-		powerpc*) echo "PowerPC";;
-		riscv*) echo "RISCV";;
-		sparc*) echo "Sparc";;
-		s390*) echo "SystemZ";;
-		x86_64*|i?86*) echo "X86";;
-		xtensa*) echo "Xtensa";;
-		*) die "Unknown LLVM target for tuple ${1:-${CHOST}}"
-	esac
-}
-
-# @FUNCTION: llvm_fix_clang_version
-# @USAGE: <variable-name>...
-# @DESCRIPTION:
-# Fix the clang compiler name in specified variables to include
-# the major version, to prevent PATH alterations from forcing an older
-# clang version being used.
-llvm_fix_clang_version() {
-	debug-print-function ${FUNCNAME} "${@}"
-
-	local shopt_save=$(shopt -p -o noglob)
-	set -f
-	local var
-	for var; do
-		local split=( ${!var} )
-		case ${split[0]} in
-			*clang|*clang++|*clang-cpp)
-				local version=()
-				read -r -a version < <("${split[0]}" --version)
-				local major=${version[-1]%%.*}
-				if [[ -n ${major//[0-9]} ]]; then
-					die "${var}=${!var} produced invalid --version: ${version[*]}"
-				fi
-
-				split[0]+=-${major}
-				if ! type -P "${split[0]}" &>/dev/null; then
-					die "${split[0]} does not seem to exist"
-				fi
-				declare -g "${var}=${split[*]}"
-				;;
-		esac
-	done
-	${shopt_save}
-}
-
-# @FUNCTION: llvm_fix_tool_path
-# @USAGE: <variable-name>...
-# @DESCRIPTION:
-# Fix the LLVM tools referenced in the specified variables to their
-# current location, to prevent PATH alterations from forcing older
-# versions being used.
-llvm_fix_tool_path() {
-	debug-print-function ${FUNCNAME} "${@}"
-
-	local shopt_save=$(shopt -p -o noglob)
-	set -f
-	local var
-	for var; do
-		local split=( ${!var} )
-		local path=$(type -P ${split[0]} 2>/dev/null)
-		# if it resides in one of the LLVM prefixes, it's an LLVM tool!
-		if [[ ${path} == "${BROOT}/usr/lib/llvm"* ]]; then
-			split[0]=${path}
-			declare -g "${var}=${split[*]}"
-		fi
-	done
-	${shopt_save}
-}
-
 # @FUNCTION: llvm_pkg_setup
 # @DESCRIPTION:
 # Prepend the appropriate executable directory for the newest
diff --git a/eclass/tests/llvm-utils.sh b/eclass/tests/llvm-utils.sh
new file mode 100755
index 000000000000..44ad1b4adc84
--- /dev/null
+++ b/eclass/tests/llvm-utils.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+source tests-common.sh || exit
+
+EAPI=8
+
+inherit llvm-utils
+
+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 ${?}
+}
+
+test_fix_clang_version CC clang 19.0.0git78b4e7c5 clang-19
+test_fix_clang_version CC clang 17.0.6 clang-17
+test_fix_clang_version CXX clang++ 17.0.6 clang++-17
+test_fix_clang_version CC x86_64-pc-linux-gnu-clang 17.0.6 \
+	x86_64-pc-linux-gnu-clang-17
+test_fix_clang_version CC clang-17 n/a clang-17
+test_fix_clang_version CC gcc n/a gcc
+
+test_fix_tool_path AR llvm-ar 1
+test_fix_tool_path RANLIB llvm-ranlib 1
+test_fix_tool_path AR ar 1
+test_fix_tool_path AR ar 0
+
+texit
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH 2/8] llvm-utils.eclass: Split out PATH prepending logic
  2024-02-07 20:11 [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 1/8] llvm-utils.eclass: Introduce an eclass for common helpers Michał Górny
@ 2024-02-07 20:11 ` Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 3/8] llvm-utils.eclass: Fix llvm_prepend_path to avoid duplicates Michał Górny
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Michał Górny @ 2024-02-07 20:11 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Split the logic prepending PATH from pkg_setup() into a dedicated
llvm_prepend_path() function.

Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 eclass/llvm-utils.eclass   | 36 ++++++++++++++++++++++++++++++++++++
 eclass/llvm.eclass         | 25 +------------------------
 eclass/tests/llvm-utils.sh | 24 ++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 24 deletions(-)

diff --git a/eclass/llvm-utils.eclass b/eclass/llvm-utils.eclass
index 43988f6f88c7..f308667e3dc2 100644
--- a/eclass/llvm-utils.eclass
+++ b/eclass/llvm-utils.eclass
@@ -112,4 +112,40 @@ llvm_fix_tool_path() {
 	${shopt_save}
 }
 
+# @FUNCTION: llvm_prepend_path
+# @USAGE: <slot>
+# @DESCRIPTION:
+# Prepend the path to the specified LLVM slot to PATH variable,
+# and reexport it.
+llvm_prepend_path() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	[[ ${#} -ne 1 ]] && die "Usage: ${FUNCNAME} <slot>"
+	local slot=${1}
+
+	local llvm_path=${ESYSROOT}/usr/lib/llvm/${slot}/bin
+	local IFS=:
+	local split_path=( ${PATH} )
+	local new_path=()
+	local x added=
+
+	# prepend new path in front of the first LLVM version found
+	for x in "${split_path[@]}"; do
+		if [[ ${x} == */usr/lib/llvm/*/bin ]]; then
+			if [[ ${x} != ${llvm_path} ]]; then
+				new_path+=( "${llvm_path}" )
+			elif [[ ${added} && ${x} == ${llvm_path} ]]; then
+				# deduplicate
+				continue
+			fi
+			added=1
+		fi
+		new_path+=( "${x}" )
+	done
+	# ...or to the end of PATH
+	[[ ${added} ]] || new_path+=( "${llvm_path}" )
+
+	export PATH=${new_path[*]}
+}
+
 fi
diff --git a/eclass/llvm.eclass b/eclass/llvm.eclass
index 05ffcfd7cc6d..e297fe992c9f 100644
--- a/eclass/llvm.eclass
+++ b/eclass/llvm.eclass
@@ -212,30 +212,7 @@ llvm_pkg_setup() {
 			llvm_fix_tool_path LLVM_CONFIG
 		fi
 
-		local prefix=${ESYSROOT}
-		local llvm_path=${prefix}/usr/lib/llvm/${LLVM_SLOT}/bin
-		local IFS=:
-		local split_path=( ${PATH} )
-		local new_path=()
-		local x added=
-
-		# prepend new path before first LLVM version found
-		for x in "${split_path[@]}"; do
-			if [[ ${x} == */usr/lib/llvm/*/bin ]]; then
-				if [[ ${x} != ${llvm_path} ]]; then
-					new_path+=( "${llvm_path}" )
-				elif [[ ${added} && ${x} == ${llvm_path} ]]; then
-					# deduplicate
-					continue
-				fi
-				added=1
-			fi
-			new_path+=( "${x}" )
-		done
-		# ...or to the end of PATH
-		[[ ${added} ]] || new_path+=( "${llvm_path}" )
-
-		export PATH=${new_path[*]}
+		llvm_prepend_path "${LLVM_SLOT}"
 	fi
 }
 
diff --git a/eclass/tests/llvm-utils.sh b/eclass/tests/llvm-utils.sh
index 44ad1b4adc84..5a46b25b7ad6 100755
--- a/eclass/tests/llvm-utils.sh
+++ b/eclass/tests/llvm-utils.sh
@@ -66,6 +66,21 @@ test_fix_tool_path() {
 	tend ${?}
 }
 
+test_prepend_path() {
+	local slot=${1}
+	local -x PATH=${2}
+	local expected=${3}
+
+	tbegin "llvm_prepend_path ${slot} to PATH=${PATH}"
+	llvm_prepend_path "${slot}"
+	if [[ ${PATH} != ${expected} ]]; then
+		eerror "llvm_prepend_path ${var}"
+		eerror "    gave: ${PATH}"
+		eerror "expected: ${expected}"
+	fi
+	tend ${?}
+}
+
 test_fix_clang_version CC clang 19.0.0git78b4e7c5 clang-19
 test_fix_clang_version CC clang 17.0.6 clang-17
 test_fix_clang_version CXX clang++ 17.0.6 clang++-17
@@ -79,4 +94,13 @@ test_fix_tool_path RANLIB llvm-ranlib 1
 test_fix_tool_path AR ar 1
 test_fix_tool_path AR ar 0
 
+ESYSROOT=
+test_prepend_path 17 /usr/bin /usr/bin:/usr/lib/llvm/17/bin
+test_prepend_path 17 /usr/lib/llvm/17/bin:/usr/bin /usr/lib/llvm/17/bin:/usr/bin
+test_prepend_path 17 /usr/bin:/usr/lib/llvm/17/bin /usr/bin:/usr/lib/llvm/17/bin
+test_prepend_path 18 /usr/lib/llvm/17/bin:/usr/bin \
+	/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin:/usr/bin
+test_prepend_path 18 /usr/bin:/usr/lib/llvm/17/bin \
+	/usr/bin:/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin
+
 texit
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH 3/8] llvm-utils.eclass: Fix llvm_prepend_path to avoid duplicates
  2024-02-07 20:11 [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 1/8] llvm-utils.eclass: Introduce an eclass for common helpers Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 2/8] llvm-utils.eclass: Split out PATH prepending logic Michał Górny
@ 2024-02-07 20:11 ` Michał Górny
  2024-02-08 19:06   ` [gentoo-dev] [PATCH] " Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 4/8] profiles: Introduce LLVM_SLOT USE_EXPAND variable Michał Górny
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Michał Górny @ 2024-02-07 20:11 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Fix llvm_prepend_path() not to append the new path multiple times,
if the original PATH variable contained multiple LLVM directories.

Thanks to @miller-alex who spotted it in:
https://github.com/gentoo/gentoo/pull/35196#discussion_r1480330001

Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 eclass/llvm-utils.eclass   | 2 +-
 eclass/tests/llvm-utils.sh | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/eclass/llvm-utils.eclass b/eclass/llvm-utils.eclass
index f308667e3dc2..86933484fa94 100644
--- a/eclass/llvm-utils.eclass
+++ b/eclass/llvm-utils.eclass
@@ -132,7 +132,7 @@ llvm_prepend_path() {
 	# prepend new path in front of the first LLVM version found
 	for x in "${split_path[@]}"; do
 		if [[ ${x} == */usr/lib/llvm/*/bin ]]; then
-			if [[ ${x} != ${llvm_path} ]]; then
+			if [[ ${x} != ${llvm_path} && ! ${added} ]]; then
 				new_path+=( "${llvm_path}" )
 			elif [[ ${added} && ${x} == ${llvm_path} ]]; then
 				# deduplicate
diff --git a/eclass/tests/llvm-utils.sh b/eclass/tests/llvm-utils.sh
index 5a46b25b7ad6..c786ef04ddcd 100755
--- a/eclass/tests/llvm-utils.sh
+++ b/eclass/tests/llvm-utils.sh
@@ -102,5 +102,11 @@ test_prepend_path 18 /usr/lib/llvm/17/bin:/usr/bin \
 	/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin:/usr/bin
 test_prepend_path 18 /usr/bin:/usr/lib/llvm/17/bin \
 	/usr/bin:/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin
+test_prepend_path 18 /usr/lib/llvm/17/bin:/usr/lib/llvm/16/bin:/usr/bin \
+	/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin:/usr/lib/llvm/16/bin:/usr/bin
+test_prepend_path 18 /usr/bin:/usr/lib/llvm/17/bin:/usr/lib/llvm/16/bin \
+	/usr/bin:/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin:/usr/lib/llvm/16/bin
+test_prepend_path 18 /usr/lib/llvm/17/bin:/usr/bin:/usr/lib/llvm/16/bin \
+	/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin:/usr/bin:/usr/lib/llvm/16/bin
 
 texit
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH 4/8] profiles: Introduce LLVM_SLOT USE_EXPAND variable
  2024-02-07 20:11 [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess Michał Górny
                   ` (2 preceding siblings ...)
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 3/8] llvm-utils.eclass: Fix llvm_prepend_path to avoid duplicates Michał Górny
@ 2024-02-07 20:11 ` Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 5/8] llvm-r1.eclass: Initial version Michał Górny
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Michał Górny @ 2024-02-07 20:11 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 profiles/arch/base/use.mask     | 5 +++++
 profiles/arch/loong/use.mask    | 6 +++++-
 profiles/base/make.defaults     | 2 +-
 profiles/desc/llvm_slot.desc    | 8 ++++++++
 profiles/embedded/make.defaults | 4 ++--
 5 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 profiles/desc/llvm_slot.desc

diff --git a/profiles/arch/base/use.mask b/profiles/arch/base/use.mask
index 2fc87978ee66..81dea61d6575 100644
--- a/profiles/arch/base/use.mask
+++ b/profiles/arch/base/use.mask
@@ -1,6 +1,11 @@
 # Copyright 1999-2024 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
+# Michał Górny <mgorny@gentoo.org> (2021-02-05)
+# LLVM slots without keywords.
+llvm_slot_18
+llvm_slot_19
+
 # Andrew Ammerlaan <andrewammerlaan@gentoo.org> (2023-07-11)
 # Mask secureboot flag on arches where sbsigntools is not keyworded
 secureboot
diff --git a/profiles/arch/loong/use.mask b/profiles/arch/loong/use.mask
index 053f6480d1f4..b3071910944e 100644
--- a/profiles/arch/loong/use.mask
+++ b/profiles/arch/loong/use.mask
@@ -1,6 +1,10 @@
-# Copyright 2022-2023 Gentoo Authors
+# Copyright 2022-2024 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
+# Michał Górny <mgorny@gentoo.org> (2021-02-05)
+# LLVM slots without keywords.
+llvm_slot_15
+
 # WANG Xuerui <xen0n@gentoo.org> (2023-07-11)
 # dev-util/babeltrace fails tests on loong
 babeltrace
diff --git a/profiles/base/make.defaults b/profiles/base/make.defaults
index cb203399fa61..ba52a297a955 100644
--- a/profiles/base/make.defaults
+++ b/profiles/base/make.defaults
@@ -12,7 +12,7 @@ USE_EXPAND_VALUES_KERNEL="Darwin linux SunOS"
 
 # Env vars to expand into USE vars.  Modifying this requires prior
 # discussion on gentoo-dev@lists.gentoo.org.
-USE_EXPAND="ABI_MIPS ABI_S390 ABI_X86 ADA_TARGET ALSA_CARDS AMDGPU_TARGETS APACHE2_MODULES APACHE2_MPMS CALLIGRA_FEATURES CAMERAS COLLECTD_PLUGINS CPU_FLAGS_ARM CPU_FLAGS_PPC CPU_FLAGS_X86 CURL_SSL ELIBC FFTOOLS GPSD_PROTOCOLS GRUB_PLATFORMS INPUT_DEVICES KERNEL L10N LCD_DEVICES LIBREOFFICE_EXTENSIONS LLVM_TARGETS LUA_SINGLE_TARGET LUA_TARGETS MONKEYD_PLUGINS NGINX_MODULES_HTTP NGINX_MODULES_MAIL NGINX_MODULES_STREAM OFFICE_IMPLEMENTATION OPENMPI_FABRICS OPENMPI_OFED_FEATURES OPENMPI_RM PHP_TARGETS POSTGRES_TARGETS PYTHON_SINGLE_TARGET PYTHON_TARGETS QEMU_SOFTMMU_TARGETS QEMU_USER_TARGETS RUBY_TARGETS SANE_BACKENDS UWSGI_PLUGINS VIDEO_CARDS VOICEMAIL_STORAGE XTABLES_ADDONS"
+USE_EXPAND="ABI_MIPS ABI_S390 ABI_X86 ADA_TARGET ALSA_CARDS AMDGPU_TARGETS APACHE2_MODULES APACHE2_MPMS CALLIGRA_FEATURES CAMERAS COLLECTD_PLUGINS CPU_FLAGS_ARM CPU_FLAGS_PPC CPU_FLAGS_X86 CURL_SSL ELIBC FFTOOLS GPSD_PROTOCOLS GRUB_PLATFORMS INPUT_DEVICES KERNEL L10N LCD_DEVICES LIBREOFFICE_EXTENSIONS LLVM_SLOT LLVM_TARGETS LUA_SINGLE_TARGET LUA_TARGETS MONKEYD_PLUGINS NGINX_MODULES_HTTP NGINX_MODULES_MAIL NGINX_MODULES_STREAM OFFICE_IMPLEMENTATION OPENMPI_FABRICS OPENMPI_OFED_FEATURES OPENMPI_RM PHP_TARGETS POSTGRES_TARGETS PYTHON_SINGLE_TARGET PYTHON_TARGETS QEMU_SOFTMMU_TARGETS QEMU_USER_TARGETS RUBY_TARGETS SANE_BACKENDS UWSGI_PLUGINS VIDEO_CARDS VOICEMAIL_STORAGE XTABLES_ADDONS"
 
 # USE_EXPAND variables whose contents are not shown in package manager
 # output. Changes need discussion on gentoo-dev.
diff --git a/profiles/desc/llvm_slot.desc b/profiles/desc/llvm_slot.desc
new file mode 100644
index 000000000000..8e837d330333
--- /dev/null
+++ b/profiles/desc/llvm_slot.desc
@@ -0,0 +1,8 @@
+# Copyright 2024 Gentoo Authors.
+# Distributed under the terms of the GNU General Public License v2
+
+15 - Use LLVM 15.
+16 - Use LLVM 16.
+17 - Use LLVM 17.
+18 - Use LLVM 18.
+19 - Use LLVM 19.
diff --git a/profiles/embedded/make.defaults b/profiles/embedded/make.defaults
index 9b5c9c8f6e08..96fbd36959f5 100644
--- a/profiles/embedded/make.defaults
+++ b/profiles/embedded/make.defaults
@@ -1,4 +1,4 @@
-# Copyright 2008-2023 Gentoo Authors
+# Copyright 2008-2024 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 USE="minimal multicall zlib"
@@ -29,7 +29,7 @@ USE_EXPAND_VALUES_KERNEL="Darwin linux SunOS Winnt"
 
 # Env vars to expand into USE vars.  Modifying this requires prior
 # discussion on gentoo-dev@lists.gentoo.org.
-USE_EXPAND="ABI_MIPS ABI_S390 ABI_X86 ADA_TARGET ALSA_CARDS APACHE2_MODULES APACHE2_MPMS CALLIGRA_FEATURES CAMERAS COLLECTD_PLUGINS CPU_FLAGS_ARM CPU_FLAGS_PPC CPU_FLAGS_X86 CURL_SSL ELIBC FFTOOLS GPSD_PROTOCOLS GRUB_PLATFORMS INPUT_DEVICES KERNEL L10N LCD_DEVICES LIBREOFFICE_EXTENSIONS LLVM_TARGETS LUA_SINGLE_TARGET LUA_TARGETS MONKEYD_PLUGINS NGINX_MODULES_HTTP NGINX_MODULES_MAIL NGINX_MODULES_STREAM OFFICE_IMPLEMENTATION OPENMPI_FABRICS OPENMPI_OFED_FEATURES OPENMPI_RM PHP_TARGETS POSTGRES_TARGETS PYTHON_SINGLE_TARGET PYTHON_TARGETS QEMU_SOFTMMU_TARGETS QEMU_USER_TARGETS RUBY_TARGETS SANE_BACKENDS UWSGI_PLUGINS VIDEO_CARDS VOICEMAIL_STORAGE XTABLES_ADDONS"
+USE_EXPAND="ABI_MIPS ABI_S390 ABI_X86 ADA_TARGET ALSA_CARDS APACHE2_MODULES APACHE2_MPMS CALLIGRA_FEATURES CAMERAS COLLECTD_PLUGINS CPU_FLAGS_ARM CPU_FLAGS_PPC CPU_FLAGS_X86 CURL_SSL ELIBC FFTOOLS GPSD_PROTOCOLS GRUB_PLATFORMS INPUT_DEVICES KERNEL L10N LCD_DEVICES LIBREOFFICE_EXTENSIONS LLVM_SLOT LLVM_TARGETS LUA_SINGLE_TARGET LUA_TARGETS MONKEYD_PLUGINS NGINX_MODULES_HTTP NGINX_MODULES_MAIL NGINX_MODULES_STREAM OFFICE_IMPLEMENTATION OPENMPI_FABRICS OPENMPI_OFED_FEATURES OPENMPI_RM PHP_TARGETS POSTGRES_TARGETS PYTHON_SINGLE_TARGET PYTHON_TARGETS QEMU_SOFTMMU_TARGETS QEMU_USER_TARGETS RUBY_TARGETS SANE_BACKENDS UWSGI_PLUGINS VIDEO_CARDS VOICEMAIL_STORAGE XTABLES_ADDONS"
 
 # USE_EXPAND variables whose contents are not shown in package manager
 # output. Changes need discussion on gentoo-dev.
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH 5/8] llvm-r1.eclass: Initial version
  2024-02-07 20:11 [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess Michał Górny
                   ` (3 preceding siblings ...)
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 4/8] profiles: Introduce LLVM_SLOT USE_EXPAND variable Michał Górny
@ 2024-02-07 20:11 ` Michał Górny
  2024-02-08 19:07   ` [gentoo-dev] [PATCH v2] " Michał Górny
  2024-02-09 16:59   ` [gentoo-dev] [PATCH v3] " Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 6/8] dev-util/intel_clc: Migrate to llvm-r1 Michał Górny
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 15+ messages in thread
From: Michał Górny @ 2024-02-07 20:11 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 eclass/llvm-r1.eclass   | 226 ++++++++++++++++++++++++++++++++++++++++
 eclass/tests/llvm-r1.sh | 151 +++++++++++++++++++++++++++
 2 files changed, 377 insertions(+)
 create mode 100644 eclass/llvm-r1.eclass
 create mode 100755 eclass/tests/llvm-r1.sh

diff --git a/eclass/llvm-r1.eclass b/eclass/llvm-r1.eclass
new file mode 100644
index 000000000000..b8bd2f185bcc
--- /dev/null
+++ b/eclass/llvm-r1.eclass
@@ -0,0 +1,226 @@
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: llvm-r1.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-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 is enabled by default.
+#
+# Example:
+# @CODE
+# LLVM_COMPAT=( {16..18} )
+#
+# inherit llvm-r1
+#
+# DEPEND="
+#   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=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=17
+
+# == 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
+
+# == global metadata ==
+
+# @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
+		IUSE="+llvm_slot_${stable[-1]}"
+		unset 'stable[-1]'
+	else
+		IUSE="+llvm_slot_${unstable[-1]}"
+		unset 'unstable[-1]'
+	fi
+	local nondefault=( "${stable[@]}" "${unstable[@]}" )
+	IUSE+=" ${nondefault[*]/#/llvm_slot_}"
+
+	local flags=( "${_LLVM_SLOTS[@]/#/llvm_slot_}" )
+	REQUIRED_USE="^^ ( ${flags[*]} )"
+	local usedep_flags=${flags[*]/%/(-)?}
+	LLVM_USEDEP=${usedep_flags// /,}
+	readonly LLVM_USEDEP
+}
+_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 '
+#     sys-devel/clang:${LLVM_SLOT}
+#     sys-devel/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.  Note that this is path
+# relative to the prefix, i.e. you need to prepend ${ESYSROOT}
+# or ${BROOT} appropriately.
+#
+# 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: 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.
+llvm-r1_pkg_setup() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	if [[ ${MERGE_TYPE} != 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
+
+EXPORT_FUNCTIONS pkg_setup
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=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-r1
+
+		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 "python_get_usedep ${arg}"
+		eerror "gave:"
+		eerror "  ${value}"
+		eerror "expected:"
+		eerror "  ${expected}"
+	fi
+	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 ${?}
+}
+
+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=( {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
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH 6/8] dev-util/intel_clc: Migrate to llvm-r1
  2024-02-07 20:11 [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess Michał Górny
                   ` (4 preceding siblings ...)
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 5/8] llvm-r1.eclass: Initial version Michał Górny
@ 2024-02-07 20:11 ` Michał Górny
  2024-02-08  7:00   ` Sam James
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 7/8] media-libs/mesa: " Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 8/8] sys-devel/lld: Migrate to llvm-utils.eclass Michał Górny
  7 siblings, 1 reply; 15+ messages in thread
From: Michał Górny @ 2024-02-07 20:11 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Closes: https://bugs.gentoo.org/923228
Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 dev-util/intel_clc/intel_clc-24.0.0.ebuild | 48 ++++------------------
 dev-util/intel_clc/intel_clc-9999.ebuild   | 48 ++++------------------
 2 files changed, 18 insertions(+), 78 deletions(-)

diff --git a/dev-util/intel_clc/intel_clc-24.0.0.ebuild b/dev-util/intel_clc/intel_clc-24.0.0.ebuild
index 10dd7e930b24..adb22e32e30a 100644
--- a/dev-util/intel_clc/intel_clc-24.0.0.ebuild
+++ b/dev-util/intel_clc/intel_clc-24.0.0.ebuild
@@ -3,9 +3,10 @@
 
 EAPI=8
 
+LLVM_COMPAT=( 16 17 )
 PYTHON_COMPAT=( python3_{10..12} )
 
-inherit llvm meson python-any-r1
+inherit llvm-r1 meson python-any-r1
 
 MY_PV="${PV/_/-}"
 
@@ -31,6 +32,11 @@ RDEPEND="
 	dev-util/spirv-tools
 	>=sys-libs/zlib-1.2.8:=
 	x11-libs/libdrm
+	$(llvm_gen_dep '
+		dev-util/spirv-llvm-translator:${LLVM_SLOT}
+		sys-devel/clang:${LLVM_SLOT}
+		sys-devel/llvm:${LLVM_SLOT}
+	')
 "
 DEPEND="${RDEPEND}
 	dev-libs/expat
@@ -41,53 +47,17 @@ BDEPEND="
 	virtual/pkgconfig
 "
 
-# Please keep the LLVM dependency block separate. Since LLVM is slotted,
-# we need to *really* make sure we're not pulling one than more slot
-# simultaneously.
-#
-# How to use it:
-# 1. Specify LLVM_MAX_SLOT (inclusive), e.g. 17.
-# 2. Specify LLVM_MIN_SLOT (inclusive), e.g. 16.
-LLVM_MAX_SLOT="17"
-LLVM_MIN_SLOT="16"
-PER_SLOT_DEPSTR="
-	(
-		dev-util/spirv-llvm-translator:@SLOT@
-		sys-devel/clang:@SLOT@
-		sys-devel/llvm:@SLOT@
-	)
-"
-LLVM_DEPSTR="
-	|| (
-		$(for ((slot=LLVM_MAX_SLOT; slot>=LLVM_MIN_SLOT; slot--)); do
-			echo "${PER_SLOT_DEPSTR//@SLOT@/${slot}}"
-		done)
-	)
-	<sys-devel/clang-$((LLVM_MAX_SLOT + 1)):=
-	<sys-devel/llvm-$((LLVM_MAX_SLOT + 1)):=
-"
-RDEPEND="${RDEPEND}
-	${LLVM_DEPSTR}
-"
-unset LLVM_MIN_SLOT {LLVM,PER_SLOT}_DEPSTR
-
-llvm_check_deps() {
-	has_version "dev-util/spirv-llvm-translator:${LLVM_SLOT}" &&
-	has_version "sys-devel/clang:${LLVM_SLOT}" &&
-	has_version "sys-devel/llvm:${LLVM_SLOT}"
-}
-
 python_check_deps() {
 	python_has_version -b ">=dev-python/mako-0.8.0[${PYTHON_USEDEP}]"
 }
 
 pkg_setup() {
-	llvm_pkg_setup
+	llvm-r1_pkg_setup
 	python-any-r1_pkg_setup
 }
 
 src_configure() {
-	PKG_CONFIG_PATH="$(get_llvm_prefix "${LLVM_MAX_SLOT}")/$(get_libdir)/pkgconfig"
+	PKG_CONFIG_PATH="$(get_llvm_prefix)/$(get_libdir)/pkgconfig"
 
 	local emesonargs=(
 		-Dllvm=enabled
diff --git a/dev-util/intel_clc/intel_clc-9999.ebuild b/dev-util/intel_clc/intel_clc-9999.ebuild
index 10dd7e930b24..adb22e32e30a 100644
--- a/dev-util/intel_clc/intel_clc-9999.ebuild
+++ b/dev-util/intel_clc/intel_clc-9999.ebuild
@@ -3,9 +3,10 @@
 
 EAPI=8
 
+LLVM_COMPAT=( 16 17 )
 PYTHON_COMPAT=( python3_{10..12} )
 
-inherit llvm meson python-any-r1
+inherit llvm-r1 meson python-any-r1
 
 MY_PV="${PV/_/-}"
 
@@ -31,6 +32,11 @@ RDEPEND="
 	dev-util/spirv-tools
 	>=sys-libs/zlib-1.2.8:=
 	x11-libs/libdrm
+	$(llvm_gen_dep '
+		dev-util/spirv-llvm-translator:${LLVM_SLOT}
+		sys-devel/clang:${LLVM_SLOT}
+		sys-devel/llvm:${LLVM_SLOT}
+	')
 "
 DEPEND="${RDEPEND}
 	dev-libs/expat
@@ -41,53 +47,17 @@ BDEPEND="
 	virtual/pkgconfig
 "
 
-# Please keep the LLVM dependency block separate. Since LLVM is slotted,
-# we need to *really* make sure we're not pulling one than more slot
-# simultaneously.
-#
-# How to use it:
-# 1. Specify LLVM_MAX_SLOT (inclusive), e.g. 17.
-# 2. Specify LLVM_MIN_SLOT (inclusive), e.g. 16.
-LLVM_MAX_SLOT="17"
-LLVM_MIN_SLOT="16"
-PER_SLOT_DEPSTR="
-	(
-		dev-util/spirv-llvm-translator:@SLOT@
-		sys-devel/clang:@SLOT@
-		sys-devel/llvm:@SLOT@
-	)
-"
-LLVM_DEPSTR="
-	|| (
-		$(for ((slot=LLVM_MAX_SLOT; slot>=LLVM_MIN_SLOT; slot--)); do
-			echo "${PER_SLOT_DEPSTR//@SLOT@/${slot}}"
-		done)
-	)
-	<sys-devel/clang-$((LLVM_MAX_SLOT + 1)):=
-	<sys-devel/llvm-$((LLVM_MAX_SLOT + 1)):=
-"
-RDEPEND="${RDEPEND}
-	${LLVM_DEPSTR}
-"
-unset LLVM_MIN_SLOT {LLVM,PER_SLOT}_DEPSTR
-
-llvm_check_deps() {
-	has_version "dev-util/spirv-llvm-translator:${LLVM_SLOT}" &&
-	has_version "sys-devel/clang:${LLVM_SLOT}" &&
-	has_version "sys-devel/llvm:${LLVM_SLOT}"
-}
-
 python_check_deps() {
 	python_has_version -b ">=dev-python/mako-0.8.0[${PYTHON_USEDEP}]"
 }
 
 pkg_setup() {
-	llvm_pkg_setup
+	llvm-r1_pkg_setup
 	python-any-r1_pkg_setup
 }
 
 src_configure() {
-	PKG_CONFIG_PATH="$(get_llvm_prefix "${LLVM_MAX_SLOT}")/$(get_libdir)/pkgconfig"
+	PKG_CONFIG_PATH="$(get_llvm_prefix)/$(get_libdir)/pkgconfig"
 
 	local emesonargs=(
 		-Dllvm=enabled
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH 7/8] media-libs/mesa: Migrate to llvm-r1
  2024-02-07 20:11 [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess Michał Górny
                   ` (5 preceding siblings ...)
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 6/8] dev-util/intel_clc: Migrate to llvm-r1 Michał Górny
@ 2024-02-07 20:11 ` Michał Górny
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 8/8] sys-devel/lld: Migrate to llvm-utils.eclass Michał Górny
  7 siblings, 0 replies; 15+ messages in thread
From: Michał Górny @ 2024-02-07 20:11 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 media-libs/mesa/mesa-24.0.0.ebuild | 53 +++++++-----------------------
 media-libs/mesa/mesa-9999.ebuild   | 53 +++++++-----------------------
 2 files changed, 22 insertions(+), 84 deletions(-)

diff --git a/media-libs/mesa/mesa-24.0.0.ebuild b/media-libs/mesa/mesa-24.0.0.ebuild
index 7d7f3b5ed165..5f3a7985bdf5 100644
--- a/media-libs/mesa/mesa-24.0.0.ebuild
+++ b/media-libs/mesa/mesa-24.0.0.ebuild
@@ -3,9 +3,10 @@
 
 EAPI=8
 
+LLVM_COMPAT=( {15..17} )
 PYTHON_COMPAT=( python3_{10..12} )
 
-inherit llvm meson-multilib python-any-r1 linux-info
+inherit llvm-r1 meson-multilib python-any-r1 linux-info
 
 MY_P="${P/_/-}"
 
@@ -64,6 +65,13 @@ RDEPEND="
 	>=sys-libs/zlib-1.2.8[${MULTILIB_USEDEP}]
 	unwind? ( sys-libs/libunwind[${MULTILIB_USEDEP}] )
 	llvm? (
+		$(llvm_gen_dep "
+			sys-devel/llvm:\${LLVM_SLOT}[llvm_targets_AMDGPU(+),${MULTILIB_USEDEP}]
+			opencl? (
+				dev-util/spirv-llvm-translator:\${LLVM_SLOT}
+				sys-devel/clang:\${LLVM_SLOT}[llvm_targets_AMDGPU(+),${MULTILIB_USEDEP}]
+			)
+		")
 		video_cards_radeonsi? (
 			virtual/libelf:0=[${MULTILIB_USEDEP}]
 		)
@@ -109,37 +117,6 @@ RDEPEND="${RDEPEND}
 	video_cards_radeonsi? ( ${LIBDRM_DEPSTRING}[video_cards_amdgpu] )
 "
 
-# Please keep the LLVM dependency block separate. Since LLVM is slotted,
-# we need to *really* make sure we're not pulling one than more slot
-# simultaneously.
-#
-# How to use it:
-# 1. Specify LLVM_MAX_SLOT (inclusive), e.g. 17.
-# 2. Specify LLVM_MIN_SLOT (inclusive), e.g. 15.
-LLVM_MAX_SLOT="17"
-LLVM_MIN_SLOT="15"
-LLVM_USE_DEPS="llvm_targets_AMDGPU(+),${MULTILIB_USEDEP}"
-PER_SLOT_DEPSTR="
-	(
-		!opencl? ( sys-devel/llvm:@SLOT@[${LLVM_USE_DEPS}] )
-		opencl? ( sys-devel/clang:@SLOT@[${LLVM_USE_DEPS}] )
-		opencl? ( dev-util/spirv-llvm-translator:@SLOT@ )
-	)
-"
-LLVM_DEPSTR="
-	|| (
-		$(for ((slot=LLVM_MAX_SLOT; slot>=LLVM_MIN_SLOT; slot--)); do
-			echo "${PER_SLOT_DEPSTR//@SLOT@/${slot}}"
-		done)
-	)
-	!opencl? ( <sys-devel/llvm-$((LLVM_MAX_SLOT + 1)):=[${LLVM_USE_DEPS}] )
-	opencl? ( <sys-devel/clang-$((LLVM_MAX_SLOT + 1)):=[${LLVM_USE_DEPS}] )
-"
-RDEPEND="${RDEPEND}
-	llvm? ( ${LLVM_DEPSTR} )
-"
-unset LLVM_MIN_SLOT {LLVM,PER_SLOT}_DEPSTR
-
 DEPEND="${RDEPEND}
 	video_cards_d3d12? ( >=dev-util/directx-headers-1.611.0[${MULTILIB_USEDEP}] )
 	valgrind? ( dev-debug/valgrind )
@@ -185,14 +162,6 @@ x86? (
 	usr/lib/libGLX_mesa.so.0.0.0
 )"
 
-llvm_check_deps() {
-	if use opencl; then
-		has_version "sys-devel/clang:${LLVM_SLOT}[${LLVM_USE_DEPS}]" || return 1
-		has_version "dev-util/spirv-llvm-translator:${LLVM_SLOT}" || return 1
-	fi
-	has_version "sys-devel/llvm:${LLVM_SLOT}[${LLVM_USE_DEPS}]"
-}
-
 pkg_pretend() {
 	if use vulkan; then
 		if ! use video_cards_d3d12 &&
@@ -269,7 +238,7 @@ pkg_setup() {
 	fi
 
 	if use llvm; then
-		llvm_pkg_setup
+		llvm-r1_pkg_setup
 	fi
 	python-any-r1_pkg_setup
 }
@@ -363,7 +332,7 @@ multilib_src_configure() {
 	fi
 
 	if use llvm && use opencl; then
-		PKG_CONFIG_PATH="$(get_llvm_prefix "${LLVM_MAX_SLOT}")/$(get_libdir)/pkgconfig"
+		PKG_CONFIG_PATH="$(get_llvm_prefix)/$(get_libdir)/pkgconfig"
 		# See https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/docs/rusticl.rst
 		emesonargs+=(
 			$(meson_native_true gallium-rusticl)
diff --git a/media-libs/mesa/mesa-9999.ebuild b/media-libs/mesa/mesa-9999.ebuild
index 7d7f3b5ed165..5f3a7985bdf5 100644
--- a/media-libs/mesa/mesa-9999.ebuild
+++ b/media-libs/mesa/mesa-9999.ebuild
@@ -3,9 +3,10 @@
 
 EAPI=8
 
+LLVM_COMPAT=( {15..17} )
 PYTHON_COMPAT=( python3_{10..12} )
 
-inherit llvm meson-multilib python-any-r1 linux-info
+inherit llvm-r1 meson-multilib python-any-r1 linux-info
 
 MY_P="${P/_/-}"
 
@@ -64,6 +65,13 @@ RDEPEND="
 	>=sys-libs/zlib-1.2.8[${MULTILIB_USEDEP}]
 	unwind? ( sys-libs/libunwind[${MULTILIB_USEDEP}] )
 	llvm? (
+		$(llvm_gen_dep "
+			sys-devel/llvm:\${LLVM_SLOT}[llvm_targets_AMDGPU(+),${MULTILIB_USEDEP}]
+			opencl? (
+				dev-util/spirv-llvm-translator:\${LLVM_SLOT}
+				sys-devel/clang:\${LLVM_SLOT}[llvm_targets_AMDGPU(+),${MULTILIB_USEDEP}]
+			)
+		")
 		video_cards_radeonsi? (
 			virtual/libelf:0=[${MULTILIB_USEDEP}]
 		)
@@ -109,37 +117,6 @@ RDEPEND="${RDEPEND}
 	video_cards_radeonsi? ( ${LIBDRM_DEPSTRING}[video_cards_amdgpu] )
 "
 
-# Please keep the LLVM dependency block separate. Since LLVM is slotted,
-# we need to *really* make sure we're not pulling one than more slot
-# simultaneously.
-#
-# How to use it:
-# 1. Specify LLVM_MAX_SLOT (inclusive), e.g. 17.
-# 2. Specify LLVM_MIN_SLOT (inclusive), e.g. 15.
-LLVM_MAX_SLOT="17"
-LLVM_MIN_SLOT="15"
-LLVM_USE_DEPS="llvm_targets_AMDGPU(+),${MULTILIB_USEDEP}"
-PER_SLOT_DEPSTR="
-	(
-		!opencl? ( sys-devel/llvm:@SLOT@[${LLVM_USE_DEPS}] )
-		opencl? ( sys-devel/clang:@SLOT@[${LLVM_USE_DEPS}] )
-		opencl? ( dev-util/spirv-llvm-translator:@SLOT@ )
-	)
-"
-LLVM_DEPSTR="
-	|| (
-		$(for ((slot=LLVM_MAX_SLOT; slot>=LLVM_MIN_SLOT; slot--)); do
-			echo "${PER_SLOT_DEPSTR//@SLOT@/${slot}}"
-		done)
-	)
-	!opencl? ( <sys-devel/llvm-$((LLVM_MAX_SLOT + 1)):=[${LLVM_USE_DEPS}] )
-	opencl? ( <sys-devel/clang-$((LLVM_MAX_SLOT + 1)):=[${LLVM_USE_DEPS}] )
-"
-RDEPEND="${RDEPEND}
-	llvm? ( ${LLVM_DEPSTR} )
-"
-unset LLVM_MIN_SLOT {LLVM,PER_SLOT}_DEPSTR
-
 DEPEND="${RDEPEND}
 	video_cards_d3d12? ( >=dev-util/directx-headers-1.611.0[${MULTILIB_USEDEP}] )
 	valgrind? ( dev-debug/valgrind )
@@ -185,14 +162,6 @@ x86? (
 	usr/lib/libGLX_mesa.so.0.0.0
 )"
 
-llvm_check_deps() {
-	if use opencl; then
-		has_version "sys-devel/clang:${LLVM_SLOT}[${LLVM_USE_DEPS}]" || return 1
-		has_version "dev-util/spirv-llvm-translator:${LLVM_SLOT}" || return 1
-	fi
-	has_version "sys-devel/llvm:${LLVM_SLOT}[${LLVM_USE_DEPS}]"
-}
-
 pkg_pretend() {
 	if use vulkan; then
 		if ! use video_cards_d3d12 &&
@@ -269,7 +238,7 @@ pkg_setup() {
 	fi
 
 	if use llvm; then
-		llvm_pkg_setup
+		llvm-r1_pkg_setup
 	fi
 	python-any-r1_pkg_setup
 }
@@ -363,7 +332,7 @@ multilib_src_configure() {
 	fi
 
 	if use llvm && use opencl; then
-		PKG_CONFIG_PATH="$(get_llvm_prefix "${LLVM_MAX_SLOT}")/$(get_libdir)/pkgconfig"
+		PKG_CONFIG_PATH="$(get_llvm_prefix)/$(get_libdir)/pkgconfig"
 		# See https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/docs/rusticl.rst
 		emesonargs+=(
 			$(meson_native_true gallium-rusticl)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH 8/8] sys-devel/lld: Migrate to llvm-utils.eclass
  2024-02-07 20:11 [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess Michał Górny
                   ` (6 preceding siblings ...)
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 7/8] media-libs/mesa: " Michał Górny
@ 2024-02-07 20:11 ` Michał Górny
  7 siblings, 0 replies; 15+ messages in thread
From: Michał Górny @ 2024-02-07 20:11 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 sys-devel/lld/lld-18.1.0_rc2.ebuild         | 5 +++--
 sys-devel/lld/lld-19.0.0.9999.ebuild        | 5 +++--
 sys-devel/lld/lld-19.0.0_pre20240203.ebuild | 5 +++--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/sys-devel/lld/lld-18.1.0_rc2.ebuild b/sys-devel/lld/lld-18.1.0_rc2.ebuild
index e72385c1bdb1..db957ad1ab9a 100644
--- a/sys-devel/lld/lld-18.1.0_rc2.ebuild
+++ b/sys-devel/lld/lld-18.1.0_rc2.ebuild
@@ -4,7 +4,7 @@
 EAPI=8
 
 PYTHON_COMPAT=( python3_{10..12} )
-inherit cmake flag-o-matic llvm llvm.org python-any-r1 toolchain-funcs
+inherit cmake flag-o-matic llvm.org llvm-utils python-any-r1 toolchain-funcs
 
 DESCRIPTION="The LLVM linker (link editor)"
 HOMEPAGE="https://llvm.org/"
@@ -41,7 +41,6 @@ python_check_deps() {
 }
 
 pkg_setup() {
-	LLVM_MAX_SLOT=${LLVM_MAJOR} llvm_pkg_setup
 	use test && python-any-r1_pkg_setup
 }
 
@@ -57,6 +56,8 @@ src_unpack() {
 }
 
 src_configure() {
+	llvm_prepend_path "${LLVM_MAJOR}"
+
 	# LLVM_ENABLE_ASSERTIONS=NO does not guarantee this for us, #614844
 	use debug || local -x CPPFLAGS="${CPPFLAGS} -DNDEBUG"
 
diff --git a/sys-devel/lld/lld-19.0.0.9999.ebuild b/sys-devel/lld/lld-19.0.0.9999.ebuild
index e72385c1bdb1..db957ad1ab9a 100644
--- a/sys-devel/lld/lld-19.0.0.9999.ebuild
+++ b/sys-devel/lld/lld-19.0.0.9999.ebuild
@@ -4,7 +4,7 @@
 EAPI=8
 
 PYTHON_COMPAT=( python3_{10..12} )
-inherit cmake flag-o-matic llvm llvm.org python-any-r1 toolchain-funcs
+inherit cmake flag-o-matic llvm.org llvm-utils python-any-r1 toolchain-funcs
 
 DESCRIPTION="The LLVM linker (link editor)"
 HOMEPAGE="https://llvm.org/"
@@ -41,7 +41,6 @@ python_check_deps() {
 }
 
 pkg_setup() {
-	LLVM_MAX_SLOT=${LLVM_MAJOR} llvm_pkg_setup
 	use test && python-any-r1_pkg_setup
 }
 
@@ -57,6 +56,8 @@ src_unpack() {
 }
 
 src_configure() {
+	llvm_prepend_path "${LLVM_MAJOR}"
+
 	# LLVM_ENABLE_ASSERTIONS=NO does not guarantee this for us, #614844
 	use debug || local -x CPPFLAGS="${CPPFLAGS} -DNDEBUG"
 
diff --git a/sys-devel/lld/lld-19.0.0_pre20240203.ebuild b/sys-devel/lld/lld-19.0.0_pre20240203.ebuild
index e72385c1bdb1..db957ad1ab9a 100644
--- a/sys-devel/lld/lld-19.0.0_pre20240203.ebuild
+++ b/sys-devel/lld/lld-19.0.0_pre20240203.ebuild
@@ -4,7 +4,7 @@
 EAPI=8
 
 PYTHON_COMPAT=( python3_{10..12} )
-inherit cmake flag-o-matic llvm llvm.org python-any-r1 toolchain-funcs
+inherit cmake flag-o-matic llvm.org llvm-utils python-any-r1 toolchain-funcs
 
 DESCRIPTION="The LLVM linker (link editor)"
 HOMEPAGE="https://llvm.org/"
@@ -41,7 +41,6 @@ python_check_deps() {
 }
 
 pkg_setup() {
-	LLVM_MAX_SLOT=${LLVM_MAJOR} llvm_pkg_setup
 	use test && python-any-r1_pkg_setup
 }
 
@@ -57,6 +56,8 @@ src_unpack() {
 }
 
 src_configure() {
+	llvm_prepend_path "${LLVM_MAJOR}"
+
 	# LLVM_ENABLE_ASSERTIONS=NO does not guarantee this for us, #614844
 	use debug || local -x CPPFLAGS="${CPPFLAGS} -DNDEBUG"
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [gentoo-dev] [PATCH 6/8] dev-util/intel_clc: Migrate to llvm-r1
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 6/8] dev-util/intel_clc: Migrate to llvm-r1 Michał Górny
@ 2024-02-08  7:00   ` Sam James
  2024-02-08 12:35     ` Arsen Arsenović
  0 siblings, 1 reply; 15+ messages in thread
From: Sam James @ 2024-02-08  7:00 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny, Arsen Arsenović

[-- Attachment #1: Type: text/plain, Size: 5104 bytes --]


Michał Górny <mgorny@gentoo.org> writes:

> Closes: https://bugs.gentoo.org/923228
> Signed-off-by: Michał Górny <mgorny@gentoo.org>
> ---
>  dev-util/intel_clc/intel_clc-24.0.0.ebuild | 48 ++++------------------
>  dev-util/intel_clc/intel_clc-9999.ebuild   | 48 ++++------------------
>  2 files changed, 18 insertions(+), 78 deletions(-)

Arsen, could you verify this does solve the problem for you, just to be
sure?

>
> diff --git a/dev-util/intel_clc/intel_clc-24.0.0.ebuild b/dev-util/intel_clc/intel_clc-24.0.0.ebuild
> index 10dd7e930b24..adb22e32e30a 100644
> --- a/dev-util/intel_clc/intel_clc-24.0.0.ebuild
> +++ b/dev-util/intel_clc/intel_clc-24.0.0.ebuild
> @@ -3,9 +3,10 @@
>  
>  EAPI=8
>  
> +LLVM_COMPAT=( 16 17 )
>  PYTHON_COMPAT=( python3_{10..12} )
>  
> -inherit llvm meson python-any-r1
> +inherit llvm-r1 meson python-any-r1
>  
>  MY_PV="${PV/_/-}"
>  
> @@ -31,6 +32,11 @@ RDEPEND="
>  	dev-util/spirv-tools
>  	>=sys-libs/zlib-1.2.8:=
>  	x11-libs/libdrm
> +	$(llvm_gen_dep '
> +		dev-util/spirv-llvm-translator:${LLVM_SLOT}
> +		sys-devel/clang:${LLVM_SLOT}
> +		sys-devel/llvm:${LLVM_SLOT}
> +	')
>  "
>  DEPEND="${RDEPEND}
>  	dev-libs/expat
> @@ -41,53 +47,17 @@ BDEPEND="
>  	virtual/pkgconfig
>  "
>  
> -# Please keep the LLVM dependency block separate. Since LLVM is slotted,
> -# we need to *really* make sure we're not pulling one than more slot
> -# simultaneously.
> -#
> -# How to use it:
> -# 1. Specify LLVM_MAX_SLOT (inclusive), e.g. 17.
> -# 2. Specify LLVM_MIN_SLOT (inclusive), e.g. 16.
> -LLVM_MAX_SLOT="17"
> -LLVM_MIN_SLOT="16"
> -PER_SLOT_DEPSTR="
> -	(
> -		dev-util/spirv-llvm-translator:@SLOT@
> -		sys-devel/clang:@SLOT@
> -		sys-devel/llvm:@SLOT@
> -	)
> -"
> -LLVM_DEPSTR="
> -	|| (
> -		$(for ((slot=LLVM_MAX_SLOT; slot>=LLVM_MIN_SLOT; slot--)); do
> -			echo "${PER_SLOT_DEPSTR//@SLOT@/${slot}}"
> -		done)
> -	)
> -	<sys-devel/clang-$((LLVM_MAX_SLOT + 1)):=
> -	<sys-devel/llvm-$((LLVM_MAX_SLOT + 1)):=
> -"
> -RDEPEND="${RDEPEND}
> -	${LLVM_DEPSTR}
> -"
> -unset LLVM_MIN_SLOT {LLVM,PER_SLOT}_DEPSTR
> -
> -llvm_check_deps() {
> -	has_version "dev-util/spirv-llvm-translator:${LLVM_SLOT}" &&
> -	has_version "sys-devel/clang:${LLVM_SLOT}" &&
> -	has_version "sys-devel/llvm:${LLVM_SLOT}"
> -}
> -
>  python_check_deps() {
>  	python_has_version -b ">=dev-python/mako-0.8.0[${PYTHON_USEDEP}]"
>  }
>  
>  pkg_setup() {
> -	llvm_pkg_setup
> +	llvm-r1_pkg_setup
>  	python-any-r1_pkg_setup
>  }
>  
>  src_configure() {
> -	PKG_CONFIG_PATH="$(get_llvm_prefix "${LLVM_MAX_SLOT}")/$(get_libdir)/pkgconfig"
> +	PKG_CONFIG_PATH="$(get_llvm_prefix)/$(get_libdir)/pkgconfig"
>  
>  	local emesonargs=(
>  		-Dllvm=enabled
> diff --git a/dev-util/intel_clc/intel_clc-9999.ebuild b/dev-util/intel_clc/intel_clc-9999.ebuild
> index 10dd7e930b24..adb22e32e30a 100644
> --- a/dev-util/intel_clc/intel_clc-9999.ebuild
> +++ b/dev-util/intel_clc/intel_clc-9999.ebuild
> @@ -3,9 +3,10 @@
>  
>  EAPI=8
>  
> +LLVM_COMPAT=( 16 17 )
>  PYTHON_COMPAT=( python3_{10..12} )
>  
> -inherit llvm meson python-any-r1
> +inherit llvm-r1 meson python-any-r1
>  
>  MY_PV="${PV/_/-}"
>  
> @@ -31,6 +32,11 @@ RDEPEND="
>  	dev-util/spirv-tools
>  	>=sys-libs/zlib-1.2.8:=
>  	x11-libs/libdrm
> +	$(llvm_gen_dep '
> +		dev-util/spirv-llvm-translator:${LLVM_SLOT}
> +		sys-devel/clang:${LLVM_SLOT}
> +		sys-devel/llvm:${LLVM_SLOT}
> +	')
>  "
>  DEPEND="${RDEPEND}
>  	dev-libs/expat
> @@ -41,53 +47,17 @@ BDEPEND="
>  	virtual/pkgconfig
>  "
>  
> -# Please keep the LLVM dependency block separate. Since LLVM is slotted,
> -# we need to *really* make sure we're not pulling one than more slot
> -# simultaneously.
> -#
> -# How to use it:
> -# 1. Specify LLVM_MAX_SLOT (inclusive), e.g. 17.
> -# 2. Specify LLVM_MIN_SLOT (inclusive), e.g. 16.
> -LLVM_MAX_SLOT="17"
> -LLVM_MIN_SLOT="16"
> -PER_SLOT_DEPSTR="
> -	(
> -		dev-util/spirv-llvm-translator:@SLOT@
> -		sys-devel/clang:@SLOT@
> -		sys-devel/llvm:@SLOT@
> -	)
> -"
> -LLVM_DEPSTR="
> -	|| (
> -		$(for ((slot=LLVM_MAX_SLOT; slot>=LLVM_MIN_SLOT; slot--)); do
> -			echo "${PER_SLOT_DEPSTR//@SLOT@/${slot}}"
> -		done)
> -	)
> -	<sys-devel/clang-$((LLVM_MAX_SLOT + 1)):=
> -	<sys-devel/llvm-$((LLVM_MAX_SLOT + 1)):=
> -"
> -RDEPEND="${RDEPEND}
> -	${LLVM_DEPSTR}
> -"
> -unset LLVM_MIN_SLOT {LLVM,PER_SLOT}_DEPSTR
> -
> -llvm_check_deps() {
> -	has_version "dev-util/spirv-llvm-translator:${LLVM_SLOT}" &&
> -	has_version "sys-devel/clang:${LLVM_SLOT}" &&
> -	has_version "sys-devel/llvm:${LLVM_SLOT}"
> -}
> -
>  python_check_deps() {
>  	python_has_version -b ">=dev-python/mako-0.8.0[${PYTHON_USEDEP}]"
>  }
>  
>  pkg_setup() {
> -	llvm_pkg_setup
> +	llvm-r1_pkg_setup
>  	python-any-r1_pkg_setup
>  }
>  
>  src_configure() {
> -	PKG_CONFIG_PATH="$(get_llvm_prefix "${LLVM_MAX_SLOT}")/$(get_libdir)/pkgconfig"
> +	PKG_CONFIG_PATH="$(get_llvm_prefix)/$(get_libdir)/pkgconfig"
>  
>  	local emesonargs=(
>  		-Dllvm=enabled


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 377 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [gentoo-dev] [PATCH 6/8] dev-util/intel_clc: Migrate to llvm-r1
  2024-02-08  7:00   ` Sam James
@ 2024-02-08 12:35     ` Arsen Arsenović
  0 siblings, 0 replies; 15+ messages in thread
From: Arsen Arsenović @ 2024-02-08 12:35 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

[-- Attachment #1: Type: text/plain, Size: 585 bytes --]


Sam James <sam@gentoo.org> writes:

> Michał Górny <mgorny@gentoo.org> writes:
>
>> Closes: https://bugs.gentoo.org/923228
>> Signed-off-by: Michał Górny <mgorny@gentoo.org>
>> ---
>>  dev-util/intel_clc/intel_clc-24.0.0.ebuild | 48 ++++------------------
>>  dev-util/intel_clc/intel_clc-9999.ebuild   | 48 ++++------------------
>>  2 files changed, 18 insertions(+), 78 deletions(-)
>
> Arsen, could you verify this does solve the problem for you, just to be
> sure?

I've confirmed on the PR before seeing this email - yes, it works :-)
-- 
Arsen Arsenović

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 381 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH] llvm-utils.eclass: Fix llvm_prepend_path to avoid duplicates
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 3/8] llvm-utils.eclass: Fix llvm_prepend_path to avoid duplicates Michał Górny
@ 2024-02-08 19:06   ` Michał Górny
  0 siblings, 0 replies; 15+ messages in thread
From: Michał Górny @ 2024-02-08 19:06 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

Fix llvm_prepend_path() not to append the new path multiple times,
if the original PATH variable contained multiple LLVM directories.

Thanks to Alexander Miller who spotted it in:
https://github.com/gentoo/gentoo/pull/35196#discussion_r1480330001

Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 eclass/llvm-utils.eclass   | 10 ++++++----
 eclass/tests/llvm-utils.sh | 12 ++++++++++++
 2 files changed, 18 insertions(+), 4 deletions(-)

Changed in v2: simplified the logic, courtesy of Alexander Miller,
and added more test cases.

diff --git a/eclass/llvm-utils.eclass b/eclass/llvm-utils.eclass
index f308667e3dc2..532e609679b8 100644
--- a/eclass/llvm-utils.eclass
+++ b/eclass/llvm-utils.eclass
@@ -129,16 +129,18 @@ llvm_prepend_path() {
 	local new_path=()
 	local x added=
 
-	# prepend new path in front of the first LLVM version found
 	for x in "${split_path[@]}"; do
 		if [[ ${x} == */usr/lib/llvm/*/bin ]]; then
-			if [[ ${x} != ${llvm_path} ]]; then
+			# prepend new path in front of the first LLVM version found
+			if [[ ! ${added} ]]; then
 				new_path+=( "${llvm_path}" )
-			elif [[ ${added} && ${x} == ${llvm_path} ]]; then
+				added=1
+			fi
+			# remove duplicate copies of the same path
+			if [[ ${x} == ${llvm_path} ]]; then
 				# deduplicate
 				continue
 			fi
-			added=1
 		fi
 		new_path+=( "${x}" )
 	done
diff --git a/eclass/tests/llvm-utils.sh b/eclass/tests/llvm-utils.sh
index 5a46b25b7ad6..6fe3da3eda13 100755
--- a/eclass/tests/llvm-utils.sh
+++ b/eclass/tests/llvm-utils.sh
@@ -98,9 +98,21 @@ ESYSROOT=
 test_prepend_path 17 /usr/bin /usr/bin:/usr/lib/llvm/17/bin
 test_prepend_path 17 /usr/lib/llvm/17/bin:/usr/bin /usr/lib/llvm/17/bin:/usr/bin
 test_prepend_path 17 /usr/bin:/usr/lib/llvm/17/bin /usr/bin:/usr/lib/llvm/17/bin
+test_prepend_path 17 /usr/lib/llvm/17/bin:/usr/bin:/usr/lib/llvm/17/bin \
+	/usr/lib/llvm/17/bin:/usr/bin
+test_prepend_path 17 /usr/lib/llvm/17/bin:/usr/lib/llvm/17/bin:/usr/bin \
+	/usr/lib/llvm/17/bin:/usr/bin
+test_prepend_path 17 /usr/bin:/usr/lib/llvm/17/bin:/usr/lib/llvm/17/bin \
+	/usr/bin:/usr/lib/llvm/17/bin
 test_prepend_path 18 /usr/lib/llvm/17/bin:/usr/bin \
 	/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin:/usr/bin
 test_prepend_path 18 /usr/bin:/usr/lib/llvm/17/bin \
 	/usr/bin:/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin
+test_prepend_path 18 /usr/lib/llvm/17/bin:/usr/lib/llvm/16/bin:/usr/bin \
+	/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin:/usr/lib/llvm/16/bin:/usr/bin
+test_prepend_path 18 /usr/bin:/usr/lib/llvm/17/bin:/usr/lib/llvm/16/bin \
+	/usr/bin:/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin:/usr/lib/llvm/16/bin
+test_prepend_path 18 /usr/lib/llvm/17/bin:/usr/bin:/usr/lib/llvm/16/bin \
+	/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin:/usr/bin:/usr/lib/llvm/16/bin
 
 texit
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH v2] llvm-r1.eclass: Initial version
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 5/8] llvm-r1.eclass: Initial version Michał Górny
@ 2024-02-08 19:07   ` Michał Górny
  2024-02-09 16:59   ` [gentoo-dev] [PATCH v3] " Michał Górny
  1 sibling, 0 replies; 15+ messages in thread
From: Michał Górny @ 2024-02-08 19:07 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

See-Also: https://bugs.gentoo.org/923228
See-Also: https://bugs.gentoo.org/880671
Closes: https://bugs.gentoo.org/821955
Closes: https://bugs.gentoo.org/919150
Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 eclass/llvm-r1.eclass   | 225 ++++++++++++++++++++++++++++++++++++++++
 eclass/tests/llvm-r1.sh | 151 +++++++++++++++++++++++++++
 2 files changed, 376 insertions(+)
 create mode 100644 eclass/llvm-r1.eclass
 create mode 100755 eclass/tests/llvm-r1.sh

Changes in v2: docstring fixes.

diff --git a/eclass/llvm-r1.eclass b/eclass/llvm-r1.eclass
new file mode 100644
index 000000000000..1b520f05e981
--- /dev/null
+++ b/eclass/llvm-r1.eclass
@@ -0,0 +1,225 @@
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: llvm-r1.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-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=( {16..18} )
+#
+# inherit llvm-r1
+#
+# DEPEND="
+#   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=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=17
+
+# == 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
+
+# == global metadata ==
+
+# @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
+		IUSE="+llvm_slot_${stable[-1]}"
+		unset 'stable[-1]'
+	else
+		IUSE="+llvm_slot_${unstable[-1]}"
+		unset 'unstable[-1]'
+	fi
+	local nondefault=( "${stable[@]}" "${unstable[@]}" )
+	IUSE+=" ${nondefault[*]/#/llvm_slot_}"
+
+	local flags=( "${_LLVM_SLOTS[@]/#/llvm_slot_}" )
+	REQUIRED_USE="^^ ( ${flags[*]} )"
+	local usedep_flags=${flags[*]/%/(-)?}
+	LLVM_USEDEP=${usedep_flags// /,}
+	readonly LLVM_USEDEP
+}
+_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 '
+#     sys-devel/clang:${LLVM_SLOT}
+#     sys-devel/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: 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.
+llvm-r1_pkg_setup() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	if [[ ${MERGE_TYPE} != 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
+
+EXPORT_FUNCTIONS pkg_setup
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=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-r1
+
+		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 "python_get_usedep ${arg}"
+		eerror "gave:"
+		eerror "  ${value}"
+		eerror "expected:"
+		eerror "  ${expected}"
+	fi
+	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 ${?}
+}
+
+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=( {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
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [gentoo-dev] [PATCH v3] llvm-r1.eclass: Initial version
  2024-02-07 20:11 ` [gentoo-dev] [PATCH 5/8] llvm-r1.eclass: Initial version Michał Górny
  2024-02-08 19:07   ` [gentoo-dev] [PATCH v2] " Michał Górny
@ 2024-02-09 16:59   ` Michał Górny
  2024-02-09 23:49     ` Sam James
  1 sibling, 1 reply; 15+ messages in thread
From: Michał Górny @ 2024-02-09 16:59 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

See-Also: https://bugs.gentoo.org/923228
See-Also: https://bugs.gentoo.org/880671
Closes: https://bugs.gentoo.org/821955
Closes: https://bugs.gentoo.org/919150
Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 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ł 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-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=( {16..18} )
+#
+# inherit llvm-r1
+#
+# DEPEND="
+#   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=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=17
+
+# == 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
+		IUSE="+llvm_slot_${stable[-1]}"
+		unset 'stable[-1]'
+	else
+		IUSE="+llvm_slot_${unstable[-1]}"
+		unset 'unstable[-1]'
+	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 '
+#     sys-devel/clang:${LLVM_SLOT}
+#     sys-devel/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: 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} != 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=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-r1
+
+		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 "python_get_usedep ${arg}"
+		eerror "gave:"
+		eerror "  ${value}"
+		eerror "expected:"
+		eerror "  ${expected}"
+	fi
+	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 ${?}
+}
+
+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=( {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
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [gentoo-dev] [PATCH v3] llvm-r1.eclass: Initial version
  2024-02-09 16:59   ` [gentoo-dev] [PATCH v3] " Michał Górny
@ 2024-02-09 23:49     ` Sam James
  0 siblings, 0 replies; 15+ messages in thread
From: Sam James @ 2024-02-09 23:49 UTC (permalink / raw)
  To: gentoo-dev; +Cc: Michał Górny

[-- Attachment #1: Type: text/plain, Size: 12666 bytes --]


Michał Górny <mgorny@gentoo.org> 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ł Górny <mgorny@gentoo.org>
> ---
>  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ł 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-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=( {16..18} )
> +#
> +# inherit llvm-r1
> +#
> +# DEPEND="
> +#   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=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=17
> +
> +# == 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
> +		IUSE="+llvm_slot_${stable[-1]}"
> +		unset 'stable[-1]'
> +	else
> +		IUSE="+llvm_slot_${unstable[-1]}"
> +		unset 'unstable[-1]'
> +	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 '
> +#     sys-devel/clang:${LLVM_SLOT}
> +#     sys-devel/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: 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} != 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=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-r1
> +
> +		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 "python_get_usedep ${arg}"
> +		eerror "gave:"
> +		eerror "  ${value}"
> +		eerror "expected:"
> +		eerror "  ${expected}"
> +	fi
> +	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 ${?}
> +}
> +
> +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=( {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


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 377 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2024-02-09 23:50 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-07 20:11 [gentoo-dev] [PATCH 0/8] llvm-r1.eclass + llvm-utils.eclass: new eclasses to sort out LLVM mess Michał Górny
2024-02-07 20:11 ` [gentoo-dev] [PATCH 1/8] llvm-utils.eclass: Introduce an eclass for common helpers Michał Górny
2024-02-07 20:11 ` [gentoo-dev] [PATCH 2/8] llvm-utils.eclass: Split out PATH prepending logic Michał Górny
2024-02-07 20:11 ` [gentoo-dev] [PATCH 3/8] llvm-utils.eclass: Fix llvm_prepend_path to avoid duplicates Michał Górny
2024-02-08 19:06   ` [gentoo-dev] [PATCH] " Michał Górny
2024-02-07 20:11 ` [gentoo-dev] [PATCH 4/8] profiles: Introduce LLVM_SLOT USE_EXPAND variable Michał Górny
2024-02-07 20:11 ` [gentoo-dev] [PATCH 5/8] llvm-r1.eclass: Initial version Michał Górny
2024-02-08 19:07   ` [gentoo-dev] [PATCH v2] " Michał Górny
2024-02-09 16:59   ` [gentoo-dev] [PATCH v3] " Michał Górny
2024-02-09 23:49     ` Sam James
2024-02-07 20:11 ` [gentoo-dev] [PATCH 6/8] dev-util/intel_clc: Migrate to llvm-r1 Michał Górny
2024-02-08  7:00   ` Sam James
2024-02-08 12:35     ` Arsen Arsenović
2024-02-07 20:11 ` [gentoo-dev] [PATCH 7/8] media-libs/mesa: " Michał Górny
2024-02-07 20:11 ` [gentoo-dev] [PATCH 8/8] sys-devel/lld: Migrate to llvm-utils.eclass Michał Górny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox