From 9ee6d97c2883d42f204a533a8bc1f4562df778fb Mon Sep 17 00:00:00 2001 From: V3n3RiX Date: Wed, 16 Sep 2020 09:32:48 +0100 Subject: gentoo resync : 16.09.2020 --- eclass/lua.eclass | 710 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 710 insertions(+) create mode 100644 eclass/lua.eclass (limited to 'eclass/lua.eclass') diff --git a/eclass/lua.eclass b/eclass/lua.eclass new file mode 100644 index 000000000000..7dccba6980a0 --- /dev/null +++ b/eclass/lua.eclass @@ -0,0 +1,710 @@ +# Copyright 1999-2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: lua.eclass +# @MAINTAINER: +# William Hubbs +# Marek Szuba +# @AUTHOR: +# Marek Szuba +# Based on python{,-utils}-r1.eclass by Michał Górny et al. +# @SUPPORTED_EAPIS: 7 +# @BLURB: A common eclass for Lua packages +# @DESCRIPTION: +# A common eclass providing helper functions to build and install +# packages supporting being installed for multiple Lua implementations. +# +# This eclass sets correct IUSE. Modification of REQUIRED_USE has to +# be done by the author of the ebuild (but LUA_REQUIRED_USE is +# provided for convenience, see below). The eclass exports LUA_DEPS +# and LUA_USEDEP so you can create correct dependencies for your +# package easily. It also provides methods to easily run a command for +# each enabled Lua implementation and duplicate the sources for them. +# +# Please note that for the time being this eclass does NOT support luajit. +# +# @EXAMPLE: +# @CODE +# EAPI=7 +# +# LUA_COMPAT=( lua5-{1..3} ) +# +# inherit lua +# +# [...] +# +# REQUIRED_USE="${LUA_REQUIRED_USE}" +# DEPEND="${LUA_DEPS}" +# RDEPEND="${DEPEND} +# dev-lua/foo[${LUA_USEDEP}]" +# BDEPEND="virtual/pkgconfig" +# +# lua_src_install() { +# emake LUA_VERSION="$(lua_get_version)" install +# } +# +# src_install() { +# lua_foreach_impl lua_src_install +# } +# @CODE + +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_R0} ]]; then + +inherit multibuild toolchain-funcs + +fi + +# @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: BUILD_DIR +# @OUTPUT_VARIABLE +# @DEFAULT_UNSET +# @DESCRIPTION: +# The current build directory. In global scope, it is supposed to +# contain an initial build directory; if unset, it defaults to ${S}. +# +# In functions run by lua_foreach_impl(), the BUILD_DIR is locally +# set to an implementation-specific build directory. That path is +# created through appending a hyphen and the implementation name +# to the final component of the initial BUILD_DIR. +# +# Example value: +# @CODE +# ${WORKDIR}/foo-1.3-lua5-1 +# @CODE + +# @ECLASS-VARIABLE: ELUA +# @DEFAULT_UNSET +# @DESCRIPTION: +# The executable name of the current Lua interpreter. This variable is set +# automatically in functions called by lua_foreach_impl(). +# +# Example value: +# @CODE +# lua5.1 +# @CODE + +# @ECLASS-VARIABLE: LUA +# @DEFAULT_UNSET +# @DESCRIPTION: +# The absolute path to the current Lua interpreter. This variable is set +# automatically in functions called by lua_foreach_impl(). +# +# Example value: +# @CODE +# /usr/bin/lua5.1 +# @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_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 + +if [[ ! ${_LUA_R0} ]]; then + +# @FUNCTION: _lua_export +# @USAGE: [] ... +# @INTERNAL +# @DESCRIPTION: +# Set and export the Lua implementation-relevant variables passed +# as parameters. +# +# The optional first parameter may specify the requested Lua +# implementation (either as LUA_TARGETS value, e.g. lua5-2, +# or an ELUA one, e.g. lua5.2). If no implementation passed, +# the current one will be obtained from ${ELUA}. +_lua_export() { + debug-print-function ${FUNCNAME} "${@}" + + local impl var + + case "${1}" in + lua*) + impl=${1/-/.} + shift + ;; + *) + impl=${ELUA} + if [[ -z ${impl} ]]; then + die "_lua_export called without a Lua implementation and ELUA is unset" + fi + ;; + esac + debug-print "${FUNCNAME}: implementation: ${impl}" + + for var; do + case "${var}" in + ELUA) + export ELUA=${impl} + debug-print "${FUNCNAME}: ELUA = ${ELUA}" + ;; + LUA) + export LUA="${EPREFIX}"/usr/bin/${impl} + debug-print "${FUNCNAME}: LUA = ${LUA}" + ;; + LUA_CFLAGS) + local val + + val=$($(tc-getPKG_CONFIG) --cflags ${impl}) || die + + export LUA_CFLAGS=${val} + debug-print "${FUNCNAME}: LUA_CFLAGS = ${LUA_CFLAGS}" + ;; + LUA_CMOD_DIR) + local val + + val=$($(tc-getPKG_CONFIG) --variable INSTALL_CMOD ${impl}) || die + + export LUA_CMOD_DIR=${val} + debug-print "${FUNCNAME}: LUA_CMOD_DIR = ${LUA_CMOD_DIR}" + ;; + LUA_LIBS) + local val + + val=$($(tc-getPKG_CONFIG) --libs ${impl}) || die + + export LUA_LIBS=${val} + debug-print "${FUNCNAME}: LUA_LIBS = ${LUA_LIBS}" + ;; + LUA_LMOD_DIR) + local val + + val=$($(tc-getPKG_CONFIG) --variable INSTALL_LMOD ${impl}) || die + + export LUA_LMOD_DIR=${val} + debug-print "${FUNCNAME}: LUA_LMOD_DIR = ${LUA_LMOD_DIR}" + ;; + LUA_PKG_DEP) + local d + case ${impl} in + lua*) + LUA_PKG_DEP="dev-lang/lua:${impl#lua}" + ;; + *) + die "Invalid implementation: ${impl}" + ;; + esac + + # use-dep + if [[ ${LUA_REQ_USE} ]]; then + LUA_PKG_DEP+=[${LUA_REQ_USE}] + fi + + export LUA_PKG_DEP + debug-print "${FUNCNAME}: LUA_PKG_DEP = ${LUA_PKG_DEP}" + ;; + LUA_VERSION) + local val + + val=$($(tc-getPKG_CONFIG) --modversion ${impl}) || die + + export LUA_VERSION=${val} + debug-print "${FUNCNAME}: LUA_VERSION = ${LUA_VERSION}" + ;; + *) + die "_lua_export: unknown variable ${var}" + ;; + esac + done +} + +# @FUNCTION: _lua_validate_useflags +# @INTERNAL +# @DESCRIPTION: +# Enforce the proper setting of LUA_TARGETS, if LUA_COMPAT_OVERRIDE +# is not in effect. If it is, just warn that the flags will be ignored. +_lua_validate_useflags() { + debug-print-function ${FUNCNAME} "${@}" + + if [[ ${LUA_COMPAT_OVERRIDE} ]]; then + if [[ ! ${_LUA_COMPAT_OVERRIDE_WARNED} ]]; then + ewarn "WARNING: LUA_COMPAT_OVERRIDE in effect. The following Lua" + ewarn "implementations will be enabled:" + ewarn + ewarn " ${LUA_COMPAT_OVERRIDE}" + ewarn + ewarn "Dependencies won't be satisfied, and LUA_TARGETS will be ignored." + _LUA_COMPAT_OVERRIDE_WARNED=1 + fi + # we do not use flags with LCO + return + fi + + local i + + for i in "${_LUA_SUPPORTED_IMPLS[@]}"; do + use "lua_targets_${i}" && return 0 + done + + eerror "No Lua implementation selected for the build. Please add one" + eerror "of the following values to your LUA_TARGETS" + eerror "(in make.conf or package.use):" + eerror + eerror "${LUA_COMPAT[@]}" + echo + die "No supported Lua implementation in LUA_TARGETS." +} + +# @FUNCTION: _lua_obtain_impls +# @INTERNAL +# @DESCRIPTION: +# Set up the enabled implementation list. +_lua_obtain_impls() { + _lua_validate_useflags + + if [[ ${LUA_COMPAT_OVERRIDE} ]]; then + MULTIBUILD_VARIANTS=( ${LUA_COMPAT_OVERRIDE} ) + return + fi + + MULTIBUILD_VARIANTS=() + + local impl + for impl in "${_LUA_SUPPORTED_IMPLS[@]}"; do + has "${impl}" "${LUA_COMPAT[@]}" && \ + use "lua_targets_${impl}" && MULTIBUILD_VARIANTS+=( "${impl}" ) + done +} + + +# @FUNCTION: _lua_multibuild_wrapper +# @USAGE: [...] +# @INTERNAL +# @DESCRIPTION: +# Initialize the environment for the Lua implementation selected +# for multibuild. +_lua_multibuild_wrapper() { + debug-print-function ${FUNCNAME} "${@}" + + local -x ELUA LUA + _lua_export "${MULTIBUILD_VARIANT}" ELUA LUA + local -x PATH=${PATH} PKG_CONFIG_PATH=${PKG_CONFIG_PATH} + _lua_wrapper_setup + + "${@}" +} + +# @FUNCTION: _lua_wrapper_setup +# @USAGE: [ []] +# @INTERNAL +# @DESCRIPTION: +# Create proper Lua executables and pkg-config wrappers +# (if available) in the directory named by . Set up PATH +# and PKG_CONFIG_PATH appropriately. defaults to ${T}/${ELUA}. +# +# The wrappers will be created for implementation named by , +# or for one named by ${ELUA} if no passed. +# +# If the named directory contains a lua symlink already, it will +# be assumed to contain proper wrappers already and only environment +# setup will be done. If wrapper update is requested, the directory +# shall be removed first. +_lua_wrapper_setup() { + debug-print-function ${FUNCNAME} "${@}" + + local workdir=${1:-${T}/${ELUA}} + local impl=${2:-${ELUA}} + + [[ ${workdir} ]] || die "${FUNCNAME}: no workdir specified." + [[ ${impl} ]] || die "${FUNCNAME}: no impl nor ELUA specified." + + if [[ ! -x ${workdir}/bin/lua ]]; then + mkdir -p "${workdir}"/{bin,pkgconfig} || die + + # Clean up, in case we were supposed to do a cheap update + rm -f "${workdir}"/bin/lua{,c} || die + rm -f "${workdir}"/pkgconfig/lua.pc || die + + local ELUA LUA + _lua_export "${impl}" ELUA LUA + + # Lua interpreter and compiler + ln -s "${EPREFIX}"/usr/bin/${ELUA} "${workdir}"/bin/lua || die + ln -s "${EPREFIX}"/usr/bin/${ELUA/a/ac} "${workdir}"/bin/luac || die + + # pkg-config + ln -s "${EPREFIX}"/usr/$(get_libdir)/pkgconfig/${ELUA}.pc \ + "${workdir}"/pkgconfig/lua.pc || die + fi + + # Now, set the environment. + # But note that ${workdir} may be shared with something else, + # and thus already on top of PATH. + if [[ ${PATH##:*} != ${workdir}/bin ]]; then + PATH=${workdir}/bin${PATH:+:${PATH}} + fi + if [[ ${PKG_CONFIG_PATH##:*} != ${workdir}/pkgconfig ]]; then + PKG_CONFIG_PATH=${workdir}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}} + fi + export PATH PKG_CONFIG_PATH +} + +# @FUNCTION: lua_copy_sources +# @DESCRIPTION: +# Create a single copy of the package sources for each enabled Lua +# implementation. +# +# The sources are always copied from initial BUILD_DIR (or S if unset) +# to implementation-specific build directory matching BUILD_DIR used by +# lua_foreach_abi(). +lua_copy_sources() { + debug-print-function ${FUNCNAME} "${@}" + + local MULTIBUILD_VARIANTS + _lua_obtain_impls + + multibuild_copy_sources +} + +# @FUNCTION: lua_foreach_impl +# @USAGE: [...] +# @DESCRIPTION: +# Run the given command for each of the enabled Lua implementations. +# If additional parameters are passed, they will be passed through +# to the command. +# +# The function will return 0 status if all invocations succeed. +# Otherwise, the return code from first failing invocation will +# be returned. +# +# For each command being run, ELUA, LUA and BUILD_DIR are set +# locally, and the former two are exported to the command environment. +lua_foreach_impl() { + debug-print-function ${FUNCNAME} "${@}" + + local MULTIBUILD_VARIANTS + _lua_obtain_impls + + multibuild_foreach_variant _lua_multibuild_wrapper "${@}" +} + +# @FUNCTION: lua_get_CFLAGS +# @USAGE: [] +# @DESCRIPTION: +# Obtain and print the compiler flags for building against Lua, +# for the given implementation. If no implementation is provided, +# ${ELUA} will be used. +# +# Please note that this function requires Lua and pkg-config installed, +# and therefore proper build-time dependencies need be added to the ebuild. +lua_get_CFLAGS() { + debug-print-function ${FUNCNAME} "${@}" + + _lua_export "${@}" LUA_CFLAGS + echo "${LUA_CFLAGS}" +} + +# @FUNCTION: lua_get_cmod_dir +# @USAGE: [] +# @DESCRIPTION: +# Obtain and print the name of the directory into which compiled Lua +# modules are installed, for the given implementation. If no implementation +# is provided, ${ELUA} will be used. +# +# Please note that this function requires Lua and pkg-config installed, +# and therefore proper build-time dependencies need be added to the ebuild. +lua_get_cmod_dir() { + debug-print-function ${FUNCNAME} "${@}" + + _lua_export "${@}" LUA_CMOD_DIR + echo "${LUA_CMOD_DIR}" +} + +# @FUNCTION: lua_get_LIBS +# @USAGE: [] +# @DESCRIPTION: +# Obtain and print the compiler flags for linking against Lua, +# for the given implementation. If no implementation is provided, +# ${ELUA} will be used. +# +# Please note that this function requires Lua and pkg-config installed, +# and therefore proper build-time dependencies need be added to the ebuild. +lua_get_LIBS() { + debug-print-function ${FUNCNAME} "${@}" + + _lua_export "${@}" LUA_LIBS + echo "${LUA_LIBS}" +} + +# @FUNCTION: lua_get_lmod_dir +# @USAGE: [] +# @DESCRIPTION: +# Obtain and print the name of the directory into which native-Lua +# modules are installed, for the given implementation. If no implementation +# is provided, ${ELUA} will be used. +# +# Please note that this function requires Lua and pkg-config installed, +# and therefore proper build-time dependencies need be added to the ebuild. +lua_get_lmod_dir() { + debug-print-function ${FUNCNAME} "${@}" + + _lua_export "${@}" LUA_LMOD_DIR + echo "${LUA_LMOD_DIR}" +} + +# @FUNCTION: lua_get_version +# @USAGE: [] +# @DESCRIPTION: +# Obtain and print the full version number of the given Lua implementation. +# If no implementation is provided, ${ELUA} will be used. +# +# Please note that this function requires Lua and pkg-config installed, +# and therefore proper build-time dependencies need be added to the ebuild. +lua_get_version() { + debug-print-function ${FUNCNAME} "${@}" + + _lua_export "${@}" LUA_VERSION + echo "${LUA_VERSION}" +} + +_LUA_R0=1 +fi + +# @ECLASS-VARIABLE: _LUA_ALL_IMPLS +# @INTERNAL +# @DESCRIPTION: +# All supported Lua implementations, most preferred last +_LUA_ALL_IMPLS=( + lua5-1 + lua5-2 + lua5-3 + lua5-4 +) +readonly _LUA_ALL_IMPLS + +# @FUNCTION: _lua_set_impls +# @INTERNAL +# @DESCRIPTION: +# Check LUA_COMPAT for well-formedness and validity, then set +# two global variables: +# +# - _LUA_SUPPORTED_IMPLS containing valid implementations supported +# by the ebuild (LUA_COMPAT minus dead implementations), +# +# - and _LUA_UNSUPPORTED_IMPLS containing valid implementations that +# are not supported by the ebuild. +# +# Implementations in both variables are ordered using the pre-defined +# eclass implementation ordering. +# +# This function must only be called once. +_lua_set_impls() { + local i + + if ! declare -p LUA_COMPAT &>/dev/null; then + die 'LUA_COMPAT not declared.' + fi + if [[ $(declare -p LUA_COMPAT) != "declare -a"* ]]; then + die 'LUA_COMPAT must be an array.' + fi + + local supp=() unsupp=() + + for i in "${_LUA_ALL_IMPLS[@]}"; do + if has "${i}" "${LUA_COMPAT[@]}"; then + supp+=( "${i}" ) + else + unsupp+=( "${i}" ) + fi + done + + if [[ ! ${supp[@]} ]]; then + die "No supported implementation in LUA_COMPAT." + fi + + if [[ ${_LUA_SUPPORTED_IMPLS[@]} ]]; then + # set once already, verify integrity + if [[ ${_LUA_SUPPORTED_IMPLS[@]} != ${supp[@]} ]]; then + eerror "Supported impls (LUA_COMPAT) changed between inherits!" + eerror "Before: ${_LUA_SUPPORTED_IMPLS[*]}" + eerror "Now : ${supp[*]}" + die "_LUA_SUPPORTED_IMPLS integrity check failed" + fi + if [[ ${_LUA_UNSUPPORTED_IMPLS[@]} != ${unsupp[@]} ]]; then + eerror "Unsupported impls changed between inherits!" + eerror "Before: ${_LUA_UNSUPPORTED_IMPLS[*]}" + eerror "Now : ${unsupp[*]}" + die "_LUA_UNSUPPORTED_IMPLS integrity check failed" + fi + else + _LUA_SUPPORTED_IMPLS=( "${supp[@]}" ) + _LUA_UNSUPPORTED_IMPLS=( "${unsupp[@]}" ) + readonly _LUA_SUPPORTED_IMPLS _LUA_UNSUPPORTED_IMPLS + fi +} + +# @FUNCTION: _lua_set_globals +# @INTERNAL +# @DESCRIPTION: +# Sets all the global output variables provided by this eclass. +# This function must be called once, in global scope. +_lua_set_globals() { + local deps i LUA_PKG_DEP + + _lua_set_impls + + for i in "${_LUA_SUPPORTED_IMPLS[@]}"; do + _lua_export "${i}" LUA_PKG_DEP + deps+="lua_targets_${i}? ( ${LUA_PKG_DEP} ) " + done + + local flags=( "${_LUA_SUPPORTED_IMPLS[@]/#/lua_targets_}" ) + local optflags=${flags[@]/%/(-)?} + + local requse="|| ( ${flags[*]} )" + local usedep=${optflags// /,} + + if [[ ${LUA_DEPS+1} ]]; then + # IUSE is magical, so we can't really check it + # (but we verify LUA_COMPAT already) + + 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_USEDEP} != "${usedep}" ]]; then + eerror "LUA_USEDEP have changed between inherits!" + eerror "Before: ${LUA_USEDEP}" + eerror "Now : ${usedep}" + die "LUA_USEDEP integrity check failed" + fi + else + IUSE=${flags[*]} + + LUA_DEPS=${deps} + LUA_REQUIRED_USE=${requse} + LUA_USEDEP=${usedep} + readonly LUA_DEPS LUA_REQUIRED_USE + fi +} + +_lua_set_globals +unset -f _lua_set_globals _lua_set_impls -- cgit v1.2.3