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>
This commit is contained in:
Michał Górny
2024-02-07 17:34:34 +01:00
parent 5d1f99c854
commit 511ce42e90
3 changed files with 200 additions and 89 deletions

115
eclass/llvm-utils.eclass Normal file
View File

@@ -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

View File

@@ -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

82
eclass/tests/llvm-utils.sh Executable file
View File

@@ -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