1 # Copyright 1999-2017 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
4 # @ECLASS: python-any-r1.eclass
6 # Python team <python@gentoo.org>
8 # Author: Michał Górny <mgorny@gentoo.org>
9 # Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
10 # @BLURB: An eclass for packages having build-time dependency on Python.
12 # A minimal eclass for packages which need any Python interpreter
13 # installed without a need for explicit choice and invariability.
14 # This usually involves packages requiring Python at build-time
15 # but having no other relevance to it.
17 # This eclass provides a minimal PYTHON_DEPS variable with a dependency
18 # string on any of the supported Python implementations. It also exports
19 # pkg_setup() which finds the best supported implementation and sets it
22 # Optionally, you can define a python_check_deps() function. It will
23 # be called by the eclass with EPYTHON set to each matching Python
24 # implementation and it is expected to check whether the implementation
25 # fulfills the package requirements. You can use the locally exported
26 # PYTHON_USEDEP to check USE-dependencies of relevant packages. It
27 # should return a true value (0) if the Python implementation fulfills
28 # the requirements, a false value (non-zero) otherwise.
30 # Please note that python-any-r1 will always inherit python-utils-r1
31 # as well. Thus, all the functions defined there can be used in the
32 # packages using python-any-r1, and there is no need ever to inherit
35 # For more information, please see the wiki:
36 # https://wiki.gentoo.org/wiki/Project:Python/python-any-r1
42 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
46 if [[ ! ${_PYTHON_ANY_R1} ]]; then
48 if [[ ${_PYTHON_R1} ]]; then
49 die 'python-any-r1.eclass can not be used with python-r1.eclass.'
50 elif [[ ${_PYTHON_SINGLE_R1} ]]; then
51 die 'python-any-r1.eclass can not be used with python-single-r1.eclass.'
54 inherit python-utils-r1
58 EXPORT_FUNCTIONS pkg_setup
60 # @ECLASS-VARIABLE: PYTHON_COMPAT
63 # This variable contains a list of Python implementations the package
64 # supports. It must be set before the `inherit' call. It has to be
69 # PYTHON_COMPAT=( python{2_5,2_6,2_7} )
72 # @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
75 # This variable can be used when working with ebuilds to override
76 # the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
77 # which will be used to build the package. It needs to be specified
78 # in the calling environment, and not in ebuilds.
80 # It should be noted that in order to preserve metadata immutability,
81 # PYTHON_COMPAT_OVERRIDE does not affect dependencies. The value of
82 # EPYTHON and eselect-python preferences are ignored. Dependencies need
83 # to be satisfied manually.
87 # PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
90 # @ECLASS-VARIABLE: PYTHON_REQ_USE
93 # The list of USEflags required to be enabled on the Python
94 # implementations, formed as a USE-dependency string. It should be valid
95 # for all implementations in PYTHON_COMPAT, so it may be necessary to
100 # PYTHON_REQ_USE="gdbm,ncurses(-)?"
103 # It will cause the Python dependencies to look like:
105 # || ( dev-lang/python:X.Y[gdbm,ncurses(-)?] ... )
108 # @ECLASS-VARIABLE: PYTHON_DEPS
110 # This is an eclass-generated Python dependency string for all
111 # implementations listed in PYTHON_COMPAT.
113 # Any of the supported interpreters will satisfy the dependency.
123 # || ( dev-lang/python:2.7[gdbm]
124 # dev-lang/python:2.6[gdbm] )
127 # @ECLASS-VARIABLE: PYTHON_USEDEP
129 # An eclass-generated USE-dependency string for the currently tested
130 # implementation. It is set locally for python_check_deps() call.
132 # The generate USE-flag list is compatible with packages using python-r1,
133 # python-single-r1 and python-distutils-ng eclasses. It must not be used
134 # on packages using python.eclass.
138 # python_check_deps() {
139 # has_version "dev-python/foo[${PYTHON_USEDEP}]"
145 # python_targets_python2_7(-)?,python_single_target_python2_7(+)?
148 _python_any_set_globals() {
149 local usestr deps i PYTHON_PKG_DEP
150 [[ ${PYTHON_REQ_USE} ]] && usestr="[${PYTHON_REQ_USE}]"
154 for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
155 python_export "${i}" PYTHON_PKG_DEP
157 # note: need to strip '=' slot operator for || deps
158 deps="${PYTHON_PKG_DEP%=} ${deps}"
162 if [[ ${PYTHON_DEPS+1} ]]; then
163 if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
164 eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
165 eerror "Before: ${PYTHON_DEPS}"
166 eerror "Now : ${deps}"
167 die "PYTHON_DEPS integrity check failed"
174 _python_any_set_globals
175 unset -f _python_any_set_globals
177 if [[ ! ${_PYTHON_ANY_R1} ]]; then
179 # @FUNCTION: python_gen_any_dep
180 # @USAGE: <dependency-block>
182 # Generate an any-of dependency that enforces a version match between
183 # the Python interpreter and Python packages. <dependency-block> needs
184 # to list one or more dependencies with verbatim '${PYTHON_USEDEP}'
185 # references (quoted!) that will get expanded inside the function.
187 # This should be used along with an appropriate python_check_deps()
188 # that checks which of the any-of blocks were matched.
192 # DEPEND="$(python_gen_any_dep '
193 # dev-python/foo[${PYTHON_USEDEP}]
194 # || ( dev-python/bar[${PYTHON_USEDEP}]
195 # dev-python/baz[${PYTHON_USEDEP}] )')"
197 # python_check_deps() {
198 # has_version "dev-python/foo[${PYTHON_USEDEP}]" \
199 # && { has_version "dev-python/bar[${PYTHON_USEDEP}]" \
200 # || has_version "dev-python/baz[${PYTHON_USEDEP}]"; }
208 # dev-lang/python:2.7
209 # dev-python/foo[python_targets_python2_7(-)?,python_single_target_python2_7(+)?]
210 # || ( dev-python/bar[python_targets_python2_7(-)?,python_single_target_python2_7(+)?]
211 # dev-python/baz[python_targets_python2_7(-)?,python_single_target_python2_7(+)?] )
214 # dev-lang/python:3.3
215 # dev-python/foo[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
216 # || ( dev-python/bar[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
217 # dev-python/baz[python_targets_python3_3(-)?,python_single_target_python3_3(+)?] )
221 python_gen_any_dep() {
222 debug-print-function ${FUNCNAME} "${@}"
225 [[ ${depstr} ]] || die "No dependency string provided"
227 local i PYTHON_PKG_DEP out=
228 for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
229 local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
230 python_export "${i}" PYTHON_PKG_DEP
232 local i_depstr=${depstr//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
233 # note: need to strip '=' slot operator for || deps
234 out="( ${PYTHON_PKG_DEP%=} ${i_depstr} ) ${out}"
239 # @FUNCTION: _python_EPYTHON_supported
243 # Check whether the specified implementation is supported by package
244 # (specified in PYTHON_COMPAT). Calls python_check_deps() if declared.
245 _python_EPYTHON_supported() {
246 debug-print-function ${FUNCNAME} "${@}"
249 local i=${EPYTHON/./_}
252 python*|jython*|pypy*)
255 ewarn "Invalid EPYTHON: ${EPYTHON}"
260 if has "${i}" "${_PYTHON_SUPPORTED_IMPLS[@]}"; then
261 if python_is_installed "${i}"; then
262 if declare -f python_check_deps >/dev/null; then
263 local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
270 elif ! has "${i}" "${_PYTHON_ALL_IMPLS[@]}"; then
271 ewarn "Invalid EPYTHON: ${EPYTHON}"
276 # @FUNCTION: python_setup
278 # Determine what the best installed (and supported) Python
279 # implementation is, and set the Python build environment up for it.
281 # This function will call python_check_deps() if defined.
283 debug-print-function ${FUNCNAME} "${@}"
285 # support developer override
286 if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
287 local impls=( ${PYTHON_COMPAT_OVERRIDE} )
288 [[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-any-r1"
290 ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
291 ewarn "implementation will be used:"
293 ewarn " ${PYTHON_COMPAT_OVERRIDE}"
295 ewarn "Dependencies won't be satisfied, and EPYTHON/eselect-python will be ignored."
297 python_export "${impls[0]}" EPYTHON PYTHON
302 # first, try ${EPYTHON}... maybe it's good enough for us.
303 if [[ ${EPYTHON} ]]; then
304 if _python_EPYTHON_supported "${EPYTHON}"; then
305 python_export EPYTHON PYTHON
311 # then, try eselect-python
313 for variant in '' '--python2' '--python3'; do
314 i=$(eselect python --show ${variant} 2>/dev/null)
316 if [[ ! ${i} ]]; then
319 elif _python_EPYTHON_supported "${i}"; then
320 python_export "${i}" EPYTHON PYTHON
326 # fallback to best installed impl.
327 # (reverse iteration over _PYTHON_SUPPORTED_IMPLS)
328 for (( i = ${#_PYTHON_SUPPORTED_IMPLS[@]} - 1; i >= 0; i-- )); do
329 python_export "${_PYTHON_SUPPORTED_IMPLS[i]}" EPYTHON PYTHON
330 if _python_EPYTHON_supported "${EPYTHON}"; then
336 eerror "No Python implementation found for the build. This is usually"
337 eerror "a bug in the ebuild. Please report it to bugs.gentoo.org"
338 eerror "along with the build log."
340 die "No supported Python implementation installed."
343 # @FUNCTION: python-any-r1_pkg_setup
345 # Runs python_setup during from-source installs.
347 # In a binary package installs is a no-op. If you need Python in pkg_*
348 # phases of a binary package, call python_setup directly.
349 python-any-r1_pkg_setup() {
350 debug-print-function ${FUNCNAME} "${@}"
352 [[ ${MERGE_TYPE} != binary ]] && python_setup