1 # Copyright 1999-2015 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
5 # @ECLASS: python-single-r1.eclass
7 # Python team <python@gentoo.org>
9 # Author: Michał Górny <mgorny@gentoo.org>
10 # Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
11 # @BLURB: An eclass for Python packages not installed for multiple implementations.
13 # An extension of the python-r1 eclass suite for packages which
14 # don't support being installed for multiple Python implementations.
15 # This mostly includes tools embedding Python.
17 # This eclass extends the IUSE and REQUIRED_USE set by python-r1
18 # to request the PYTHON_SINGLE_TARGET when the inheriting ebuild
19 # can be supported by more than one Python implementation. It also
20 # replaces PYTHON_USEDEP and PYTHON_DEPS with a more suitable form.
22 # Please note that packages support multiple Python implementations
23 # (using python-r1 eclass) can not depend on packages not supporting
24 # them (using this eclass).
26 # Please note that python-single-r1 will always inherit python-utils-r1
27 # as well. Thus, all the functions defined there can be used
28 # in the packages using python-single-r1, and there is no need ever
31 # For more information, please see the wiki:
32 # https://wiki.gentoo.org/wiki/Project:Python/python-single-r1
36 die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
39 # EAPI=4 is only allowed on legacy packages
40 if [[ ${CATEGORY}/${P} == app-arch/threadzip-1.2 ]]; then
42 elif [[ ${CATEGORY}/${P} == media-libs/lv2-1.8.0 ]]; then
44 elif [[ ${CATEGORY}/${P} == media-libs/lv2-1.10.0 ]]; then
46 elif [[ ${CATEGORY}/${P} == sys-apps/paludis-1* ]]; then
48 elif [[ ${CATEGORY}/${P} == sys-apps/paludis-2.[02].0 ]]; then
50 elif [[ ${CATEGORY}/${P} == sys-apps/util-linux-2.2[456]* ]]; then
52 elif [[ ${CATEGORY}/${P} == */gdb-7.[78]* ]]; then
55 die "Unsupported EAPI=${EAPI:-4} (too old, allowed only on restricted set of packages) for ${ECLASS}"
59 # EAPI=5 is required for sane USE_EXPAND dependencies
62 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
66 if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
68 if [[ ${_PYTHON_R1} ]]; then
69 die 'python-single-r1.eclass can not be used with python-r1.eclass.'
70 elif [[ ${_PYTHON_ANY_R1} ]]; then
71 die 'python-single-r1.eclass can not be used with python-any-r1.eclass.'
74 inherit python-utils-r1
78 EXPORT_FUNCTIONS pkg_setup
80 if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
82 # @ECLASS-VARIABLE: PYTHON_COMPAT
85 # This variable contains a list of Python implementations the package
86 # supports. It must be set before the `inherit' call. It has to be
91 # PYTHON_COMPAT=( python2_7 python3_3 python3_4} )
94 # Please note that you can also use bash brace expansion if you like:
96 # PYTHON_COMPAT=( python2_7 python3_{3,4} )
99 # @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
102 # This variable can be used when working with ebuilds to override
103 # the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
104 # which package will be built for. It needs to be specified
105 # in the calling environment, and not in ebuilds.
107 # It should be noted that in order to preserve metadata immutability,
108 # PYTHON_COMPAT_OVERRIDE does not affect IUSE nor dependencies.
109 # The state of PYTHON_TARGETS and PYTHON_SINGLE_TARGET is ignored,
110 # and the implementation in PYTHON_COMPAT_OVERRIDE is built instead.
111 # Dependencies need to be satisfied manually.
115 # PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
118 # @ECLASS-VARIABLE: PYTHON_REQ_USE
121 # The list of USEflags required to be enabled on the chosen Python
122 # implementations, formed as a USE-dependency string. It should be valid
123 # for all implementations in PYTHON_COMPAT, so it may be necessary to
126 # This should be set before calling `inherit'.
130 # PYTHON_REQ_USE="gdbm,ncurses(-)?"
133 # It will cause the Python dependencies to look like:
135 # python_single_target_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?] )
138 # @ECLASS-VARIABLE: PYTHON_DEPS
140 # This is an eclass-generated Python dependency string for all
141 # implementations listed in PYTHON_COMPAT.
143 # The dependency string is conditional on PYTHON_SINGLE_TARGET.
147 # RDEPEND="${PYTHON_DEPS}
149 # DEPEND="${RDEPEND}"
154 # dev-lang/python-exec:=
155 # python_single_target_python2_7? ( dev-lang/python:2.7[gdbm] )
156 # python_single_target_pypy? ( virtual/pypy[gdbm] )
159 # @ECLASS-VARIABLE: PYTHON_USEDEP
161 # This is an eclass-generated USE-dependency string which can be used to
162 # depend on another Python package being built for the same Python
165 # The generate USE-flag list is compatible with packages using python-r1,
166 # python-single-r1 and python-distutils-ng eclasses. It must not be used
167 # on packages using python.eclass.
171 # RDEPEND="dev-python/foo[${PYTHON_USEDEP}]"
176 # python_targets_python2_7(-)?,python_single_target_python3_4(+)?
179 # @ECLASS-VARIABLE: PYTHON_REQUIRED_USE
181 # This is an eclass-generated required-use expression which ensures the following
182 # when more than one python implementation is possible:
183 # 1. Exactly one PYTHON_SINGLE_TARGET value has been enabled.
184 # 2. The selected PYTHON_SINGLE_TARGET value is enabled in PYTHON_TARGETS.
186 # This expression should be utilized in an ebuild by including it in
187 # REQUIRED_USE, optionally behind a use flag.
191 # REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"
196 # python_single_target_python2_7? ( python_targets_python2_7 )
197 # python_single_target_python3_3? ( python_targets_python3_3 )
198 # ^^ ( python_single_target_python2_7 python_single_target_python3_3 )
201 _python_single_set_globals() {
205 local i PYTHON_PKG_DEP
207 local flags_mt=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" )
208 local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_single_target_}" )
209 local unflags=( "${_PYTHON_UNSUPPORTED_IMPLS[@]/#/-python_single_target_}" )
211 local optflags=${flags_mt[@]/%/(-)?},${unflags[@]/%/(-)}
213 IUSE="${flags_mt[*]}"
215 if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
216 # There is only one supported implementation; set IUSE and other
217 # variables without PYTHON_SINGLE_TARGET.
218 PYTHON_REQUIRED_USE="${flags_mt[*]}"
219 python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" PYTHON_PKG_DEP
220 PYTHON_DEPS="${PYTHON_PKG_DEP} "
221 # Force on the python_single_target_* flag for this impl, so
222 # that any dependencies that inherit python-single-r1 and
223 # happen to have multiple implementations will still need
224 # to bound by the implementation used by this package.
225 optflags+=,${flags[0]/%/(+)}
227 # Multiple supported implementations; honor PYTHON_SINGLE_TARGET.
229 PYTHON_REQUIRED_USE="^^ ( ${flags[*]} )"
230 # Ensure deps honor the same python_single_target_* flag as is set
232 optflags+=,${flags[@]/%/(+)?}
234 for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
235 # The chosen targets need to be in PYTHON_TARGETS as well.
236 # This is in order to enforce correct dependencies on packages
237 # supporting multiple implementations.
238 PYTHON_REQUIRED_USE+=" python_single_target_${i}? ( python_targets_${i} )"
240 python_export "${i}" PYTHON_PKG_DEP
241 PYTHON_DEPS+="python_single_target_${i}? ( ${PYTHON_PKG_DEP} ) "
244 PYTHON_USEDEP=${optflags// /,}
246 # 1) well, python-exec would suffice as an RDEP
247 # but no point in making this overcomplex, BDEP doesn't hurt anyone
248 # 2) python-exec should be built with all targets forced anyway
249 # but if new targets were added, we may need to force a rebuild
250 # 3) use whichever python-exec slot installed in EAPI 5. For EAPI 4,
251 # just fix :2 since := deps are not supported.
252 if [[ ${_PYTHON_WANT_PYTHON_EXEC2} == 0 ]]; then
253 die "python-exec:0 is no longer supported, please fix your ebuild to work with python-exec:2"
254 elif [[ ${EAPI} != 4 ]]; then
255 PYTHON_DEPS+=">=dev-lang/python-exec-2:=[${PYTHON_USEDEP}]"
257 PYTHON_DEPS+="dev-lang/python-exec:2[${PYTHON_USEDEP}]"
259 readonly PYTHON_DEPS PYTHON_REQUIRED_USE PYTHON_USEDEP
261 _python_single_set_globals
262 unset -f _python_single_set_globals
264 # @FUNCTION: python_gen_usedep
265 # @USAGE: <pattern> [...]
267 # Output a USE dependency string for Python implementations which
268 # are both in PYTHON_COMPAT and match any of the patterns passed
269 # as parameters to the function.
271 # Remember to escape or quote the patterns to prevent shell filename
274 # When all implementations are requested, please use ${PYTHON_USEDEP}
275 # instead. Please also remember to set an appropriate REQUIRED_USE
276 # to avoid ineffective USE flags.
280 # PYTHON_COMPAT=( python{2_7,3_4} )
281 # DEPEND="doc? ( dev-python/epydoc[$(python_gen_usedep 'python2*')] )"
284 # It will cause the dependency to look like:
286 # DEPEND="doc? ( dev-python/epydoc[python_targets_python2_7(-)?,...] )"
288 python_gen_usedep() {
289 debug-print-function ${FUNCNAME} "${@}"
294 for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
296 if [[ ${impl} == ${pattern} ]]; then
298 "python_targets_${impl}(-)?"
299 "python_single_target_${impl}(+)?"
306 [[ ${matches[@]} ]] || die "No supported implementations match python_gen_usedep patterns: ${@}"
308 local out=${matches[@]}
312 # @FUNCTION: python_gen_useflags
313 # @USAGE: <pattern> [...]
315 # Output a list of USE flags for Python implementations which
316 # are both in PYTHON_COMPAT and match any of the patterns passed
317 # as parameters to the function.
321 # PYTHON_COMPAT=( python{2_7,3_4} )
322 # REQUIRED_USE="doc? ( ^^ ( $(python_gen_useflags 'python2*') ) )"
325 # It will cause the variable to look like:
327 # REQUIRED_USE="doc? ( ^^ ( python_single_target_python2_7 ) )"
329 python_gen_useflags() {
330 debug-print-function ${FUNCNAME} "${@}"
332 local flag_prefix impl pattern
335 if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
336 flag_prefix=python_targets
338 flag_prefix=python_single_target
341 for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
343 if [[ ${impl} == ${pattern} ]]; then
344 matches+=( "${flag_prefix}_${impl}" )
353 # @FUNCTION: python_gen_cond_dep
354 # @USAGE: <dependency> <pattern> [...]
356 # Output a list of <dependency>-ies made conditional to USE flags
357 # of Python implementations which are both in PYTHON_COMPAT and match
358 # any of the patterns passed as the remaining parameters.
360 # In order to enforce USE constraints on the packages, verbatim
361 # '${PYTHON_USEDEP}' (quoted!) may be placed in the dependency
362 # specification. It will get expanded within the function into a proper
363 # USE dependency string.
367 # PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
368 # RDEPEND="$(python_gen_cond_dep \
369 # 'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )"
372 # It will cause the variable to look like:
374 # RDEPEND="python_single_target_python2_7? (
375 # dev-python/unittest2[python_targets_python2_7(-)?,...] )
376 # python_single_target_pypy? (
377 # dev-python/unittest2[python_targets_pypy(-)?,...] )"
379 python_gen_cond_dep() {
380 debug-print-function ${FUNCNAME} "${@}"
382 local flag_prefix impl pattern
385 if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
386 flag_prefix=python_targets
388 flag_prefix=python_single_target
394 for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
396 if [[ ${impl} == ${pattern} ]]; then
397 # substitute ${PYTHON_USEDEP} if used
398 # (since python_gen_usedep() will not return ${PYTHON_USEDEP}
399 # the code is run at most once)
400 if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then
401 local usedep=$(python_gen_usedep "${@}")
402 dep=${dep//\$\{PYTHON_USEDEP\}/${usedep}}
405 matches+=( "${flag_prefix}_${impl}? ( ${dep} )" )
414 # @FUNCTION: python_gen_impl_dep
415 # @USAGE: [<requested-use-flags> [<impl-pattern>...]]
417 # Output a dependency on Python implementations with the specified USE
418 # dependency string appended, or no USE dependency string if called
419 # without the argument (or with empty argument). If any implementation
420 # patterns are passed, the output dependencies will be generated only
421 # for the implementations matching them.
423 # Use this function when you need to request different USE flags
424 # on the Python interpreter depending on package's USE flags. If you
425 # only need a single set of interpreter USE flags, just set
426 # PYTHON_REQ_USE and use ${PYTHON_DEPS} globally.
430 # PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
431 # RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )"
434 # It will cause the variable to look like:
437 # python_single_target_python2_7? (
438 # dev-lang/python:2.7[xml(+)] )
439 # python_single_target_pypy? (
440 # dev-python/pypy[xml(+)] ) )"
442 python_gen_impl_dep() {
443 debug-print-function ${FUNCNAME} "${@}"
448 if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
449 flag_prefix=python_targets
451 flag_prefix=python_single_target
454 local PYTHON_REQ_USE=${1}
457 local patterns=( "${@-*}" )
458 for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
459 for pattern in "${patterns[@]}"; do
460 if [[ ${impl} == ${pattern} ]]; then
462 python_export "${impl}" PYTHON_PKG_DEP
463 matches+=( "${flag_prefix}_${impl}? ( ${PYTHON_PKG_DEP} )" )
472 # @FUNCTION: python_setup
474 # Determine what the selected Python implementation is and set
475 # the Python build environment up for it.
477 debug-print-function ${FUNCNAME} "${@}"
481 # support developer override
482 if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
483 local impls=( ${PYTHON_COMPAT_OVERRIDE} )
484 [[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-single-r1"
486 ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
487 ewarn "implementation will be used:"
489 ewarn " ${PYTHON_COMPAT_OVERRIDE}"
491 ewarn "Dependencies won't be satisfied, and PYTHON_SINGLE_TARGET flags will be ignored."
493 python_export "${impls[0]}" EPYTHON PYTHON
498 if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
499 if use "python_targets_${_PYTHON_SUPPORTED_IMPLS[0]}"; then
500 # Only one supported implementation, enable it explicitly
501 python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" EPYTHON PYTHON
506 for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
507 if use "python_single_target_${impl}"; then
508 if [[ ${EPYTHON} ]]; then
509 eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python"
510 eerror "implementation. Please set it to just one value. If you need"
511 eerror "to override the value for a single package, please use package.env"
512 eerror "or an equivalent solution (man 5 portage)."
514 die "More than one implementation in PYTHON_SINGLE_TARGET."
517 if ! use "python_targets_${impl}"; then
518 eerror "The implementation chosen as PYTHON_SINGLE_TARGET must be added"
519 eerror "to PYTHON_TARGETS as well. This is in order to ensure that"
520 eerror "dependencies are satisfied correctly. We're sorry"
521 eerror "for the inconvenience."
523 die "Build target (${impl}) not in PYTHON_TARGETS."
526 python_export "${impl}" EPYTHON PYTHON
532 if [[ ! ${EPYTHON} ]]; then
533 eerror "No Python implementation selected for the build. Please set"
534 if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
535 eerror "the PYTHON_TARGETS variable in your make.conf to include one"
537 eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one"
539 eerror "of the following values:"
541 eerror "${_PYTHON_SUPPORTED_IMPLS[@]}"
543 die "No supported Python implementation in PYTHON_SINGLE_TARGET/PYTHON_TARGETS."
547 # @FUNCTION: python-single-r1_pkg_setup
550 python-single-r1_pkg_setup() {
551 debug-print-function ${FUNCNAME} "${@}"
553 [[ ${MERGE_TYPE} != binary ]] && python_setup