sys-process/glances: 3.1.4.1-r1 amd64 stable, bug #720368
[gentoo.git] / eclass / ada.eclass
1 # Copyright 2019 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: ada.eclass
5 # @MAINTAINER:
6 # Ada team <ada@gentoo.org>
7 # @AUTHOR:
8 # Tupone Alfredo <tupone@gentoo.org>
9 # @SUPPORTED_EAPIS: 6 7
10 # @BLURB: An eclass for Ada packages
11 # @DESCRIPTION:
12 # This eclass set the IUSE and REQUIRED_USE to request the ADA_TARGET
13 # when the inheriting ebuild can be supported by more than one Ada
14 # implementation. It also set ADA_USEDEP and ADA_DEPS with a suitable form.
15 # A common eclass providing helper functions to build and install
16 # packages supporting Ada implementations.
17 #
18 # This eclass sets correct IUSE. Modification of REQUIRED_USE has to
19 # be done by the author of the ebuild (but ADA_REQUIRED_USE is
20 # provided for convenience, see below). ada exports ADA_DEPS
21 # and ADA_USEDEP so you can create correct dependencies for your
22 # package easily.
23 #
24 # Mostly copied from python-single-r1.eclass
25
26 case "${EAPI:-0}" in
27         0|1|2|3|4|5)
28                 die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
29                 ;;
30         6|7)
31                 # EAPI=5 is required for sane USE_EXPAND dependencies
32                 ;;
33         *)
34                 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
35                 ;;
36 esac
37
38 EXPORT_FUNCTIONS pkg_setup
39
40 # @ECLASS-VARIABLE: ADA_DEPS
41 # @DESCRIPTION:
42 # This is an eclass-generated Ada dependency string for all
43 # implementations listed in ADA_COMPAT.
44 #
45 # The dependency string is conditional on ADA_TARGET.
46 #
47 # Example use:
48 # @CODE
49 # RDEPEND="${ADA_DEPS}
50 #   dev-foo/mydep"
51 # DEPEND="${RDEPEND}"
52 # @CODE
53 #
54
55 # @ECLASS-VARIABLE: _ADA_ALL_IMPLS
56 # @INTERNAL
57 # @DESCRIPTION:
58 # All supported Ada implementations, most preferred last.
59 _ADA_ALL_IMPLS=(
60         gnat_2016 gnat_2017 gnat_2018 gnat_2019
61 )
62 readonly _ADA_ALL_IMPLS
63
64
65 # @FUNCTION: _ada_impl_supported
66 # @USAGE: <impl>
67 # @INTERNAL
68 # @DESCRIPTION:
69 # Check whether the implementation <impl> (ADA_COMPAT-form)
70 # is still supported.
71 #
72 # Returns 0 if the implementation is valid and supported. If it is
73 # unsupported, returns 1 -- and the caller should ignore the entry.
74 # If it is invalid, dies with an appopriate error messages.
75 _ada_impl_supported() {
76         debug-print-function ${FUNCNAME} "${@}"
77
78         [[ ${#} -eq 1 ]] || die "${FUNCNAME}: takes exactly 1 argument (impl)."
79
80         local impl=${1}
81
82         # keep in sync with _ADA_ALL_IMPLS!
83         # (not using that list because inline patterns shall be faster)
84         case "${impl}" in
85                 gnat_201[6789])
86                         return 0
87                         ;;
88                 *)
89                         [[ ${ADA_COMPAT_NO_STRICT} ]] && return 1
90                         die "Invalid implementation in ADA_COMPAT: ${impl}"
91         esac
92 }
93
94 # @FUNCTION: _ada_set_impls
95 # @INTERNAL
96 # @DESCRIPTION:
97 # Check ADA_COMPAT for well-formedness and validity, then set
98 # two global variables:
99 #
100 # - _ADA_SUPPORTED_IMPLS containing valid implementations supported
101 #   by the ebuild (ADA_COMPAT - dead implementations),
102 #
103 # - and _ADA_UNSUPPORTED_IMPLS containing valid implementations that
104 #   are not supported by the ebuild.
105 #
106 # Implementations in both variables are ordered using the pre-defined
107 # eclass implementation ordering.
108 #
109 # This function must be called once in global scope by an eclass
110 # utilizing ADA_COMPAT.
111 _ada_set_impls() {
112         local i
113
114         if ! declare -p ADA_COMPAT &>/dev/null; then
115                 die 'ADA_COMPAT not declared.'
116         fi
117         if [[ $(declare -p ADA_COMPAT) != "declare -a"* ]]; then
118                 die 'ADA_COMPAT must be an array.'
119         fi
120         for i in "${ADA_COMPAT[@]}"; do
121                 # trigger validity checks
122                 _ada_impl_supported "${i}"
123         done
124
125         local supp=() unsupp=()
126
127         for i in "${_ADA_ALL_IMPLS[@]}"; do
128                 if has "${i}" "${ADA_COMPAT[@]}"; then
129                         supp+=( "${i}" )
130                 else
131                         unsupp+=( "${i}" )
132                 fi
133         done
134         if [[ ! ${supp[@]} ]]; then
135                 die "No supported implementation in ADA_COMPAT."
136         fi
137
138         if [[ ${_ADA_SUPPORTED_IMPLS[@]} ]]; then
139                 # set once already, verify integrity
140                 if [[ ${_ADA_SUPPORTED_IMPLS[@]} != ${supp[@]} ]]; then
141                         eerror "Supported impls (ADA_COMPAT) changed between inherits!"
142                         eerror "Before: ${_ADA_SUPPORTED_IMPLS[*]}"
143                         eerror "Now   : ${supp[*]}"
144                         die "_ADA_SUPPORTED_IMPLS integrity check failed"
145                 fi
146                 if [[ ${_ADA_UNSUPPORTED_IMPLS[@]} != ${unsupp[@]} ]]; then
147                         eerror "Unsupported impls changed between inherits!"
148                         eerror "Before: ${_ADA_UNSUPPORTED_IMPLS[*]}"
149                         eerror "Now   : ${unsupp[*]}"
150                         die "_ADA_UNSUPPORTED_IMPLS integrity check failed"
151                 fi
152         else
153                 _ADA_SUPPORTED_IMPLS=( "${supp[@]}" )
154                 _ADA_UNSUPPORTED_IMPLS=( "${unsupp[@]}" )
155                 readonly _ADA_SUPPORTED_IMPLS _ADA_UNSUPPORTED_IMPLS
156         fi
157 }
158
159 # @FUNCTION: ada_export
160 # @USAGE: [<impl>] <variables>...
161 # @DESCRIPTION:
162 # Set and export the Ada implementation-relevant variables passed
163 # as parameters.
164 #
165 # The optional first parameter may specify the requested Ada
166 # implementation (either as ADA_TARGETS value, e.g. ada2_7,
167 # or an EADA one, e.g. ada2.7). If no implementation passed,
168 # the current one will be obtained from ${EADA}.
169 #
170 # The variables which can be exported are: GCC, EADA, GNATMAKE.
171 # They are described more completely in the eclass
172 # variable documentation.
173 ada_export() {
174         debug-print-function ${FUNCNAME} "${@}"
175
176         local impl var
177
178         case "${1}" in
179                 gnat_201[6789])
180                         impl=${1}
181                         shift
182                         ;;
183                 *)
184                         impl=${EADA}
185                         if [[ -z ${impl} ]]; then
186                                 die "ada_export called without a ada implementation and EADA is unset"
187                         fi
188                         ;;
189         esac
190         debug-print "${FUNCNAME}: implementation: ${impl}"
191
192         local gcc_pv
193         case "${impl}" in
194                 gnat_2016)
195                         gcc_pv=4.9.4
196                         ;;
197                 gnat_2017)
198                         gcc_pv=6.3.0
199                         ;;
200                 gnat_2018)
201                         gcc_pv=7.3.1
202                         ;;
203                 gnat_2019)
204                         gcc_pv=8.3.1
205                         ;;
206                 *)
207                         gcc_pv="9.9.9"
208                         ;;
209         esac
210
211         for var; do
212                 case "${var}" in
213                         EADA)
214                                 export EADA=${impl}
215                                 debug-print "${FUNCNAME}: EADA = ${EADA}"
216                                 ;;
217                         GCC)
218                                 export GCC=${EPREFIX}/usr/bin/gcc-${gcc_pv}
219                                 debug-print "${FUNCNAME}: GCC = ${GCC}"
220                                 ;;
221                         GCC_PV)
222                                 export GCC_PV=${gcc_pv}
223                                 debug-print "${FUNCNAME}: GCC_PV = ${GCC_PV}"
224                                 ;;
225                         GNAT)
226                                 export GNAT=${EPREFIX}/usr/bin/gnat-${gcc_pv}
227                                 debug-print "${FUNCNAME}: GNAT = ${GNAT}"
228                                 ;;
229                         GNATBIND)
230                                 export GNATBIND=${EPREFIX}/usr/bin/gnatbind-${gcc_pv}
231                                 debug-print "${FUNCNAME}: GNATBIND = ${GNATBIND}"
232                                 ;;
233                         GNATMAKE)
234                                 export GNATMAKE=${EPREFIX}/usr/bin/gnatmake-${gcc_pv}
235                                 debug-print "${FUNCNAME}: GNATMAKE = ${GNATMAKE}"
236                                 ;;
237                         GNATLS)
238                                 export GNATLS=${EPREFIX}/usr/bin/gnatls-${gcc_pv}
239                                 debug-print "${FUNCNAME}: GNATLS = ${GNATLS}"
240                                 ;;
241                         GNATPREP)
242                                 export GNATPREP=${EPREFIX}/usr/bin/gnatprep-${gcc_pv}
243                                 debug-print "${FUNCNAME}: GNATPREP = ${GNATPREP}"
244                                 ;;
245                         GNATCHOP)
246                                 export GNATCHOP=${EPREFIX}/usr/bin/gnatchop-${gcc_pv}
247                                 debug-print "${FUNCNAME}: GNATCHOP = ${GNATCHOP}"
248                                 ;;
249                         ADA_PKG_DEP)
250                                 ADA_PKG_DEP="dev-lang/gnat-gpl:${gcc_pv}"
251
252                                 # use-dep
253                                 if [[ ${ADA_REQ_USE} ]]; then
254                                         ADA_PKG_DEP+=[${ADA_REQ_USE}]
255                                 fi
256
257                                 export ADA_PKG_DEP
258                                 debug-print "${FUNCNAME}: ADA_PKG_DEP = ${ADA_PKG_DEP}"
259                                 ;;
260                         *)
261                                 die "ada_export: unknown variable ${var}"
262                 esac
263         done
264 }
265
266 _ada_single_set_globals() {
267         _ada_set_impls
268         local i ADA_PKG_DEP
269
270         local flags=( "${_ADA_SUPPORTED_IMPLS[@]/#/ada_target_}" )
271         local unflags=( "${_ADA_UNSUPPORTED_IMPLS[@]/#/-ada_target_}" )
272         local allflags=( ${flags[@]} ${unflags[@]} )
273
274         local optflags=${flags[@]/%/(-)?}
275
276         IUSE="${allflags[*]}"
277
278         if [[ ${#_ADA_UNSUPPORTED_IMPLS[@]} -gt 0 ]]; then
279                 optflags+=,${unflags[@]/%/(-)}
280         fi
281
282         local deps requse usedep
283         if [[ ${#_ADA_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
284                 # There is only one supported implementation; set IUSE and other
285                 # variables without ADA_SINGLE_TARGET.
286                 requse=${flags[*]}
287                 ada_export "${_ADA_SUPPORTED_IMPLS[0]}" ADA_PKG_DEP
288                 deps="${flags[*]}? ( ${ADA_PKG_DEP} ) "
289         else
290                 # Multiple supported implementations; honor ADA_TARGET.
291                 requse="^^ ( ${flags[*]} )"
292
293                 for i in "${_ADA_SUPPORTED_IMPLS[@]}"; do
294                         ada_export "${i}" ADA_PKG_DEP
295                         deps+="ada_target_${i}? ( ${ADA_PKG_DEP} ) "
296                 done
297         fi
298         usedep=${optflags// /,}
299         if [[ ${ADA_DEPS+1} ]]; then
300                 if [[ ${ADA_DEPS} != "${deps}" ]]; then
301                         eerror "ADA_DEPS have changed between inherits (ADA_REQ_USE?)!"
302                         eerror "Before: ${ADA_DEPS}"
303                         eerror "Now   : ${deps}"
304                         die "ADA_DEPS integrity check failed"
305                 fi
306
307                 # these two are formality -- they depend on ADA_COMPAT only
308                 if [[ ${ADA_REQUIRED_USE} != ${requse} ]]; then
309                         eerror "ADA_REQUIRED_USE have changed between inherits!"
310                         eerror "Before: ${ADA_REQUIRED_USE}"
311                         eerror "Now   : ${requse}"
312                         die "ADA_REQUIRED_USE integrity check failed"
313                 fi
314
315                 if [[ ${ADA_USEDEP} != "${usedep}" ]]; then
316                         eerror "ADA_USEDEP have changed between inherits!"
317                         eerror "Before: ${ADA_USEDEP}"
318                         eerror "Now   : ${usedep}"
319                         die "ADA_USEDEP integrity check failed"
320                 fi
321         else
322                 ADA_DEPS=${deps}
323                 ADA_REQUIRED_USE=${requse}
324                 ADA_USEDEP=${usedep}
325                 readonly ADA_DEPS ADA_REQUIRED_USE ADA_USEDEP
326         fi
327 }
328 _ada_single_set_globals
329 unset -f _ada_single_set_globals
330
331 # @FUNCTION: ada_wrapper_setup
332 # @USAGE: [<path> [<impl>]]
333 # @DESCRIPTION:
334 # Create proper 'ada' executable wrappers
335 # in the directory named by <path>. Set up PATH
336 # appropriately. <path> defaults to ${T}/${EADA}.
337 #
338 # The wrappers will be created for implementation named by <impl>,
339 # or for one named by ${EADA} if no <impl> passed.
340 #
341 # If the named directory contains a ada symlink already, it will
342 # be assumed to contain proper wrappers already and only environment
343 # setup will be done. If wrapper update is requested, the directory
344 # shall be removed first.
345 ada_wrapper_setup() {
346         debug-print-function ${FUNCNAME} "${@}"
347
348         local workdir=${1:-${T}/${EADA}}
349         local impl=${2:-${EADA}}
350
351         [[ ${workdir} ]] || die "${FUNCNAME}: no workdir specified."
352         [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EADA specified."
353
354         if [[ ! -x ${workdir}/bin/gnatmake ]]; then
355                 mkdir -p "${workdir}"/bin || die
356
357                 local GCC GNATMAKE GNATLS GNATBIND GNATCHOP GNATPREP
358                 ada_export "${impl}" GCC GNAT GNATMAKE GNATLS GNATCHOP GNATBIND GNATPREP
359
360                 # Ada compiler
361                 cat > "${workdir}/bin/gcc" <<-_EOF_ || die
362                         #!/bin/sh
363                         exec "${GCC}" "\${@}"
364                 _EOF_
365                 chmod a+x "${workdir}/bin/gcc" || die
366                 cat > "${workdir}/bin/gnatmake" <<-_EOF_ || die
367                         #!/bin/sh
368                         exec "${GNATMAKE}" "\${@}"
369                 _EOF_
370                 chmod a+x "${workdir}/bin/gnatmake" || die
371                 cat > "${workdir}/bin/gnatls" <<-_EOF_ || die
372                         #!/bin/sh
373                         exec "${GNATLS}" "\${@}"
374                 _EOF_
375                 chmod a+x "${workdir}/bin/gnatls" || die
376                 cat > "${workdir}/bin/gnatbind" <<-_EOF_ || die
377                         #!/bin/sh
378                         exec "${GNATBIND}" "\${@}"
379                 _EOF_
380                 chmod a+x "${workdir}/bin/gnatbind" || die
381                 cat > "${workdir}/bin/gnatchop" <<-_EOF_ || die
382                         #!/bin/sh
383                         exec "${GNATCHOP}" "\${@}"
384                 _EOF_
385                 chmod a+x "${workdir}/bin/gnatchop" || die
386                 cat > "${workdir}/bin/gnatprep" <<-_EOF_ || die
387                         #!/bin/sh
388                         exec "${GNATPREP}" "\${@}"
389                 _EOF_
390                 chmod a+x "${workdir}/bin/gnatprep" || die
391                 cat > "${workdir}/bin/gnat" <<-_EOF_ || die
392                         #!/bin/sh
393                         exec "${GNAT}" "\${@}"
394                 _EOF_
395                 chmod a+x "${workdir}/bin/gnat" || die
396         fi
397
398         # Now, set the environment.
399         # But note that ${workdir} may be shared with something else,
400         # and thus already on top of PATH.
401         if [[ ${PATH##:*} != ${workdir}/bin ]]; then
402                 PATH=${workdir}/bin${PATH:+:${PATH}}
403         fi
404         export PATH
405 }
406
407 # @FUNCTION: ada_setup
408 # @DESCRIPTION:
409 # Determine what the selected Ada implementation is and set
410 # the Ada build environment up for it.
411 ada_setup() {
412         debug-print-function ${FUNCNAME} "${@}"
413
414         unset EADA
415
416         if [[ ${#_ADA_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
417                 if use "ada_target_${_ADA_SUPPORTED_IMPLS[0]}"; then
418                         # Only one supported implementation, enable it explicitly
419                         ada_export "${_ADA_SUPPORTED_IMPLS[0]}" EADA GCC_PV GNAT GNATBIND GNATLS GNATMAKE
420                         ada_wrapper_setup
421                 fi
422         else
423                 local impl
424                 for impl in "${_ADA_SUPPORTED_IMPLS[@]}"; do
425                         if use "ada_target_${impl}"; then
426                                 if [[ ${EADA} ]]; then
427                                         eerror "Your ADA_TARGET setting lists more than a single Ada"
428                                         eerror "implementation. Please set it to just one value. If you need"
429                                         eerror "to override the value for a single package, please use package.env"
430                                         eerror "or an equivalent solution (man 5 portage)."
431                                         echo
432                                         die "More than one implementation in ADA_TARGET."
433                                 fi
434
435                                 ada_export "${impl}" EADA GCC_PV GNAT GNATBIND GNATLS GNATMAKE
436                                 ada_wrapper_setup
437                         fi
438                 done
439         fi
440
441         if [[ ! ${EADA} ]]; then
442                 eerror "No Ada implementation selected for the build. Please set"
443                 if [[ ${#_ADA_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
444                         eerror "the ADA_TARGETS variable in your make.conf to include one"
445                 else
446                         eerror "the ADA_SINGLE_TARGET variable in your make.conf to one"
447                 fi
448                 eerror "of the following values:"
449                 eerror
450                 eerror "${_ADA_SUPPORTED_IMPLS[@]}"
451                 echo
452                 die "No supported Ada implementation in ADA_SINGLE_TARGET/ADA_TARGETS."
453         fi
454 }
455
456 # @FUNCTION: ada_pkg_setup
457 # @DESCRIPTION:
458 # Runs ada_setup.
459 ada_pkg_setup() {
460         debug-print-function ${FUNCNAME} "${@}"
461
462         [[ ${MERGE_TYPE} != binary ]] && ada_setup
463 }