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