commit:     6c869809927d3b3d35be224dd8dfe5c8aba490ee
Author:     Marek Szuba <marecki <AT> gentoo <DOT> org>
AuthorDate: Wed Sep 30 16:03:54 2020 +0000
Commit:     Marek Szuba <marecki <AT> gentoo <DOT> org>
CommitDate: Mon Oct  5 12:14:12 2020 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=6c869809

lua-single.eclass: new eclass for single-implementation Lua ebuilds

With many thanks to Michał Górny and other authors of
python-single-r1.eclass.

Signed-off-by: Marek Szuba <marecki <AT> gentoo.org>

 eclass/lua-single.eclass | 510 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 510 insertions(+)

diff --git a/eclass/lua-single.eclass b/eclass/lua-single.eclass
new file mode 100644
index 00000000000..2233fdd33b6
--- /dev/null
+++ b/eclass/lua-single.eclass
@@ -0,0 +1,510 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: lua-single.eclass
+# @MAINTAINER:
+# William Hubbs <willi...@gentoo.org>
+# Marek Szuba <mare...@gentoo.org>
+# @AUTHOR:
+# Marek Szuba <mare...@gentoo.org>
+# Based on python-single-r1.eclass by Michał Górny <mgo...@gentoo.org> et al.
+# @SUPPORTED_EAPIS: 7
+# @BLURB: An eclass for Lua packages not installed for multiple 
implementations.
+# @DESCRIPTION:
+# An extension of lua.eclass suite for packages which don't support being
+# installed for multiple Lua implementations. This mostly includes software
+# embedding Lua.
+#
+# This eclass sets correct IUSE.  It also provides LUA_DEPS
+# and LUA_REQUIRED_USE that need to be added to appropriate ebuild
+# metadata variables.
+#
+# The eclass exports LUA_SINGLE_USEDEP that is suitable for depending
+# on other packages using the eclass.  Dependencies on packages using
+# lua.eclass should be created via lua_gen_cond_dep() function, using
+# LUA_USEDEP placeholder.
+#
+# Please note that packages support multiple Lua implementations
+# (using lua.eclass) cannot depend on packages not supporting
+# them (using this eclass).
+#
+# Note that since this eclass always inherits lua-utils as well, in ebuilds
+# using the former there is no need to explicitly inherit the latter in order
+# to use helper functions such as lua_get_CFLAGS.
+
+case ${EAPI:-0} in
+       0|1|2|3|4|5|6)
+               die "Unsupported EAPI=${EAPI} (too old) for ${ECLASS}"
+               ;;
+       7)
+               ;;
+       *)
+               die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
+               ;;
+esac
+
+if [[ ! ${_LUA_SINGLE_R0} ]]; then
+
+if [[ ${_LUA_R0} ]]; then
+       die 'lua-single.eclass cannot be used with lua.eclass.'
+fi
+
+inherit lua-utils
+
+fi
+
+EXPORT_FUNCTIONS pkg_setup
+
+# @ECLASS-VARIABLE: LUA_COMPAT
+# @REQUIRED
+# @PRE_INHERIT
+# @DESCRIPTION:
+# This variable contains a list of Lua implementations the package
+# supports. It must be set before the `inherit' call. It has to be
+# an array.
+#
+# Example:
+# @CODE
+# LUA_COMPAT=( lua5-1 lua5-2 lua5-3 )
+# @CODE
+#
+# Please note that you can also use bash brace expansion if you like:
+# @CODE
+# LUA_COMPAT=( lua5-{1..3} )
+# @CODE
+
+# @ECLASS-VARIABLE: LUA_COMPAT_OVERRIDE
+# @USER_VARIABLE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# This variable can be used when working with ebuilds to override
+# the in-ebuild LUA_COMPAT. It is a string listing all
+# the implementations which package will be built for. It need be
+# specified in the calling environment, and not in ebuilds.
+#
+# It should be noted that in order to preserve metadata immutability,
+# LUA_COMPAT_OVERRIDE does not affect IUSE nor dependencies.
+# The state of LUA_TARGETS is ignored, and all the implementations
+# in LUA_COMPAT_OVERRIDE are built. Dependencies need to be satisfied
+# manually.
+#
+# Example:
+# @CODE
+# LUA_COMPAT_OVERRIDE='lua5-2' emerge -1v dev-lua/foo
+# @CODE
+
+# @ECLASS-VARIABLE: LUA_REQ_USE
+# @DEFAULT_UNSET
+# @PRE_INHERIT
+# @DESCRIPTION:
+# The list of USE flags required to be enabled on the chosen Lua
+# implementations, formed as a USE-dependency string. It should be valid
+# for all implementations in LUA_COMPAT, so it may be necessary to
+# use USE defaults.
+# This must be set before calling `inherit'.
+#
+# Example:
+# @CODE
+# LUA_REQ_USE="deprecated"
+# @CODE
+#
+# It will cause the Lua dependencies to look like:
+# @CODE
+# lua_targets_luaX-Y? ( dev-lang/lua:X.Y[deprecated] )
+# @CODE
+
+# @ECLASS-VARIABLE: LUA_DEPS
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# This is an eclass-generated Lua dependency string for all
+# implementations listed in LUA_COMPAT.
+#
+# Example use:
+# @CODE
+# RDEPEND="${LUA_DEPS}
+#   dev-foo/mydep"
+# DEPEND="${RDEPEND}"
+# @CODE
+#
+# Example value:
+# @CODE
+# lua_targets_lua5-1? ( dev-lang/lua:5.1 )
+# lua_targets_lua5-2? ( dev-lang/lua:5.2 )
+# @CODE
+
+# @ECLASS-VARIABLE: LUA_REQUIRED_USE
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# This is an eclass-generated required-use expression which ensures at
+# least one Lua implementation has been enabled.
+#
+# This expression should be utilized in an ebuild by including it in
+# REQUIRED_USE, optionally behind a use flag.
+#
+# Example use:
+# @CODE
+# REQUIRED_USE="lua? ( ${LUA_REQUIRED_USE} )"
+# @CODE
+#
+# Example value:
+# @CODE
+# || ( lua_targets_lua5-1 lua_targets_lua5-2 )
+# @CODE
+
+# @ECLASS-VARIABLE: LUA_SINGLE_USEDEP
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# This is an eclass-generated USE-dependency string which can be used
+# to depend on another lua-single package being built for the same
+# Lua implementations.
+#
+# If you need to depend on a multi-impl (lua.eclass) package, use
+# lua_gen_cond_dep with LUA_USEDEP placeholder instead.
+#
+# Example use:
+# @CODE
+# RDEPEND="dev-lua/foo[${LUA_SINGLE_USEDEP}]"
+# @CODE
+#
+# Example value:
+# @CODE
+# lua_single_target_lua5-1(-)?
+# @CODE
+
+# @ECLASS-VARIABLE: LUA_USEDEP
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# This is an eclass-generated USE-dependency string which can be used to
+# depend on another Lua package being built for the same Lua
+# implementations.
+#
+# Example use:
+# @CODE
+# RDEPEND="dev-lua/foo[${LUA_USEDEP}]"
+# @CODE
+#
+# Example value:
+# @CODE
+# lua_targets_lua5-1(-)?,lua_targets_lua5-2(-)?
+# @CODE
+
+# @FUNCTION: _lua_single_set_globals
+# @INTERNAL
+# @DESCRIPTION:
+# Sets all the global output variables provided by this eclass.
+# This function must be called once, in global scope.
+_lua_single_set_globals() {
+       _lua_set_impls
+
+       local flags=( "${_LUA_SUPPORTED_IMPLS[@]/#/lua_single_target_}" )
+
+       if [[ ${#_LUA_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
+               # if only one implementation is supported, use IUSE defaults
+               # to avoid requesting the user to enable it
+               IUSE="+${flags[0]}"
+       else
+               IUSE="${flags[*]}"
+       fi
+
+       local requse="^^ ( ${flags[*]} )"
+       local single_flags="${flags[@]/%/(-)?}"
+       local single_usedep=${single_flags// /,}
+
+       local deps= i PYTHON_PKG_DEP
+       for i in "${_LUA_SUPPORTED_IMPLS[@]}"; do
+               _lua_export "${i}" LUA_PKG_DEP
+               deps+="lua_single_target_${i}? ( ${LUA_PKG_DEP} ) "
+       done
+
+       if [[ ${LUA_DEPS+1} ]]; then
+               if [[ ${LUA_DEPS} != "${deps}" ]]; then
+                       eerror "LUA_DEPS have changed between inherits 
(LUA_REQ_USE?)!"
+                       eerror "Before: ${LUA_DEPS}"
+                       eerror "Now   : ${deps}"
+                       die "LUA_DEPS integrity check failed"
+               fi
+
+               # these two are formality -- they depend on LUA_COMPAT only
+               if [[ ${LUA_REQUIRED_USE} != ${requse} ]]; then
+                       eerror "LUA_REQUIRED_USE have changed between inherits!"
+                       eerror "Before: ${LUA_REQUIRED_USE}"
+                       eerror "Now   : ${requse}"
+                       die "LUA_REQUIRED_USE integrity check failed"
+               fi
+
+               if [[ ${LUA_SINGLE_USEDEP} != "${single_usedep}" ]]; then
+                       eerror "LUA_SINGLE_USEDEP have changed between 
inherits!"
+                       eerror "Before: ${LUA_SINGLE_USEDEP}"
+                       eerror "Now   : ${single_usedep}"
+                       die "LUA_SINGLE_USEDEP integrity check failed"
+               fi
+       else
+               LUA_DEPS=${deps}
+               LUA_REQUIRED_USE=${requse}
+               LUA_SINGLE_USEDEP=${single_usedep}
+               LUA_USEDEP='%LUA_USEDEP-NEEDS-TO-BE-USED-IN-LUA_GEN_COND_DEP%'
+               readonly LUA_DEPS LUA_REQUIRED_USE LUA_SINGLE_USEDEP LUA_USEDEP
+       fi
+}
+
+_lua_single_set_globals
+unset -f _lua_single_set_globals
+
+if [[ ! ${_LUA_SINGLE_R0} ]]; then
+
+# @FUNCTION: _lua_gen_usedep
+# @USAGE: [<pattern>...]
+# @INTERNAL
+# @DESCRIPTION:
+# Output a USE dependency string for Lua implementations which
+# are both in LUA_COMPAT and match any of the patterns passed
+# as parameters to the function.
+#
+# The patterns can be fnmatch-style patterns (matched via bash == operator
+# against LUA_COMPAT values). Remember to escape or quote the fnmatch
+# patterns to prevent accidental shell filename expansion.
+#
+# This is an internal function used to implement lua_gen_cond_dep.
+_lua_gen_usedep() {
+       debug-print-function ${FUNCNAME} "${@}"
+
+       local impl matches=()
+
+       _lua_verify_patterns "${@}"
+       for impl in "${_LUA_SUPPORTED_IMPLS[@]}"; do
+               if _lua_impl_matches "${impl}" "${@}"; then
+                       matches+=(
+                               "lua_single_target_${impl}(-)?"
+                       )
+               fi
+       done
+
+       [[ ${matches[@]} ]] || die "No supported implementations match 
lua_gen_usedep patterns: ${@}"
+
+       local out=${matches[@]}
+       echo "${out// /,}"
+}
+
+# @FUNCTION: _lua_impl_matches
+# @USAGE: <impl> [<pattern>...]
+# @INTERNAL
+# @DESCRIPTION:
+# Check whether the specified <impl> matches at least one
+# of the patterns following it. Return 0 if it does, 1 otherwise.
+# Matches if no patterns are provided.
+#
+# <impl> can be in LUA_COMPAT or ELUA form. The patterns can be
+# fnmatch-style patterns, e.g. 'lua5*', '..
+_lua_impl_matches() {
+       [[ ${#} -ge 1 ]] || die "${FUNCNAME}: takes at least 1 parameter"
+       [[ ${#} -eq 1 ]] && return 0
+
+       local impl=${1} pattern
+       shift
+
+       for pattern; do
+               # unify value style to allow lax matching
+               if [[ ${impl/./-} == ${pattern/./-} ]]; then
+                       return 0
+               fi
+       done
+
+       return 1
+}
+
+# @FUNCTION: _lua_verify_patterns
+# @USAGE: <pattern>...
+# @INTERNAL
+# @DESCRIPTION:
+# Verify whether the patterns passed to the eclass function are correct
+# (i.e. can match any valid implementation).  Dies on wrong pattern.
+_lua_verify_patterns() {
+       debug-print-function ${FUNCNAME} "${@}"
+
+       local impl pattern
+       for pattern; do
+               for impl in "${_LUA_ALL_IMPLS[@]}"; do
+                       [[ ${impl} == ${pattern/./-} ]] && continue 2
+               done
+
+               die "Invalid implementation pattern: ${pattern}"
+       done
+}
+
+# @FUNCTION: lua_gen_cond_dep
+# @USAGE: <dependency> [<pattern>...]
+# @DESCRIPTION:
+# Output a list of <dependency>-ies made conditional to USE flags
+# of Lua implementations which are both in LUA_COMPAT and match
+# any of the patterns passed as the remaining parameters.
+#
+# The patterns can be fnmatch-style patterns (matched via bash == operator
+# against LUA_COMPAT values). Remember to escape or quote the fnmatch
+# patterns to prevent accidental shell filename expansion.
+#
+# In order to enforce USE constraints on the packages, verbatim
+# '${LUA_SINGLE_USEDEP}' and '${LUA_USEDEP}' (quoted!) may
+# be placed in the dependency specification. It will get expanded within
+# the function into a proper USE dependency string.
+#
+# Example:
+# @CODE
+# LUA_COMPAT=( lua5-{1..3} )
+# RDEPEND="$(lua_gen_cond_dep \
+#   'dev-lua/backported_core_module[${LUA_USEDEP}]' lua5-1 lua5-2 )"
+# @CODE
+#
+# It will cause the variable to look like:
+# @CODE
+# RDEPEND="lua_single_target_lua5-1? (
+#     dev-lua/backported_core_module[lua_targets_lua5-1(-)?,...] )
+#      lua_single_target_lua5-2? (
+#     dev-lua/backported_core_module[lua_targets_lua5-2(-)?,...] )"
+# @CODE
+lua_gen_cond_dep() {
+       debug-print-function ${FUNCNAME} "${@}"
+
+       local impl matches=()
+
+       local dep=${1}
+       shift
+
+       _lua_verify_patterns "${@}"
+       for impl in "${_LUA_SUPPORTED_IMPLS[@]}"; do
+               if _lua_impl_matches "${impl}" "${@}"; then
+                       # substitute ${LUA_SINGLE_USEDEP} if used
+                       # (since lua_gen_usedep() will not return
+                       #  ${LUA_SINGLE_USEDEP}, the code is run at most once)
+                       if [[ ${dep} == *'${LUA_SINGLE_USEDEP}'* ]]; then
+                               local usedep=$(_lua_gen_usedep "${@}")
+                               dep=${dep//\$\{LUA_SINGLE_USEDEP\}/${usedep}}
+                       fi
+                       local multi_usedep="lua_targets_${impl}(-)"
+
+                       local 
subdep=${dep//\$\{LUA_MULTI_USEDEP\}/${multi_usedep}}
+                       matches+=( "lua_single_target_${impl}? (
+                               ${subdep//\$\{LUA_USEDEP\}/${multi_usedep}} )" )
+               fi
+       done
+
+       echo "${matches[@]}"
+}
+
+# @FUNCTION: lua_gen_impl_dep
+# @USAGE: [<requested-use-flags> [<impl-pattern>...]]
+# @DESCRIPTION:
+# Output a dependency on Lua implementations with the specified USE
+# dependency string appended, or no USE dependency string if called
+# without the argument (or with empty argument). If any implementation
+# patterns are passed, the output dependencies will be generated only
+# for the implementations matching them.
+#
+# The patterns can be fnmatch-style patterns (matched via bash == operator
+# against LUA_COMPAT values). Remember to escape or quote the fnmatch
+# patterns to prevent accidental shell filename expansion.
+#
+# Use this function when you need to request different USE flags
+# on the Lua interpreter depending on package's USE flags. If you
+# only need a single set of interpreter USE flags, just set
+# LUA_REQ_USE and use ${LUA_DEPS} globally.
+#
+# Example:
+# @CODE
+# LUA_COMPAT=( lua5-{1..3} )
+# RDEPEND="foo? ( $(lua_gen_impl_dep 'deprecated(+)' lua5-3 ) )"
+# @CODE
+#
+# It will cause the variable to look like:
+# @CODE
+# RDEPEND="foo? (
+#      lua_single_target_lua5-3? ( dev-lang/lua:5.3[deprecated(+)] )
+# )"
+# @CODE
+lua_gen_impl_dep() {
+       debug-print-function ${FUNCNAME} "${@}"
+
+       local impl
+       local matches=()
+
+       local LUA_REQ_USE=${1}
+       shift
+
+       _lua_verify_patterns "${@}"
+       for impl in "${_LUA_SUPPORTED_IMPLS[@]}"; do
+               if _lua_impl_matches "${impl}" "${@}"; then
+                       local LUA_PKG_DEP
+                       _lua_export "${impl}" LUA_PKG_DEP
+                       matches+=( "lua_single_target_${impl}? ( ${LUA_PKG_DEP} 
)" )
+               fi
+       done
+
+       echo "${matches[@]}"
+}
+
+# @FUNCTION: lua_setup
+# @DESCRIPTION:
+# Determine what the selected Lua implementation is and set
+# the Lua build environment up for it.
+lua_setup() {
+       debug-print-function ${FUNCNAME} "${@}"
+
+       unset ELUA
+
+       # support developer override
+       if [[ ${LUA_COMPAT_OVERRIDE} ]]; then
+               local impls=( ${LUA_COMPAT_OVERRIDE} )
+               [[ ${#impls[@]} -eq 1 ]] || die "LUA_COMPAT_OVERRIDE must name 
exactly one implementation for lua-single"
+
+               ewarn "WARNING: LUA_COMPAT_OVERRIDE in effect. The following 
Lua"
+               ewarn "implementation will be used:"
+               ewarn
+               ewarn " ${LUA_COMPAT_OVERRIDE}"
+               ewarn
+               ewarn "Dependencies won't be satisfied, and LUA_SINGLE_TARGET 
flags will be ignored."
+
+               _lua_export "${impls[0]}" ELUA LUA
+               _lua_wrapper_setup
+               einfo "Using ${ELUA} to build"
+               return
+       fi
+
+       local impl
+       for impl in "${_LUA_SUPPORTED_IMPLS[@]}"; do
+               if use "lua_single_target_${impl}"; then
+                       if [[ ${ELUA} ]]; then
+                               eerror "Your LUA_SINGLE_TARGET setting lists 
more than a single Lua"
+                               eerror "implementation. Please set it to just 
one value. If you need"
+                               eerror "to override the value for a single 
package, please use package.env"
+                               eerror "or an equivalent solution (man 5 
portage)."
+                               echo
+                               die "More than one implementation in 
LUA_SINGLE_TARGET."
+                       fi
+
+                       _lua_export "${impl}" ELUA LUA
+                       _lua_wrapper_setup
+                       einfo "Using ${ELUA} to build"
+               fi
+       done
+
+       if [[ ! ${ELUA} ]]; then
+               eerror "No Lua implementation selected for the build. Please 
set"
+               eerror "the LUA_SINGLE_TARGET variable in your make.conf to one"
+               eerror "of the following values:"
+               eerror
+               eerror "${_LUA_SUPPORTED_IMPLS[@]}"
+               echo
+               die "No supported Lua implementation in LUA_SINGLE_TARGET."
+       fi
+}
+
+# @FUNCTION: lua-single_pkg_setup
+# @DESCRIPTION:
+# Runs lua_setup.
+lua-single_pkg_setup() {
+       debug-print-function ${FUNCNAME} "${@}"
+
+       [[ ${MERGE_TYPE} != binary ]] && lua_setup
+}
+
+_LUA_SINGLE_R0=1
+fi

Reply via email to