mirror of
https://anongit.gentoo.org/git/repo/gentoo.git
synced 2025-07-21 14:38:43 +02:00
Noticed this when looking at app-office/gnucash which was disabling
GUILE_AUTO_COMPILE entirely (see 72dbf2ec40
).
We don't want Guile making decisions based on the system cache
files. Always recompile so we're deterministic.
See https://www.gnu.org/software/guile/manual/html_node/Environment-Variables.html#index-GUILE_005fAUTO_005fCOMPILE.
Signed-off-by: Sam James <sam@gentoo.org>
280 lines
7.6 KiB
Bash
280 lines
7.6 KiB
Bash
# Copyright 2023-2024 Gentoo Authors
|
|
# Distributed under the terms of the GNU General Public License v2
|
|
|
|
# @ECLASS: guile-utils.eclass
|
|
# @MAINTAINER:
|
|
# Gentoo Scheme project <scheme@gentoo.org>
|
|
# @AUTHOR:
|
|
# Author: Arsen Arsenović <arsen@gentoo.org>
|
|
# @SUPPORTED_EAPIS: 8
|
|
# @BLURB: Common code between GNU Guile-related eclasses and ebuilds.
|
|
# @DESCRIPTION:
|
|
# This eclass contains various bits of common code between
|
|
# dev-scheme/guile, Guile multi-implementation ebuilds and Guile
|
|
# single-implementation ebuilds.
|
|
#
|
|
# Inspired by prior work in the Gentoo Python ecosystem.
|
|
|
|
case "${EAPI}" in
|
|
8) ;;
|
|
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
|
|
esac
|
|
|
|
if [[ ! "${_GUILE_UTILS_ECLASS}" ]]; then
|
|
_GUILE_UTILS_ECLASS=1
|
|
|
|
inherit toolchain-funcs
|
|
|
|
BDEPEND="virtual/pkgconfig"
|
|
|
|
# @ECLASS_VARIABLE: GUILE_COMPAT
|
|
# @REQUIRED
|
|
# @PRE_INHERIT
|
|
# @DESCRIPTION:
|
|
# List of acceptable versions of Guile. For instance, setting this
|
|
# variable like below will allow the package to be built against either
|
|
# Guile 2.2 or 3.0:
|
|
#
|
|
# @CODE
|
|
# GUILE_COMPAT=( 2-2 3-0 )
|
|
# @CODE
|
|
#
|
|
# Please keep in ascending order.
|
|
|
|
# @FUNCTION: guile_check_compat
|
|
# @DESCRIPTION:
|
|
# Checks that GUILE_COMPAT is set to an array, and has no invalid
|
|
# values.
|
|
guile_check_compat() {
|
|
debug-print-function ${FUNCNAME} "$@"
|
|
|
|
if ! [[ ${GUILE_COMPAT@a} == *a* ]]; then
|
|
die "GUILE_COMPAT not set to an array"
|
|
fi
|
|
|
|
if [[ ${#GUILE_COMPAT[@]} -eq 0 ]]; then
|
|
die "GUILE_COMPAT is empty"
|
|
fi
|
|
}
|
|
|
|
guile_check_compat
|
|
|
|
# @ECLASS_VARIABLE: GUILE_REQ_USE
|
|
# @PRE_INHERIT
|
|
# @DEFAULT_UNSET
|
|
# @DESCRIPTION:
|
|
# Specifies a USE dependency string for all versions of Guile in
|
|
# GUILE_COMPAT.
|
|
#
|
|
# @EXAMPLE:
|
|
# GUILE_REQ_USE="deprecated"
|
|
|
|
# @ECLASS_VARIABLE: GUILE_USEDEP
|
|
# @OUTPUT_VARIABLE
|
|
# @DESCRIPTION:
|
|
# This variable is populated with a USE-dependency string which can be
|
|
# used to depend on other Guile multi-implementation packages.
|
|
# This variable is not usable from guile-single packages.
|
|
|
|
# @ECLASS_VARIABLE: GUILE_DEPS
|
|
# @OUTPUT_VARIABLE
|
|
# @DESCRIPTION:
|
|
# Contains the dependency string for the compatible Guile runtimes.
|
|
|
|
# @FUNCTION: guile_set_common_vars
|
|
# @DESCRIPTION:
|
|
# Sets common variables that apply to all Guile packages, namely,
|
|
# GUILE_AUTO_COMPILE and QA_PREBUILT.
|
|
guile_set_common_vars() {
|
|
debug-print-function ${FUNCNAME} "$@"
|
|
|
|
# We don't want Guile making decisions based on the system cache
|
|
# files. Always recompile so we're deterministic.
|
|
export GUILE_AUTO_COMPILE=fresh
|
|
|
|
# These aren't strictly speaking prebuilt. but they do generated a
|
|
# nonstandard ELF object.
|
|
if [[ -z ${QA_PREBUILT} ]]; then
|
|
QA_PREBUILT="usr/$(get_libdir)/guile/*/site-ccache/*"
|
|
fi
|
|
}
|
|
|
|
# @FUNCTION: guile_filter_pkgconfig_path
|
|
# @USAGE: <acceptable slots>...
|
|
# @DESCRIPTION:
|
|
# Alters ${PKG_CONFIG_PATH} such that it does not contain any Guile
|
|
# slots besides the ones required by the caller.
|
|
guile_filter_pkgconfig_path() {
|
|
debug-print-function ${FUNCNAME} "$@"
|
|
|
|
local filtered_path= unfiltered_path path
|
|
IFS=: read -ra unfiltered_path <<<"${PKG_CONFIG_PATH}"
|
|
debug-print "Unfiltered PKG_CONFIG_PATH:" "${unfiltered_path[@]}"
|
|
for p in "${unfiltered_path[@]}"; do
|
|
for v in "$@"; do
|
|
debug-print "... considering '${p}' for ${v}"
|
|
# Exclude non-selected versions.
|
|
[[ ${p} == */usr/share/guile-data/${v}/pkgconfig* ]] \
|
|
|| continue
|
|
debug-print "... OK"
|
|
|
|
# Add separator, if some data already exists.
|
|
[[ "${filtered_path}" ]] && filtered_path+=:
|
|
|
|
filtered_path+="${p}"
|
|
break
|
|
done
|
|
done
|
|
|
|
debug-print "${FUNCNAME}: Constructed PKG_CONFIG_PATH: ${filtered_path}"
|
|
PKG_CONFIG_PATH="$filtered_path"
|
|
}
|
|
|
|
# @FUNCTION: guile_generate_depstrings
|
|
# @USAGE: <prefix> <depop>
|
|
# @DESCRIPTION:
|
|
# Generates GUILE_REQUIRED_USE/GUILE_DEPS/GUILE_USEDEP based on
|
|
# GUILE_COMPAT, and populates IUSE.
|
|
guile_generate_depstrings() {
|
|
debug-print-function ${FUNCNAME} "$@"
|
|
|
|
# Generate IUSE, REQUIRED_USE, GUILE_USEDEP
|
|
local prefix="$1" depop="$2"
|
|
GUILE_USEDEP=""
|
|
local ver uses=()
|
|
# TODO(arsen): enforce GUILE_COMPAT is in ascending order.
|
|
for ver in "${GUILE_COMPAT[@]}"; do
|
|
[[ -n ${GUILE_USEDEP} ]] && GUILE_USEDEP+=","
|
|
uses+=("${prefix}_${ver}")
|
|
GUILE_USEDEP+="${prefix}_${ver}"
|
|
done
|
|
GUILE_REQUIRED_USE="${depop} ( ${uses[@]} )"
|
|
IUSE="${uses[@]}"
|
|
debug-print "${FUNCNAME}: requse ${GUILE_REQUIRED_USE}"
|
|
debug-print "${FUNCNAME}: generated ${uses[*]}"
|
|
debug-print "${FUNCNAME}: iuse ${IUSE}"
|
|
|
|
# Generate GUILE_DEPS
|
|
local base_deps=()
|
|
local requse="${GUILE_REQ_USE+[}${GUILE_REQ_USE:-}${GUILE_REQ_USE+]}"
|
|
for ver in "${GUILE_COMPAT[@]}"; do
|
|
base_deps+="
|
|
${prefix}_${ver}? (
|
|
dev-scheme/guile:${ver/-/.}${requse}
|
|
)
|
|
"
|
|
done
|
|
GUILE_DEPS="${base_deps[*]}"
|
|
debug-print "${FUNCNAME}: GUILE_DEPS=${GUILE_DEPS}"
|
|
debug-print "${FUNCNAME}: GUILE_USEDEP=${GUILE_USEDEP}"
|
|
}
|
|
|
|
# @FUNCTION: guile_unstrip_ccache
|
|
# @DESCRIPTION:
|
|
# Marks site-ccache files not to be stripped. Operates on ${D}.
|
|
guile_unstrip_ccache() {
|
|
debug-print-function ${FUNCNAME} "$@"
|
|
|
|
local ccache
|
|
while read -r -d $'\0' ccache; do
|
|
debug-print "${FUNCNAME}: ccache found: ${ccache#.}"
|
|
dostrip -x "${ccache#.}"
|
|
done < <(cd "${ED}" || die; \
|
|
find . \
|
|
-name '*.go' \
|
|
-path "*/usr/$(get_libdir)/guile/*/site-ccache/*" \
|
|
-print0 || die) || die
|
|
}
|
|
|
|
# @FUNCTION: guile_export
|
|
# @USAGE: [GUILE|GUILD|GUILE_SITECCACHEDIR|GUILE_SITEDIR]...
|
|
# @DESCRIPTION:
|
|
# Exports a given variable for the selected Guile variant.
|
|
#
|
|
# Supported variables are:
|
|
#
|
|
# - GUILE - Path to the guile executable,
|
|
# - GUILD - Path to the guild executable,
|
|
# - GUILESNARF - Path to the guile-snarf executable
|
|
# - GUILECONFIG - Path to the guile-config executable
|
|
# - GUILE_SITECCACHEDIR - Path to the site-ccache directory,
|
|
# - GUILE_SITEDIR - Path to the site Scheme directory
|
|
guile_export() {
|
|
debug-print-function ${FUNCNAME} "$@"
|
|
|
|
local gver
|
|
if [[ "${GUILE_CURRENT_VERSION}" ]]; then
|
|
gver="${GUILE_CURRENT_VERSION}"
|
|
elif [[ "${GUILE_SELECTED_TARGET}" ]]; then
|
|
gver="${GUILE_SELECTED_TARGET}"
|
|
else
|
|
die "Calling guile_export outside of a Guile build context?"
|
|
fi
|
|
|
|
_guile_pcvar() {
|
|
local tip="Did you source /etc/profile after an update?"
|
|
$(tc-getPKG_CONFIG) --variable="$1" guile-"${gver}" \
|
|
|| die "Could not get $1 out of guile-${gver}. ${tip}"
|
|
}
|
|
|
|
for var; do
|
|
case "${var}" in
|
|
GUILE) export GUILE="$(_guile_pcvar guile)" ;;
|
|
GUILD) export GUILD="$(_guile_pcvar guild)" ;;
|
|
GUILESNARF)
|
|
GUILESNARF="${EPREFIX}/usr/bin/guile-snarf-${gver}"
|
|
export GUILESNARF
|
|
;;
|
|
GUILECONFIG)
|
|
GUILECONFIG="${EPREFIX}/usr/bin/guile-config-${gver}"
|
|
export GUILECONFIG
|
|
;;
|
|
GUILE_SITECCACHEDIR)
|
|
GUILE_SITECCACHEDIR="$(_guile_pcvar siteccachedir)"
|
|
export GUILE_SITECCACHEDIR
|
|
;;
|
|
GUILE_SITEDIR)
|
|
export GUILE_SITEDIR="$(_guile_pcvar sitedir)"
|
|
;;
|
|
*) die "Unknown variable '${var}'" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# @FUNCTION: guile_create_temporary_config
|
|
# @USAGE: <version>
|
|
# @DESCRIPTION:
|
|
# Creates a guile-config executable for a given Guile version, and
|
|
# inserts it into path.
|
|
guile_create_temporary_config() {
|
|
debug-print-function ${FUNCNAME} "$@"
|
|
|
|
[[ ${1} ]] || die "Must specify a Guile version"
|
|
|
|
local cdir="${T}/guiles/${1}/"
|
|
mkdir -p "${cdir}" || die
|
|
|
|
pushd "${cdir}" >/dev/null 2>&1 || die
|
|
cat >guile-config <<-EOF
|
|
#!/bin/sh
|
|
exec guile-config-${1} "\${@}"
|
|
EOF
|
|
chmod +x guile-config
|
|
popd >/dev/null 2>&1 || die
|
|
PATH="${cdir}:${PATH}"
|
|
}
|
|
|
|
# @FUNCTION: guile_bump_sources
|
|
# @DESCRIPTION:
|
|
# Searches over ${S} for .scm files and bumps them to avoid Guile using
|
|
# the system ccache while trying to build packages.
|
|
#
|
|
# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=38112
|
|
guile_bump_sources() {
|
|
debug-print-function ${FUNCNAME} "$@"
|
|
|
|
einfo "bumping *.scm source files..."
|
|
find "${S}" -name "*.scm" -exec touch {} + || die
|
|
}
|
|
|
|
fi # _GUILE_UTILS_ECLASS
|