kde-plasma/breeze-gtk: x86 stable wrt bug #613144
[gentoo.git] / eclass / python-single-r1.eclass
1 # Copyright 1999-2017 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: python-single-r1.eclass
5 # @MAINTAINER:
6 # Python team <python@gentoo.org>
7 # @AUTHOR:
8 # Author: Michał Górny <mgorny@gentoo.org>
9 # Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
10 # @BLURB: An eclass for Python packages not installed for multiple implementations.
11 # @DESCRIPTION:
12 # An extension of the python-r1 eclass suite for packages which
13 # don't support being installed for multiple Python implementations.
14 # This mostly includes tools embedding Python.
15 #
16 # This eclass extends the IUSE and REQUIRED_USE set by python-r1
17 # to request the PYTHON_SINGLE_TARGET when the inheriting ebuild
18 # can be supported by more than one Python implementation. It also
19 # replaces PYTHON_USEDEP and PYTHON_DEPS with a more suitable form.
20 #
21 # Please note that packages support multiple Python implementations
22 # (using python-r1 eclass) can not depend on packages not supporting
23 # them (using this eclass).
24 #
25 # Please note that python-single-r1 will always inherit python-utils-r1
26 # as well. Thus, all the functions defined there can be used
27 # in the packages using python-single-r1, and there is no need ever
28 # to inherit both.
29 #
30 # For more information, please see the wiki:
31 # https://wiki.gentoo.org/wiki/Project:Python/python-single-r1
32
33 case "${EAPI:-0}" in
34         0|1|2|3|4)
35                 die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
36                 ;;
37         5|6)
38                 # EAPI=5 is required for sane USE_EXPAND dependencies
39                 ;;
40         *)
41                 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
42                 ;;
43 esac
44
45 if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
46
47 if [[ ${_PYTHON_R1} ]]; then
48         die 'python-single-r1.eclass can not be used with python-r1.eclass.'
49 elif [[ ${_PYTHON_ANY_R1} ]]; then
50         die 'python-single-r1.eclass can not be used with python-any-r1.eclass.'
51 fi
52
53 inherit python-utils-r1
54
55 fi
56
57 EXPORT_FUNCTIONS pkg_setup
58
59 # @ECLASS-VARIABLE: PYTHON_COMPAT
60 # @REQUIRED
61 # @DESCRIPTION:
62 # This variable contains a list of Python implementations the package
63 # supports. It must be set before the `inherit' call. It has to be
64 # an array.
65 #
66 # Example:
67 # @CODE
68 # PYTHON_COMPAT=( python2_7 python3_3 python3_4 )
69 # @CODE
70 #
71 # Please note that you can also use bash brace expansion if you like:
72 # @CODE
73 # PYTHON_COMPAT=( python2_7 python3_{3,4} )
74 # @CODE
75
76 # @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
77 # @INTERNAL
78 # @DESCRIPTION:
79 # This variable can be used when working with ebuilds to override
80 # the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
81 # which package will be built for. It needs to be specified
82 # in the calling environment, and not in ebuilds.
83 #
84 # It should be noted that in order to preserve metadata immutability,
85 # PYTHON_COMPAT_OVERRIDE does not affect IUSE nor dependencies.
86 # The state of PYTHON_TARGETS and PYTHON_SINGLE_TARGET is ignored,
87 # and the implementation in PYTHON_COMPAT_OVERRIDE is built instead.
88 # Dependencies need to be satisfied manually.
89 #
90 # Example:
91 # @CODE
92 # PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
93 # @CODE
94
95 # @ECLASS-VARIABLE: PYTHON_REQ_USE
96 # @DEFAULT_UNSET
97 # @DESCRIPTION:
98 # The list of USEflags required to be enabled on the chosen Python
99 # implementations, formed as a USE-dependency string. It should be valid
100 # for all implementations in PYTHON_COMPAT, so it may be necessary to
101 # use USE defaults.
102 #
103 # This should be set before calling `inherit'.
104 #
105 # Example:
106 # @CODE
107 # PYTHON_REQ_USE="gdbm,ncurses(-)?"
108 # @CODE
109 #
110 # It will cause the Python dependencies to look like:
111 # @CODE
112 # python_single_target_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?] )
113 # @CODE
114
115 # @ECLASS-VARIABLE: PYTHON_DEPS
116 # @DESCRIPTION:
117 # This is an eclass-generated Python dependency string for all
118 # implementations listed in PYTHON_COMPAT.
119 #
120 # The dependency string is conditional on PYTHON_SINGLE_TARGET.
121 #
122 # Example use:
123 # @CODE
124 # RDEPEND="${PYTHON_DEPS}
125 #       dev-foo/mydep"
126 # DEPEND="${RDEPEND}"
127 # @CODE
128 #
129 # Example value:
130 # @CODE
131 # dev-lang/python-exec:=
132 # python_single_target_python2_7? ( dev-lang/python:2.7[gdbm] )
133 # python_single_target_pypy? ( virtual/pypy[gdbm] )
134 # @CODE
135
136 # @ECLASS-VARIABLE: PYTHON_USEDEP
137 # @DESCRIPTION:
138 # This is an eclass-generated USE-dependency string which can be used to
139 # depend on another Python package being built for the same Python
140 # implementations.
141 #
142 # The generate USE-flag list is compatible with packages using python-r1,
143 # python-single-r1 and python-distutils-ng eclasses. It must not be used
144 # on packages using python.eclass.
145 #
146 # Example use:
147 # @CODE
148 # RDEPEND="dev-python/foo[${PYTHON_USEDEP}]"
149 # @CODE
150 #
151 # Example value:
152 # @CODE
153 # python_targets_python2_7(-)?,python_single_target_python3_4(+)?
154 # @CODE
155
156 # @ECLASS-VARIABLE: PYTHON_REQUIRED_USE
157 # @DESCRIPTION:
158 # This is an eclass-generated required-use expression which ensures the following
159 # when more than one python implementation is possible:
160 # 1. Exactly one PYTHON_SINGLE_TARGET value has been enabled.
161 # 2. The selected PYTHON_SINGLE_TARGET value is enabled in PYTHON_TARGETS.
162 #
163 # This expression should be utilized in an ebuild by including it in
164 # REQUIRED_USE, optionally behind a use flag.
165 #
166 # Example use:
167 # @CODE
168 # REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"
169 # @CODE
170 #
171 # Example value:
172 # @CODE
173 # python_single_target_python2_7? ( python_targets_python2_7 )
174 # python_single_target_python3_3? ( python_targets_python3_3 )
175 # ^^ ( python_single_target_python2_7 python_single_target_python3_3 )
176 # @CODE
177
178 _python_single_set_globals() {
179         _python_set_impls
180
181         local i PYTHON_PKG_DEP
182
183         local flags_mt=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" )
184         local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_single_target_}" )
185         local unflags=( "${_PYTHON_UNSUPPORTED_IMPLS[@]/#/-python_single_target_}" )
186
187         local optflags=${flags_mt[@]/%/(-)?},${unflags[@]/%/(-)}
188
189         IUSE="${flags_mt[*]}"
190
191         local deps requse usedep
192         if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
193                 # There is only one supported implementation; set IUSE and other
194                 # variables without PYTHON_SINGLE_TARGET.
195                 requse=${flags_mt[*]}
196                 python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" PYTHON_PKG_DEP
197                 deps="${flags_mt[*]}? ( ${PYTHON_PKG_DEP} ) "
198                 # Force on the python_single_target_* flag for this impl, so
199                 # that any dependencies that inherit python-single-r1 and
200                 # happen to have multiple implementations will still need
201                 # to bound by the implementation used by this package.
202                 optflags+=,${flags[0]/%/(+)}
203         else
204                 # Multiple supported implementations; honor PYTHON_SINGLE_TARGET.
205                 IUSE+=" ${flags[*]}"
206                 requse="^^ ( ${flags[*]} )"
207                 # Ensure deps honor the same python_single_target_* flag as is set
208                 # on this package.
209                 optflags+=,${flags[@]/%/(+)?}
210
211                 for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
212                         # The chosen targets need to be in PYTHON_TARGETS as well.
213                         # This is in order to enforce correct dependencies on packages
214                         # supporting multiple implementations.
215                         requse+=" python_single_target_${i}? ( python_targets_${i} )"
216
217                         python_export "${i}" PYTHON_PKG_DEP
218                         deps+="python_single_target_${i}? ( ${PYTHON_PKG_DEP} ) "
219                 done
220         fi
221         usedep=${optflags// /,}
222
223         # 1) well, python-exec would suffice as an RDEP
224         # but no point in making this overcomplex, BDEP doesn't hurt anyone
225         # 2) python-exec should be built with all targets forced anyway
226         # but if new targets were added, we may need to force a rebuild
227         if [[ ${_PYTHON_WANT_PYTHON_EXEC2} == 0 ]]; then
228                 die "python-exec:0 is no longer supported, please fix your ebuild to work with python-exec:2"
229         else
230                 deps+=">=dev-lang/python-exec-2:=[${usedep}]"
231         fi
232
233         if [[ ${PYTHON_DEPS+1} ]]; then
234                 if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
235                         eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
236                         eerror "Before: ${PYTHON_DEPS}"
237                         eerror "Now   : ${deps}"
238                         die "PYTHON_DEPS integrity check failed"
239                 fi
240
241                 # these two are formality -- they depend on PYTHON_COMPAT only
242                 if [[ ${PYTHON_REQUIRED_USE} != ${requse} ]]; then
243                         eerror "PYTHON_REQUIRED_USE have changed between inherits!"
244                         eerror "Before: ${PYTHON_REQUIRED_USE}"
245                         eerror "Now   : ${requse}"
246                         die "PYTHON_REQUIRED_USE integrity check failed"
247                 fi
248
249                 if [[ ${PYTHON_USEDEP} != "${usedep}" ]]; then
250                         eerror "PYTHON_USEDEP have changed between inherits!"
251                         eerror "Before: ${PYTHON_USEDEP}"
252                         eerror "Now   : ${usedep}"
253                         die "PYTHON_USEDEP integrity check failed"
254                 fi
255         else
256                 PYTHON_DEPS=${deps}
257                 PYTHON_REQUIRED_USE=${requse}
258                 PYTHON_USEDEP=${usedep}
259                 readonly PYTHON_DEPS PYTHON_REQUIRED_USE PYTHON_USEDEP
260         fi
261 }
262 _python_single_set_globals
263 unset -f _python_single_set_globals
264
265 if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
266
267 # @FUNCTION: python_gen_usedep
268 # @USAGE: <pattern> [...]
269 # @DESCRIPTION:
270 # Output a USE dependency string for Python implementations which
271 # are both in PYTHON_COMPAT and match any of the patterns passed
272 # as parameters to the function.
273 #
274 # Remember to escape or quote the patterns to prevent shell filename
275 # expansion.
276 #
277 # When all implementations are requested, please use ${PYTHON_USEDEP}
278 # instead. Please also remember to set an appropriate REQUIRED_USE
279 # to avoid ineffective USE flags.
280 #
281 # Example:
282 # @CODE
283 # PYTHON_COMPAT=( python{2_7,3_4} )
284 # DEPEND="doc? ( dev-python/epydoc[$(python_gen_usedep 'python2*')] )"
285 # @CODE
286 #
287 # It will cause the dependency to look like:
288 # @CODE
289 # DEPEND="doc? ( dev-python/epydoc[python_targets_python2_7(-)?,...] )"
290 # @CODE
291 python_gen_usedep() {
292         debug-print-function ${FUNCNAME} "${@}"
293
294         local impl pattern
295         local matches=()
296
297         for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
298                 for pattern; do
299                         if [[ ${impl} == ${pattern} ]]; then
300                                 matches+=(
301                                         "python_targets_${impl}(-)?"
302                                         "python_single_target_${impl}(+)?"
303                                 )
304                                 break
305                         fi
306                 done
307         done
308
309         [[ ${matches[@]} ]] || die "No supported implementations match python_gen_usedep patterns: ${@}"
310
311         local out=${matches[@]}
312         echo "${out// /,}"
313 }
314
315 # @FUNCTION: python_gen_useflags
316 # @USAGE: <pattern> [...]
317 # @DESCRIPTION:
318 # Output a list of USE flags for Python implementations which
319 # are both in PYTHON_COMPAT and match any of the patterns passed
320 # as parameters to the function.
321 #
322 # Example:
323 # @CODE
324 # PYTHON_COMPAT=( python{2_7,3_4} )
325 # REQUIRED_USE="doc? ( ^^ ( $(python_gen_useflags 'python2*') ) )"
326 # @CODE
327 #
328 # It will cause the variable to look like:
329 # @CODE
330 # REQUIRED_USE="doc? ( ^^ ( python_single_target_python2_7 ) )"
331 # @CODE
332 python_gen_useflags() {
333         debug-print-function ${FUNCNAME} "${@}"
334
335         local flag_prefix impl pattern
336         local matches=()
337
338         if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
339                 flag_prefix=python_targets
340         else
341                 flag_prefix=python_single_target
342         fi
343
344         for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
345                 for pattern; do
346                         if [[ ${impl} == ${pattern} ]]; then
347                                 matches+=( "${flag_prefix}_${impl}" )
348                                 break
349                         fi
350                 done
351         done
352
353         echo "${matches[@]}"
354 }
355
356 # @FUNCTION: python_gen_cond_dep
357 # @USAGE: <dependency> <pattern> [...]
358 # @DESCRIPTION:
359 # Output a list of <dependency>-ies made conditional to USE flags
360 # of Python implementations which are both in PYTHON_COMPAT and match
361 # any of the patterns passed as the remaining parameters.
362 #
363 # In order to enforce USE constraints on the packages, verbatim
364 # '${PYTHON_USEDEP}' (quoted!) may be placed in the dependency
365 # specification. It will get expanded within the function into a proper
366 # USE dependency string.
367 #
368 # Example:
369 # @CODE
370 # PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
371 # RDEPEND="$(python_gen_cond_dep \
372 #   'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )"
373 # @CODE
374 #
375 # It will cause the variable to look like:
376 # @CODE
377 # RDEPEND="python_single_target_python2_7? (
378 #     dev-python/unittest2[python_targets_python2_7(-)?,...] )
379 #       python_single_target_pypy? (
380 #     dev-python/unittest2[python_targets_pypy(-)?,...] )"
381 # @CODE
382 python_gen_cond_dep() {
383         debug-print-function ${FUNCNAME} "${@}"
384
385         local flag_prefix impl pattern
386         local matches=()
387
388         if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
389                 flag_prefix=python_targets
390         else
391                 flag_prefix=python_single_target
392         fi
393
394         local dep=${1}
395         shift
396
397         for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
398                 for pattern; do
399                         if [[ ${impl} == ${pattern} ]]; then
400                                 # substitute ${PYTHON_USEDEP} if used
401                                 # (since python_gen_usedep() will not return ${PYTHON_USEDEP}
402                                 #  the code is run at most once)
403                                 if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then
404                                         local usedep=$(python_gen_usedep "${@}")
405                                         dep=${dep//\$\{PYTHON_USEDEP\}/${usedep}}
406                                 fi
407
408                                 matches+=( "${flag_prefix}_${impl}? ( ${dep} )" )
409                                 break
410                         fi
411                 done
412         done
413
414         echo "${matches[@]}"
415 }
416
417 # @FUNCTION: python_gen_impl_dep
418 # @USAGE: [<requested-use-flags> [<impl-pattern>...]]
419 # @DESCRIPTION:
420 # Output a dependency on Python implementations with the specified USE
421 # dependency string appended, or no USE dependency string if called
422 # without the argument (or with empty argument). If any implementation
423 # patterns are passed, the output dependencies will be generated only
424 # for the implementations matching them.
425 #
426 # Use this function when you need to request different USE flags
427 # on the Python interpreter depending on package's USE flags. If you
428 # only need a single set of interpreter USE flags, just set
429 # PYTHON_REQ_USE and use ${PYTHON_DEPS} globally.
430 #
431 # Example:
432 # @CODE
433 # PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
434 # RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )"
435 # @CODE
436 #
437 # It will cause the variable to look like:
438 # @CODE
439 # RDEPEND="foo? (
440 #   python_single_target_python2_7? (
441 #     dev-lang/python:2.7[xml(+)] )
442 #       python_single_target_pypy? (
443 #     dev-python/pypy[xml(+)] ) )"
444 # @CODE
445 python_gen_impl_dep() {
446         debug-print-function ${FUNCNAME} "${@}"
447
448         local impl pattern
449         local matches=()
450
451         if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
452                 flag_prefix=python_targets
453         else
454                 flag_prefix=python_single_target
455         fi
456
457         local PYTHON_REQ_USE=${1}
458         shift
459
460         local patterns=( "${@-*}" )
461         for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
462                 for pattern in "${patterns[@]}"; do
463                         if [[ ${impl} == ${pattern} ]]; then
464                                 local PYTHON_PKG_DEP
465                                 python_export "${impl}" PYTHON_PKG_DEP
466                                 matches+=( "${flag_prefix}_${impl}? ( ${PYTHON_PKG_DEP} )" )
467                                 break
468                         fi
469                 done
470         done
471
472         echo "${matches[@]}"
473 }
474
475 # @FUNCTION: python_setup
476 # @DESCRIPTION:
477 # Determine what the selected Python implementation is and set
478 # the Python build environment up for it.
479 python_setup() {
480         debug-print-function ${FUNCNAME} "${@}"
481
482         unset EPYTHON
483
484         # support developer override
485         if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
486                 local impls=( ${PYTHON_COMPAT_OVERRIDE} )
487                 [[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-single-r1"
488
489                 ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
490                 ewarn "implementation will be used:"
491                 ewarn
492                 ewarn " ${PYTHON_COMPAT_OVERRIDE}"
493                 ewarn
494                 ewarn "Dependencies won't be satisfied, and PYTHON_SINGLE_TARGET flags will be ignored."
495
496                 python_export "${impls[0]}" EPYTHON PYTHON
497                 python_wrapper_setup
498                 return
499         fi
500
501         if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
502                 if use "python_targets_${_PYTHON_SUPPORTED_IMPLS[0]}"; then
503                         # Only one supported implementation, enable it explicitly
504                         python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" EPYTHON PYTHON
505                         python_wrapper_setup
506                 fi
507         else
508                 local impl
509                 for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
510                         if use "python_single_target_${impl}"; then
511                                 if [[ ${EPYTHON} ]]; then
512                                         eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python"
513                                         eerror "implementation. Please set it to just one value. If you need"
514                                         eerror "to override the value for a single package, please use package.env"
515                                         eerror "or an equivalent solution (man 5 portage)."
516                                         echo
517                                         die "More than one implementation in PYTHON_SINGLE_TARGET."
518                                 fi
519
520                                 if ! use "python_targets_${impl}"; then
521                                         eerror "The implementation chosen as PYTHON_SINGLE_TARGET must be added"
522                                         eerror "to PYTHON_TARGETS as well. This is in order to ensure that"
523                                         eerror "dependencies are satisfied correctly. We're sorry"
524                                         eerror "for the inconvenience."
525                                         echo
526                                         die "Build target (${impl}) not in PYTHON_TARGETS."
527                                 fi
528
529                                 python_export "${impl}" EPYTHON PYTHON
530                                 python_wrapper_setup
531                         fi
532                 done
533         fi
534
535         if [[ ! ${EPYTHON} ]]; then
536                 eerror "No Python implementation selected for the build. Please set"
537                 if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
538                         eerror "the PYTHON_TARGETS variable in your make.conf to include one"
539                 else
540                         eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one"
541                 fi
542                 eerror "of the following values:"
543                 eerror
544                 eerror "${_PYTHON_SUPPORTED_IMPLS[@]}"
545                 echo
546                 die "No supported Python implementation in PYTHON_SINGLE_TARGET/PYTHON_TARGETS."
547         fi
548 }
549
550 # @FUNCTION: python-single-r1_pkg_setup
551 # @DESCRIPTION:
552 # Runs python_setup.
553 python-single-r1_pkg_setup() {
554         debug-print-function ${FUNCNAME} "${@}"
555
556         [[ ${MERGE_TYPE} != binary ]] && python_setup
557 }
558
559 _PYTHON_SINGLE_R1=1
560 fi