Gentoo Archives: gentoo-dev

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

Replies

Subject Author
Re: [gentoo-dev] [PATCH] ada.eclass: New eclass for dev-ada packages "Michał Górny" <mgorny@g.o>