public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Arsen Arsenović" <arsen@gentoo.org>
To: gentoo-dev@lists.gentoo.org
Cc: "Arsen Arsenović" <arsen@gentoo.org>
Subject: [gentoo-dev] [RFC HELP WANTED 1/9] guile-utils.eclass: new eclass, common code for guile packages
Date: Mon, 12 Aug 2024 00:22:46 +0200	[thread overview]
Message-ID: <20240811231742.942813-2-arsen@gentoo.org> (raw)
In-Reply-To: <20240811231742.942813-1-arsen@gentoo.org>

Bug: https://bugs.gentoo.org/689408
Signed-off-by: Arsen Arsenović <arsen@gentoo.org>
---
 eclass/guile-utils.eclass | 277 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 277 insertions(+)
 create mode 100644 eclass/guile-utils.eclass

diff --git a/eclass/guile-utils.eclass b/eclass/guile-utils.eclass
new file mode 100644
index 000000000000..a7cfc0cc8724
--- /dev/null
+++ b/eclass/guile-utils.eclass
@@ -0,0 +1,277 @@
+# 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>
+# Inspired by prior work in the Gentoo Python ecosystem.
+# @BLURB: Common code between GNU Guile-related eclasses and ebuilds.
+# @SUPPORTED_EAPIS: 8
+# @DESCRIPTION:
+# This eclass contains various bits of common code between
+# dev-scheme/guile, Guile multi-implementation ebuilds and Guile
+# single-implementation ebuilds.
+
+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 ! [[ $(declare -p GUILE_COMPAT) =~ 'declare -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
+# @USAGE: guile_set_common_vars
+# @VARIABLE: QA_PREBUILT
+# @DESCRIPTION:
+# Sets common variables that apply to all Guile packages, namely,
+# QA_PREBUILT.
+guile_set_common_vars() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# 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
-- 
2.45.2



  reply	other threads:[~2024-08-11 23:18 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-11 22:22 [gentoo-dev] [RFC HELP WANTED 0/9] Mending the Guile ecosystem Arsen Arsenović
2024-08-11 22:22 ` Arsen Arsenović [this message]
2024-08-11 22:22 ` [gentoo-dev] [RFC HELP WANTED 2/9] guile-single.eclass: new eclass, for single-impl guile packages Arsen Arsenović
2024-08-11 22:22 ` [gentoo-dev] [RFC HELP WANTED 3/9] guile.eclass: new eclass, for guile multi-impl packages Arsen Arsenović
2024-08-11 22:22 ` [gentoo-dev] [RFC HELP WANTED 4/9] profiles/base: add guile _TARGETS USE_EXPAND variables Arsen Arsenović
2024-08-11 22:22 ` [gentoo-dev] [RFC HELP WANTED 5/9] dev-build/make: switch to new guile mechanism Arsen Arsenović
2024-08-11 22:22 ` [gentoo-dev] [RFC HELP WANTED 6/9] dev-scheme/guile-reader: port to new guile eclasses Arsen Arsenović
2024-08-11 22:22 ` [gentoo-dev] [RFC HELP WANTED 7/9] dev-scheme/guile-commonmark: new package, add 0.1.2_pre20240803 Arsen Arsenović
2024-08-11 22:22 ` [gentoo-dev] [RFC HELP WANTED 8/9] www-apps/haunt: new package, add 0.3.0 Arsen Arsenović
2024-08-11 22:22 ` [gentoo-dev] [RFC HELP WANTED 9/9] dev-scheme/slib: add 3c1, port to new guile eclasses Arsen Arsenović
2024-08-18  9:29 ` [gentoo-dev] [RFC HELP WANTED 0/9] Mending the Guile ecosystem Sam James

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240811231742.942813-2-arsen@gentoo.org \
    --to=arsen@gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox