diff options
Diffstat (limited to 'eclass')
-rw-r--r-- | eclass/Manifest.gz | bin | 39853 -> 40156 bytes | |||
-rw-r--r-- | eclass/llvm-r1.eclass | 2 | ||||
-rw-r--r-- | eclass/llvm-r2.eclass | 476 | ||||
-rw-r--r-- | eclass/llvm-utils.eclass | 27 | ||||
-rwxr-xr-x | eclass/tests/llvm-r2.sh | 188 |
5 files changed, 690 insertions, 3 deletions
diff --git a/eclass/Manifest.gz b/eclass/Manifest.gz Binary files differindex 7f6932b82420..9d162a2b9dfb 100644 --- a/eclass/Manifest.gz +++ b/eclass/Manifest.gz diff --git a/eclass/llvm-r1.eclass b/eclass/llvm-r1.eclass index 7326e3a6b271..e59bd9c317b9 100644 --- a/eclass/llvm-r1.eclass +++ b/eclass/llvm-r1.eclass @@ -14,8 +14,10 @@ # in a matching slot. To use the eclass: # # 1. Set LLVM_COMPAT to the list of supported LLVM slots. +# # 2. Use llvm_gen_dep and/or LLVM_USEDEP to add appropriate # dependencies. +# # 3. Use llvm-r1_pkg_setup, get_llvm_prefix or LLVM_SLOT. # # The eclass sets IUSE and REQUIRED_USE. The flag corresponding diff --git a/eclass/llvm-r2.eclass b/eclass/llvm-r2.eclass new file mode 100644 index 000000000000..4dda9aedc7c6 --- /dev/null +++ b/eclass/llvm-r2.eclass @@ -0,0 +1,476 @@ +# Copyright 2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: llvm-r2.eclass +# @MAINTAINER: +# Michał Górny <mgorny@gentoo.org> +# @AUTHOR: +# Michał Górny <mgorny@gentoo.org> +# @SUPPORTED_EAPIS: 8 +# @PROVIDES: llvm-utils +# @BLURB: Provide LLVM_SLOT to build against slotted LLVM +# @DESCRIPTION: +# An eclass to reliably depend on a set of LLVM-related packages +# in a matching slot. To use the eclass: +# +# 1. Set LLVM_COMPAT to the list of supported LLVM slots. +# +# 2. Use llvm_gen_dep and/or LLVM_USEDEP to add appropriate +# dependencies. +# +# 3. Use llvm-r2_pkg_setup, llvm_chost_setup, llvm_cbuild_setup, +# get_llvm_prefix or LLVM_SLOT. +# +# The eclass sets IUSE and REQUIRED_USE. The flag corresponding +# to the newest supported stable LLVM slot (or the newest testing, +# if no stable slots are supported) is enabled by default. +# +# Note that the eclass aims for a best-effort support of CHOST builds +# (i.e. compiling/linking against LLVM) and CBUILD use (i.e. calling +# LLVM tools at build time). You need to determine what the package +# in question needs, and put the appropriate packages in DEPEND and/or +# BDEPEND appropriately. +# +# Example: +# @CODE +# LLVM_COMPAT=( {16..18} ) +# +# inherit llvm-r2 +# +# DEPEND=" +# dev-libs/libfoo[${LLVM_USEDEP}] +# $(llvm_gen_dep ' +# llvm-core/clang:${LLVM_SLOT}= +# llvm-core/llvm:${LLVM_SLOT}= +# ') +# " +# @CODE + +case ${EAPI} in + 8) ;; + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; +esac + +if [[ -z ${_LLVM_R2_ECLASS} ]]; then +_LLVM_R2_ECLASS=1 + +inherit llvm-utils + +# == internal control knobs == + +# @ECLASS_VARIABLE: _LLVM_OLDEST_SLOT +# @INTERNAL +# @DESCRIPTION: +# Oldest supported LLVM slot. This is used to automatically filter out +# unsupported LLVM_COMPAT values. +_LLVM_OLDEST_SLOT=15 + +# @ECLASS_VARIABLE: _LLVM_NEWEST_STABLE +# @INTERNAL +# @DESCRIPTION: +# The newest stable LLVM version. Versions newer than that won't +# be automatically enabled via USE defaults. +_LLVM_NEWEST_STABLE=19 + +# == control variables == + +# @ECLASS_VARIABLE: LLVM_COMPAT +# @PRE_INHERIT +# @REQUIRED +# @DESCRIPTION: +# A list of LLVM slots supported by the package, oldest to newest. +# +# Example: +# @CODE +# LLVM_COMPAT=( {15..17} ) +# @CODE + +# @ECLASS_VARIABLE: LLVM_OPTIONAL +# @PRE_INHERIT +# @DEFAULT_UNSET +# @DESCRIPTION: +# If set to a non-empty value, disables setting REQUIRED_USE +# and exporting pkg_setup. You have to add LLVM_REQUIRED_USE and call +# pkg_setup manually, with appropriate USE conditions. + +# == global metadata == + +# @ECLASS_VARIABLE: LLVM_REQUIRED_USE +# @OUTPUT_VARIABLE +# @DESCRIPTION: +# An eclass-generated REQUIRED_USE string that enforces selecting +# exactly one slot. It LLVM_OPTIONAL is set, it needs to be copied +# into REQUIRED_USE, under appropriate USE conditions. Otherwise, +# it is added automatically. + +# @ECLASS_VARIABLE: LLVM_USEDEP +# @OUTPUT_VARIABLE +# @DESCRIPTION: +# An eclass-generated USE dependency string that can be applied to other +# packages using the same eclass, to enforce a LLVM slot match. + +_llvm_set_globals() { + debug-print-function ${FUNCNAME} "$@" + + if [[ ${LLVM_COMPAT@a} != *a* ]]; then + die "LLVM_COMPAT must be set to an array before inheriting ${ECLASS}" + fi + + local stable=() unstable=() + local x + for x in "${LLVM_COMPAT[@]}"; do + if [[ ${x} -gt ${_LLVM_NEWEST_STABLE} ]]; then + unstable+=( "${x}" ) + elif [[ ${x} -ge ${_LLVM_OLDEST_SLOT} ]]; then + stable+=( "${x}" ) + fi + done + + _LLVM_SLOTS=( "${stable[@]}" "${unstable[@]}" ) + if [[ ! ${_LLVM_SLOTS[@]} ]]; then + die "LLVM_COMPAT does not contain any valid versions (all older than ${_LLVM_OLDEST_SLOT}?)" + fi + + if [[ ${stable[@]} ]]; then + # If there is at least one stable slot supported, then enable + # the newest stable slot by default. + IUSE="+llvm_slot_${stable[-1]}" + unset 'stable[-1]' + else + # Otherwise, enable the "oldest" ~arch slot. We really only + # expect a single ~arch version, so this primarily prevents + # defaulting to non-keyworded slots. + IUSE="+llvm_slot_${unstable[0]}" + unset 'unstable[0]' + fi + local nondefault=( "${stable[@]}" "${unstable[@]}" ) + IUSE+=" ${nondefault[*]/#/llvm_slot_}" + + local flags=( "${_LLVM_SLOTS[@]/#/llvm_slot_}" ) + LLVM_REQUIRED_USE="^^ ( ${flags[*]} )" + local usedep_flags=${flags[*]/%/(-)?} + LLVM_USEDEP=${usedep_flags// /,} + readonly LLVM_REQUIRED_USE LLVM_USEDEP + + if [[ ! ${LLVM_OPTIONAL} ]]; then + REQUIRED_USE=${LLVM_REQUIRED_USE} + fi +} +_llvm_set_globals +unset -f _llvm_set_globals + +# == metadata helpers == + +# @FUNCTION: llvm_gen_dep +# @USAGE: <dependency> +# @DESCRIPTION: +# Output a dependency block, repeating "<dependency>" conditionally +# to all llvm_slot_* USE flags. Any occurences of '${LLVM_SLOT}' +# within the block will be substituted for the respective slot. +# +# Example: +# @CODE +# DEPEND=" +# $(llvm_gen_dep ' +# llvm-core/clang:${LLVM_SLOT}= +# llvm-core/llvm:${LLVM_SLOT}= +# ') +# " +# @CODE +llvm_gen_dep() { + debug-print-function ${FUNCNAME} "$@" + + [[ ${#} -ne 1 ]] && die "Usage: ${FUNCNAME} <dependency>" + + local dep=${1} + + local slot + for slot in "${_LLVM_SLOTS[@]}"; do + echo "llvm_slot_${slot}? ( ${dep//\$\{LLVM_SLOT\}/${slot}} )" + done +} + +# == ebuild helpers == + +# @FUNCTION: get_llvm_prefix +# @USAGE: [-b|-d] +# @DESCRIPTION: +# Output the path to the selected LLVM slot. +# +# With no option or "-d", the path is prefixed by ESYSROOT. LLVM +# dependencies should be in DEPEND then. +# +# With "-b" option, the path is prefixed by BROOT. LLVM dependencies +# should be in BDEPEND then. +get_llvm_prefix() { + debug-print-function ${FUNCNAME} "$@" + + [[ ${#} -gt 1 ]] && die "Usage: ${FUNCNAME} [-b|-d]" + + local prefix + case ${1--d} in + -d) + prefix=${ESYSROOT} + ;; + -b) + prefix=${BROOT} + ;; + *) + die "${FUNCNAME}: invalid option: ${1}" + ;; + esac + + echo "${prefix}/usr/lib/llvm/${LLVM_SLOT}" +} + +# @FUNCTION: generate_llvm_config +# @DESCRIPTION: +# Output a llvm-config compatible script that yields paths specific +# to the requested LLVM version. +generate_llvm_config() { + debug-print-function ${FUNCNAME} "$@" + + local bindir=$(get_llvm_prefix -b)/bin + [[ ! -d ${bindir} ]] && bindir= + + local prefix=$(get_llvm_prefix -d) + local includedir=${prefix}/include + local libdir=${prefix}/$(get_libdir) + local cmake_conf=${libdir}/cmake/llvm/LLVMConfig.cmake + if [[ ! -f ${cmake_conf} ]]; then + cat <<-EOF + #!/usr/bin/env sh + echo "LLVM ${LLVM_SLOT} not installed for ABI=${ABI}" >&2 + exit 127 + EOF + return + fi + + local version=$( + sed -ne 's:set(LLVM_PACKAGE_VERSION \(.*\)):\1:p' "${cmake_conf}" || die + ) + [[ -n ${version} ]] || die + local cppdefs=$( + sed -ne 's:set(LLVM_DEFINITIONS "\(.*\)"):\1:p' "${cmake_conf}" || die + ) + [[ -n ${cppdefs} ]] || die + local targets=$( + sed -ne 's:set(LLVM_TARGETS_TO_BUILD \(.*\)):\1:p' "${cmake_conf}" || die + ) + [[ -n ${targets} ]] || die + local libs=$( + sed -ne 's:set(LLVM_AVAILABLE_LIBS \(.*\)):\1:p' "${cmake_conf}" || die + ) + [[ -n ${libs} ]] || die + local target_triple=$( + sed -ne 's:set(LLVM_TARGET_TRIPLE "\(.*\)"):\1:p' "${cmake_conf}" || die + ) + [[ -n ${target_triple} ]] || die + + readarray -d';' -t targets <<<"${targets}" + readarray -d';' -t libs <<<"${libs}" + # easier than parsing CMake booleans + local assertions=OFF + [[ ${cppdefs} == *-D_DEBUG* ]] && assertions=ON + # major + suffix + local shlib_name=LLVM-${version%%.*} + [[ ${version} == *git* ]] && shlib_name+="git${version##*git}" + + local components=( + "${libs[@]#LLVM}" "${targets[@]}" + # special component groups (grep for add_llvm_component_group) + all all-targets engine native nativecodegen + ) + + cat <<-EOF + #!/usr/bin/env sh + + echo "\${0} \${*}" >> "${T}/llvm-config-calls.txt" + + do_echo() { + echo " \${*}" >> "${T}/llvm-config-calls.txt" + echo "\${@}" + } + + for arg; do + case \${arg} in + --assertion-mode) + do_echo "${assertions}" + ;; + --bindir) + if [ -n "${bindir}" ]; then + do_echo "${bindir}" + else + do_echo "CBUILD LLVM not available" >&2 + exit 1 + fi + ;; + --build-mode) + do_echo RelWithDebInfo + ;; + --build-system) + do_echo cmake + ;; + --cflags|--cppflags) + do_echo "-I${includedir} ${cppdefs[*]}" + ;; + --cmakedir) + do_echo "${libdir}/cmake/llvm" + ;; + --components) + do_echo "${components[*],,}" + ;; + --cxxflags) + do_echo "-I${includedir} -std=c++17 ${cppdefs[*]}" + ;; + --has-rtti) + do_echo YES + ;; + --host-target) + do_echo "${target_triple}" + ;; + --ignore-libllvm) + # ignored + ;; + --includedir) + do_echo "${includedir}" + ;; + --ldflags) + do_echo "-L${libdir}" + ;; + --libdir) + do_echo "${libdir}" + ;; + --libfiles) + do_echo "${libdir}/lib${shlib_name}.so" + ;; + --libnames) + do_echo lib${shlib_name}.so + ;; + --libs) + do_echo "-l${shlib_name}" + ;; + --link-shared|--link-static) + # ignored + ;; + --obj-root|--prefix) + do_echo "${prefix}" + ;; + --shared-mode) + do_echo shared + ;; + --system-libs) + do_echo + ;; + --targets-built) + do_echo "${targets[*]}" + ;; + --version) + do_echo "${version}" + ;; + -*) + do_echo "Unsupported option: \${arg}" >&2 + exit 1 + ;; + *) + # ignore components, we always return the dylib + ;; + esac + done + EOF +} +# @FUNCTION: llvm_cbuild_setup +# @DESCRIPTION: +# Prepend the PATH for selected LLVM version in CBUILD. +# +# This function is meant to be used when the package in question uses +# LLVM tools at build time. It is called automatically +# by llvm-r2_pkg_setup if LLVM is found installed in BROOT. +# +# Note that llvm-config from this path must not be used to build against +# LLVM, as that will break cross-compilation. +llvm_cbuild_setup() { + debug-print-function ${FUNCNAME} "$@" + + local broot_prefix=$(get_llvm_prefix -b) + einfo "Using ${broot_prefix} for CBUILD LLVM ${LLVM_SLOT}" + [[ -d ${broot_prefix}/bin ]] || + die "LLVM ${LLVM_SLOT} not found installed in BROOT (expected: ${broot_prefix}/bin)" + + llvm_fix_clang_version CC CPP CXX + # keep in sync with profiles/features/llvm/make.defaults! + llvm_fix_tool_path ADDR2LINE AR AS LD NM OBJCOPY OBJDUMP RANLIB + llvm_fix_tool_path READELF STRINGS STRIP + llvm_prepend_path -b "${LLVM_SLOT}" +} + +# @FUNCTION: llvm_chost_setup +# @DESCRIPTION: +# Set the environment for finding selected LLVM slot installed +# for CHOST. Create llvm-config wrappers to satisfy legacy lookups. +# +# This function is meant to be used when the package in question uses +# LLVM compiles against and links to LLVM. It is called automatically +# by llvm-r2_pkg_setup if LLVM is found installed in ESYSROOT. +# +# Note that the generated llvm-config may refer to CBUILD installation +# of LLVM via --bindir, if it is found available. +llvm_chost_setup() { + debug-print-function ${FUNCNAME} "$@" + + local esysroot_prefix=$(get_llvm_prefix -d) + einfo "Using ${esysroot_prefix} for CHOST LLVM ${LLVM_SLOT}" + [[ -d ${esysroot_prefix} ]] || + die "LLVM ${LLVM_SLOT} not found installed in ESYSROOT (expected: ${esysroot_prefix})" + + # satisfies find_package() in CMake + export LLVM_ROOT="${esysroot_prefix}" + export Clang_ROOT="${esysroot_prefix}" + export LLD_ROOT="${esysroot_prefix}" + export MLIR_ROOT="${esysroot_prefix}" + export Polly_ROOT="${esysroot_prefix}" + + # satisfies llvm-config calls, e.g. from meson + export PATH="${T}/llvm-bin:${PATH}" + mkdir "${T}"/llvm-bin || die + # we need to generate it per-ABI, since libdir changes + local ABI + for ABI in $(get_all_abis); do + local path="${T}/llvm-bin/$(get_abi_CHOST)-llvm-config" + generate_llvm_config > "${path}" || die + chmod +x "${path}" || die + done + ln -s "$(get_abi_CHOST)-llvm-config" "${T}/llvm-bin/llvm-config" || die +} + +# @FUNCTION: llvm-r2_pkg_setup +# @DESCRIPTION: +# Handle all supported setup actions automatically. If LLVM is found +# installed for CBUILD, call llvm_cbuild_setup. If it is found +# installed for CHOST, call llvm_chost_setup. +# +# This function is a no-op when installing a binary package. +# +# Note that this function is not exported if LLVM_OPTIONAL is set. +# In that case, it needs to be called manually. +llvm-r2_pkg_setup() { + debug-print-function ${FUNCNAME} "$@" + + if [[ ${MERGE_TYPE} != binary ]]; then + [[ -z ${LLVM_SLOT} ]] && die "LLVM_SLOT unset (broken USE_EXPAND?)" + + if [[ -d $(get_llvm_prefix -b)/bin ]]; then + llvm_cbuild_setup + fi + + if [[ -d $(get_llvm_prefix -d) ]]; then + llvm_chost_setup + fi + fi +} + +fi + +if [[ ! ${LLVM_OPTIONAL} ]]; then + EXPORT_FUNCTIONS pkg_setup +fi diff --git a/eclass/llvm-utils.eclass b/eclass/llvm-utils.eclass index 1ae3295484c8..b105e169fbc4 100644 --- a/eclass/llvm-utils.eclass +++ b/eclass/llvm-utils.eclass @@ -113,17 +113,38 @@ llvm_fix_tool_path() { } # @FUNCTION: llvm_prepend_path -# @USAGE: <slot> +# @USAGE: [-b|-d] <slot> # @DESCRIPTION: # Prepend the path to the specified LLVM slot to PATH variable, # and reexport it. +# +# With no option or "-d", the path is prefixed by ESYSROOT. LLVM +# dependencies should be in DEPEND then. +# +# With "-b" option, the path is prefixed by BROOT. LLVM dependencies +# should be in BDEPEND then. llvm_prepend_path() { debug-print-function ${FUNCNAME} "$@" - [[ ${#} -ne 1 ]] && die "Usage: ${FUNCNAME} <slot>" + local prefix + case ${1--d} in + -d) + prefix=${ESYSROOT} + shift + ;; + -b) + prefix=${BROOT} + shift + ;; + -*) + die "${FUNCNAME}: invalid option: ${1}" + ;; + esac + + [[ ${#} -ne 1 ]] && die "Usage: ${FUNCNAME} [-b|-d] <slot>" local slot=${1} - local llvm_path=${ESYSROOT}/usr/lib/llvm/${slot}/bin + local llvm_path=${prefix}/usr/lib/llvm/${slot}/bin local IFS=: local split_path=( ${PATH} ) local new_path=() diff --git a/eclass/tests/llvm-r2.sh b/eclass/tests/llvm-r2.sh new file mode 100755 index 000000000000..fde76d2d682e --- /dev/null +++ b/eclass/tests/llvm-r2.sh @@ -0,0 +1,188 @@ +#!/bin/bash +# Copyright 2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +source tests-common.sh || exit + +EAPI=8 + +test_globals() { + local compat=${1} + local expected_iuse=${2} + local expected_required_use=${3} + local expected_usedep=${4} + local x + + tbegin "LLVM_COMPAT=( ${compat} )" + + ( + local fail=0 + local LLVM_COMPAT=( ${compat} ) + + inherit llvm-r2 + + if [[ ${IUSE%% } != ${expected_iuse} ]]; then + eerror " IUSE: ${IUSE%% }" + eerror "does not match: ${expected_iuse}" + fail=1 + fi + + if [[ ${REQUIRED_USE} != ${expected_required_use} ]]; then + eerror " REQUIRED_USE: ${REQUIRED_USE}" + eerror "does not match: ${expected_required_use}" + fail=1 + fi + + if [[ ${LLVM_USEDEP} != ${expected_usedep} ]]; then + eerror " LLVM_USEDEP: ${LLVM_USEDEP}" + eerror "does not match: ${expected_usedep}" + fail=1 + fi + + exit "${fail}" + ) + + tend "${?}" +} + +test_gen_dep() { + local arg=${1} + local expected + read -r -d '' expected + + tbegin "llvm_gen_dep ${arg}" + local value=$(llvm_gen_dep "${arg}") + + if [[ ${value} != ${expected} ]]; then + eerror "llvm_gen_dep ${arg}" + eerror "gave:" + eerror " ${value}" + eerror "expected:" + eerror " ${expected}" + fi + tend ${?} +} + +LLVM_CONFIG_OPTIONS=( + --assertion-mode + --bindir + --build-mode + --build-system + --cflags + --cmakedir + --components + --cppflags + --cxxflags + --has-rtti + --host-target + --ignore-libllvm + --includedir + --ldflags + --libdir + --libfiles + --libnames + --libs + --link-shared + --link-static + --obj-root + --prefix + --shared-mode + --system-libs + --targets-built + --version +) + +normalize_list() { + "${@}" | + sed -e 's:\s\+:\n:g' | + sed -e '/^$/d' | + sort + local ps=${PIPESTATUS[*]} + [[ ${ps} == '0 0 0 0' ]] || die "normalize_list pipe failed: ${ps}" +} + +test_llvm_config() { + einfo "llvm-config for slot ${LLVM_SLOT}, libdir ${LLVM_LIBDIR}" + eindent + + generate_llvm_config > "${TMP}/llvm-config" || die + local triple=$(sh "${TMP}/llvm-config" --host-target || die) + local llvm_config=/usr/lib/llvm/${LLVM_SLOT}/bin/${triple}-llvm-config + + local option res + for option in "${LLVM_CONFIG_OPTIONS[@]}"; do + tbegin "${option}" + + normalize_list sh "${TMP}/llvm-config" "${option}" > "${TMP}/our" + normalize_list "${llvm_config}" "${option}" > "${TMP}/upstream" + case ${option} in + --components) + # our components are a superset of what llvm-config yields + res=$(comm -13 "${TMP}/our" "${TMP}/upstream") + ;; + *) + # expect all elements to match + res=$(comm -3 "${TMP}/our" "${TMP}/upstream") + ;; + esac + + if [[ -z ${res} ]]; then + tend 0 + else + eerror "$(diff -u "${TMP}/our" "${TMP}/upstream")" + tend 1 + fi + done + + eoutdent +} + +# full range +test_globals '14 15 16 17 18 19' \ + "+llvm_slot_19 llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18" \ + "^^ ( llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18 llvm_slot_19 )" \ + "llvm_slot_15(-)?,llvm_slot_16(-)?,llvm_slot_17(-)?,llvm_slot_18(-)?,llvm_slot_19(-)?" +test_globals '14 15 16 17 18' \ + "+llvm_slot_18 llvm_slot_15 llvm_slot_16 llvm_slot_17" \ + "^^ ( llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18 )" \ + "llvm_slot_15(-)?,llvm_slot_16(-)?,llvm_slot_17(-)?,llvm_slot_18(-)?" +# older than stable +test_globals '14 15 16' \ + "+llvm_slot_16 llvm_slot_15" \ + "^^ ( llvm_slot_15 llvm_slot_16 )" \ + "llvm_slot_15(-)?,llvm_slot_16(-)?" +# old + newer than current stable +test_globals '15 20' \ + "+llvm_slot_15 llvm_slot_20" \ + "^^ ( llvm_slot_15 llvm_slot_20 )" \ + "llvm_slot_15(-)?,llvm_slot_20(-)?" +# newer than current stable +test_globals '19' \ + "+llvm_slot_19" \ + "^^ ( llvm_slot_19 )" \ + "llvm_slot_19(-)?" + +LLVM_COMPAT=( {14..18} ) +inherit llvm-r2 + +test_gen_dep 'llvm-core/llvm:${LLVM_SLOT} llvm-core/clang:${LLVM_SLOT}' <<-EOF + llvm_slot_15? ( llvm-core/llvm:15 llvm-core/clang:15 ) + llvm_slot_16? ( llvm-core/llvm:16 llvm-core/clang:16 ) + llvm_slot_17? ( llvm-core/llvm:17 llvm-core/clang:17 ) + llvm_slot_18? ( llvm-core/llvm:18 llvm-core/clang:18 ) +EOF + +TMP=$(mktemp -d || die) +trap 'rm -rf \"${TMP}\"' EXIT +get_libdir() { echo "${LLVM_LIBDIR}"; } + +for installed_llvm_cmake in /usr/lib/llvm/*/lib*/cmake; do + installed_llvm_libdir=${installed_llvm_cmake%/*} + LLVM_LIBDIR=${installed_llvm_libdir##*/} + installed_llvm=${installed_llvm_libdir%/*} + LLVM_SLOT=${installed_llvm##*/} + + test_llvm_config +done + +texit |