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 |