Mailing List Archive

[PATCH 1/8] llvm-utils.eclass: Introduce an eclass for common helpers
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