diff options
author | Tupone Alfredo <tupone@gentoo.org> | 2019-09-05 20:24:07 +0200 |
---|---|---|
committer | Tupone Alfredo <tupone@gentoo.org> | 2019-09-12 08:00:46 +0200 |
commit | 80aa5f73e588bd8746d5bbf2794a23b3685419d8 (patch) | |
tree | 34ad0d676fd2525f04897c7aa4d4a7c9344f4538 /eclass/ada.eclass | |
parent | dev-ruby/parser: add 2.6.4.1 (diff) | |
download | gentoo-80aa5f73e588bd8746d5bbf2794a23b3685419d8.tar.gz gentoo-80aa5f73e588bd8746d5bbf2794a23b3685419d8.tar.bz2 gentoo-80aa5f73e588bd8746d5bbf2794a23b3685419d8.zip |
ada.eclass: New eclass for dev-ada packages
Signed-off-by: Alfredo Tupone <tupone@gentoo.org>
Diffstat (limited to 'eclass/ada.eclass')
-rw-r--r-- | eclass/ada.eclass | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/eclass/ada.eclass b/eclass/ada.eclass new file mode 100644 index 000000000000..338b73bab86b --- /dev/null +++ b/eclass/ada.eclass @@ -0,0 +1,435 @@ +# Copyright 2019 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: ada.eclass +# @MAINTAINER: +# Ada team <ada@gentoo.org> +# @AUTHOR: +# Tupone Alfredo <tupone@gentoo.org> +# @BLURB: An eclass for Ada packages +# @DESCRIPTION: +# This eclass set the IUSE and REQUIRED_USE to request the ADA_TARGET +# when the inheriting ebuild can be supported by more than one Ada +# implementation. It also set ADA_USEDEP and ADA_DEPS with a suitable form. +# A common eclass providing helper functions to build and install +# packages supporting Ada implementations. +# +# This eclass sets correct IUSE. Modification of REQUIRED_USE has to +# be done by the author of the ebuild (but ADA_REQUIRED_USE is +# provided for convenience, see below). ada exports ADA_DEPS +# and ADA_USEDEP so you can create correct dependencies for your +# package easily. +# +# Mostly copied from python-single-r1.eclass + +case "${EAPI:-0}" in + 0|1|2|3|4) + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" + ;; + 5|6|7) + # EAPI=5 is required for sane USE_EXPAND dependencies + ;; + *) + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" + ;; +esac + +EXPORT_FUNCTIONS pkg_setup + +# @ECLASS-VARIABLE: ADA_DEPS +# @DESCRIPTION: +# This is an eclass-generated Ada dependency string for all +# implementations listed in ADA_COMPAT. +# +# The dependency string is conditional on ADA_TARGET. +# +# Example use: +# @CODE +# RDEPEND="${ADA_DEPS} +# dev-foo/mydep" +# DEPEND="${RDEPEND}" +# @CODE +# + +# @ECLASS-VARIABLE: _ADA_ALL_IMPLS +# @INTERNAL +# @DESCRIPTION: +# All supported Ada implementations, most preferred last. +_ADA_ALL_IMPLS=( + gnat_2016 gnat_2017 gnat_2018 gnat_2019 +) +readonly _ADA_ALL_IMPLS + + +# @FUNCTION: _ada_impl_supported +# @USAGE: <impl> +# @INTERNAL +# @DESCRIPTION: +# Check whether the implementation <impl> (ADA_COMPAT-form) +# is still supported. +# +# Returns 0 if the implementation is valid and supported. If it is +# unsupported, returns 1 -- and the caller should ignore the entry. +# If it is invalid, dies with an appopriate error messages. +_ada_impl_supported() { + debug-print-function ${FUNCNAME} "${@}" + + [[ ${#} -eq 1 ]] || die "${FUNCNAME}: takes exactly 1 argument (impl)." + + local impl=${1} + + # keep in sync with _ADA_ALL_IMPLS! + # (not using that list because inline patterns shall be faster) + case "${impl}" in + gnat_201[6789]) + return 0 + ;; + *) + [[ ${ADA_COMPAT_NO_STRICT} ]] && return 1 + die "Invalid implementation in ADA_COMPAT: ${impl}" + esac +} + +# @FUNCTION: _ada_set_impls +# @INTERNAL +# @DESCRIPTION: +# Check ADA_COMPAT for well-formedness and validity, then set +# two global variables: +# +# - _ADA_SUPPORTED_IMPLS containing valid implementations supported +# by the ebuild (ADA_COMPAT - dead implementations), +# +# - and _ADA_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 be called once in global scope by an eclass +# utilizing ADA_COMPAT. +_ada_set_impls() { + local i + + if ! declare -p ADA_COMPAT &>/dev/null; then + die 'ADA_COMPAT not declared.' + fi + if [[ $(declare -p ADA_COMPAT) != "declare -a"* ]]; then + die 'ADA_COMPAT must be an array.' + fi + for i in "${ADA_COMPAT[@]}"; do + # trigger validity checks + _ada_impl_supported "${i}" + done + + local supp=() unsupp=() + + for i in "${_ADA_ALL_IMPLS[@]}"; do + if has "${i}" "${ADA_COMPAT[@]}"; then + supp+=( "${i}" ) + else + unsupp+=( "${i}" ) + fi + done + if [[ ! ${supp[@]} ]]; then + die "No supported implementation in ADA_COMPAT." + fi + + if [[ ${_ADA_SUPPORTED_IMPLS[@]} ]]; then + # set once already, verify integrity + if [[ ${_ADA_SUPPORTED_IMPLS[@]} != ${supp[@]} ]]; then + eerror "Supported impls (ADA_COMPAT) changed between inherits!" + eerror "Before: ${_ADA_SUPPORTED_IMPLS[*]}" + eerror "Now : ${supp[*]}" + die "_ADA_SUPPORTED_IMPLS integrity check failed" + fi + if [[ ${_ADA_UNSUPPORTED_IMPLS[@]} != ${unsupp[@]} ]]; then + eerror "Unsupported impls changed between inherits!" + eerror "Before: ${_ADA_UNSUPPORTED_IMPLS[*]}" + eerror "Now : ${unsupp[*]}" + die "_ADA_UNSUPPORTED_IMPLS integrity check failed" + fi + else + _ADA_SUPPORTED_IMPLS=( "${supp[@]}" ) + _ADA_UNSUPPORTED_IMPLS=( "${unsupp[@]}" ) + readonly _ADA_SUPPORTED_IMPLS _ADA_UNSUPPORTED_IMPLS + fi +} + +# @FUNCTION: ada_export +# @USAGE: [<impl>] <variables>... +# @DESCRIPTION: +# Set and export the Ada implementation-relevant variables passed +# as parameters. +# +# The optional first parameter may specify the requested Ada +# implementation (either as ADA_TARGETS value, e.g. ada2_7, +# or an EADA one, e.g. ada2.7). If no implementation passed, +# the current one will be obtained from ${EADA}. +# +# The variables which can be exported are: GCC, EADA, GNATMAKE. +# They are described more completely in the eclass +# variable documentation. +ada_export() { + debug-print-function ${FUNCNAME} "${@}" + + local impl var + + case "${1}" in + gnat_201[6789]) + impl=${1} + shift + ;; + *) + impl=${EADA} + if [[ -z ${impl} ]]; then + die "ada_export called without a ada implementation and EADA is unset" + fi + ;; + esac + debug-print "${FUNCNAME}: implementation: ${impl}" + + local gcc_pv + case "${impl}" in + gnat_2016) + gcc_pv=4.9.4 + ;; + gnat_2017) + gcc_pv=6.3.0 + ;; + gnat_2018) + gcc_pv=7.3.1 + ;; + gnat_2019) + gcc_pv=8.3.1 + ;; + *) + gcc_pv="9.9.9" + ;; + esac + + for var; do + case "${var}" in + EADA) + export EADA=${impl} + debug-print "${FUNCNAME}: EADA = ${EADA}" + ;; + GCC) + export GCC=${EPREFIX}/usr/bin/gcc-${gcc_pv} + debug-print "${FUNCNAME}: GCC = ${GCC}" + ;; + GCC_PV) + export GCC_PV=${gcc_pv} + debug-print "${FUNCNAME}: GCC_PV = ${GCC_PV}" + ;; + GNATBIND) + export GNATBIND=${EPREFIX}/usr/bin/gnatbind-${gcc_pv} + debug-print "${FUNCNAME}: GNATBIND = ${GNATBIND}" + ;; + GNATMAKE) + export GNATMAKE=${EPREFIX}/usr/bin/gnatmake-${gcc_pv} + debug-print "${FUNCNAME}: GNATMAKE = ${GNATMAKE}" + ;; + GNATLS) + export GNATLS=${EPREFIX}/usr/bin/gnatls-${gcc_pv} + debug-print "${FUNCNAME}: GNATLS = ${GNATLS}" + ;; + ADA_PKG_DEP) + ADA_PKG_DEP="dev-lang/gnat-gpl:${gcc_pv}" + + # use-dep + if [[ ${ADA_REQ_USE} ]]; then + ADA_PKG_DEP+=[${ADA_REQ_USE}] + fi + + export ADA_PKG_DEP + debug-print "${FUNCNAME}: ADA_PKG_DEP = ${ADA_PKG_DEP}" + ;; + *) + die "ada_export: unknown variable ${var}" + esac + done +} + +_ada_single_set_globals() { + _ada_set_impls + local i ADA_PKG_DEP + + local flags=( "${_ADA_SUPPORTED_IMPLS[@]/#/ada_target_}" ) + local unflags=( "${_ADA_UNSUPPORTED_IMPLS[@]/#/-ada_target_}" ) + local allflags=( ${flags[@]} ${unflags[@]} ) + + local optflags=${flags[@]/%/(-)?} + + IUSE="${allflags[*]}" + + if [[ ${#_ADA_UNSUPPORTED_IMPLS[@]} -gt 0 ]]; then + optflags+=,${unflags[@]/%/(-)} + fi + + local deps requse usedep + if [[ ${#_ADA_SUPPORTED_IMPLS[@]} -eq 1 ]]; then + # There is only one supported implementation; set IUSE and other + # variables without ADA_SINGLE_TARGET. + requse=${flags[*]} + ada_export "${_ADA_SUPPORTED_IMPLS[0]}" ADA_PKG_DEP + deps="${flags[*]}? ( ${ADA_PKG_DEP} ) " + else + # Multiple supported implementations; honor ADA_TARGET. + requse="^^ ( ${flags[*]} )" + + for i in "${_ADA_SUPPORTED_IMPLS[@]}"; do + ada_export "${i}" ADA_PKG_DEP + deps+="ada_target_${i}? ( ${ADA_PKG_DEP} ) " + done + fi + usedep=${optflags// /,} + if [[ ${ADA_DEPS+1} ]]; then + if [[ ${ADA_DEPS} != "${deps}" ]]; then + eerror "ADA_DEPS have changed between inherits (ADA_REQ_USE?)!" + eerror "Before: ${ADA_DEPS}" + eerror "Now : ${deps}" + die "ADA_DEPS integrity check failed" + fi + + # these two are formality -- they depend on ADA_COMPAT only + if [[ ${ADA_REQUIRED_USE} != ${requse} ]]; then + eerror "ADA_REQUIRED_USE have changed between inherits!" + eerror "Before: ${ADA_REQUIRED_USE}" + eerror "Now : ${requse}" + die "ADA_REQUIRED_USE integrity check failed" + fi + + if [[ ${ADA_USEDEP} != "${usedep}" ]]; then + eerror "ADA_USEDEP have changed between inherits!" + eerror "Before: ${ADA_USEDEP}" + eerror "Now : ${usedep}" + die "ADA_USEDEP integrity check failed" + fi + else + ADA_DEPS=${deps} + ADA_REQUIRED_USE=${requse} + ADA_USEDEP=${usedep} + readonly ADA_DEPS ADA_REQUIRED_USE ADA_USEDEP + fi +} +_ada_single_set_globals +unset -f _ada_single_set_globals + +# @FUNCTION: ada_wrapper_setup +# @USAGE: [<path> [<impl>]] +# @DESCRIPTION: +# Create proper 'ada' executable wrappers +# in the directory named by <path>. Set up PATH +# appropriately. <path> defaults to ${T}/${EADA}. +# +# The wrappers will be created for implementation named by <impl>, +# or for one named by ${EADA} if no <impl> passed. +# +# If the named directory contains a ada 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. +ada_wrapper_setup() { + debug-print-function ${FUNCNAME} "${@}" + + local workdir=${1:-${T}/${EADA}} + local impl=${2:-${EADA}} + + [[ ${workdir} ]] || die "${FUNCNAME}: no workdir specified." + [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EADA specified." + + if [[ ! -x ${workdir}/bin/gnatmake ]]; then + mkdir -p "${workdir}"/bin || die + + local GCC GNATMAKE GNATLS GNATBIND + ada_export "${impl}" GCC GNATMAKE GNATLS GNATBIND + + # Ada compiler + cat > "${workdir}/bin/gcc" <<-_EOF_ || die + #!/bin/sh + exec "${GCC}" "\${@}" + _EOF_ + chmod a+x "${workdir}/bin/gcc" + cat > "${workdir}/bin/gnatmake" <<-_EOF_ || die + #!/bin/sh + exec "${GNATMAKE}" "\${@}" + _EOF_ + chmod a+x "${workdir}/bin/gnatmake" + cat > "${workdir}/bin/gnatls" <<-_EOF_ || die + #!/bin/sh + exec "${GNATLS}" "\${@}" + _EOF_ + chmod a+x "${workdir}/bin/gnatls" + cat > "${workdir}/bin/gnatbind" <<-_EOF_ || die + #!/bin/sh + exec "${GNATBIND}" "\${@}" + _EOF_ + chmod a+x "${workdir}/bin/gnatbind" + 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 + export PATH +} + +# @FUNCTION: ada_setup +# @DESCRIPTION: +# Determine what the selected Ada implementation is and set +# the Ada build environment up for it. +ada_setup() { + debug-print-function ${FUNCNAME} "${@}" + + unset EADA + + if [[ ${#_ADA_SUPPORTED_IMPLS[@]} -eq 1 ]]; then + if use "ada_targets_${_ADA_SUPPORTED_IMPLS[0]}"; then + # Only one supported implementation, enable it explicitly + ada_export "${_ADA_SUPPORTED_IMPLS[0]}" EADA GCC GCC_PV GNATMAKE + ada_wrapper_setup + fi + else + local impl + for impl in "${_ADA_SUPPORTED_IMPLS[@]}"; do + if use "ada_target_${impl}"; then + if [[ ${EADA} ]]; then + eerror "Your ADA_TARGET setting lists more than a single Ada" + 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 ADA_TARGET." + fi + + ada_export "${impl}" EADA GCC GCC_PV GNATMAKE + ada_wrapper_setup + fi + done + fi + + if [[ ! ${EADA} ]]; then + eerror "No Ada implementation selected for the build. Please set" + if [[ ${#_ADA_SUPPORTED_IMPLS[@]} -eq 1 ]]; then + eerror "the ADA_TARGETS variable in your make.conf to include one" + else + eerror "the ADA_SINGLE_TARGET variable in your make.conf to one" + fi + eerror "of the following values:" + eerror + eerror "${_ADA_SUPPORTED_IMPLS[@]}" + echo + die "No supported Ada implementation in ADA_SINGLE_TARGET/ADA_TARGETS." + fi +} + +# @FUNCTION: ada_pkg_setup +# @DESCRIPTION: +# Runs ada_setup. +ada_pkg_setup() { + debug-print-function ${FUNCNAME} "${@}" + + [[ ${MERGE_TYPE} != binary ]] && ada_setup +} |