x11-proto/kbproto: arm stable wrt bug #651286
[gentoo.git] / eclass / python-any-r1.eclass
1 # Copyright 1999-2017 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: python-any-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 packages having build-time dependency on Python.
11 # @DESCRIPTION:
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.
16 #
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
20 # as the active one.
21 #
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.
29 #
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
33 # both.
34 #
35 # For more information, please see the wiki:
36 # https://wiki.gentoo.org/wiki/Project:Python/python-any-r1
37
38 case "${EAPI:-0}" in
39         0|1|2|3|4|5|6)
40                 ;;
41         *)
42                 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
43                 ;;
44 esac
45
46 if [[ ! ${_PYTHON_ANY_R1} ]]; then
47
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.'
52 fi
53
54 inherit python-utils-r1
55
56 fi
57
58 EXPORT_FUNCTIONS pkg_setup
59
60 # @ECLASS-VARIABLE: PYTHON_COMPAT
61 # @REQUIRED
62 # @DESCRIPTION:
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
65 # an array.
66 #
67 # Example:
68 # @CODE
69 # PYTHON_COMPAT=( python{2_5,2_6,2_7} )
70 # @CODE
71
72 # @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
73 # @INTERNAL
74 # @DESCRIPTION:
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.
79 #
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.
84 #
85 # Example:
86 # @CODE
87 # PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
88 # @CODE
89
90 # @ECLASS-VARIABLE: PYTHON_REQ_USE
91 # @DEFAULT_UNSET
92 # @DESCRIPTION:
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
96 # use USE defaults.
97 #
98 # Example:
99 # @CODE
100 # PYTHON_REQ_USE="gdbm,ncurses(-)?"
101 # @CODE
102 #
103 # It will cause the Python dependencies to look like:
104 # @CODE
105 # || ( dev-lang/python:X.Y[gdbm,ncurses(-)?] ... )
106 # @CODE
107
108 # @ECLASS-VARIABLE: PYTHON_DEPS
109 # @DESCRIPTION:
110 # This is an eclass-generated Python dependency string for all
111 # implementations listed in PYTHON_COMPAT.
112 #
113 # Any of the supported interpreters will satisfy the dependency.
114 #
115 # Example use:
116 # @CODE
117 # DEPEND="${RDEPEND}
118 #       ${PYTHON_DEPS}"
119 # @CODE
120 #
121 # Example value:
122 # @CODE
123 # || ( dev-lang/python:2.7[gdbm]
124 #       dev-lang/python:2.6[gdbm] )
125 # @CODE
126
127 # @ECLASS-VARIABLE: PYTHON_USEDEP
128 # @DESCRIPTION:
129 # An eclass-generated USE-dependency string for the currently tested
130 # implementation. It is set locally for python_check_deps() call.
131 #
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.
135 #
136 # Example use:
137 # @CODE
138 # python_check_deps() {
139 #       has_version "dev-python/foo[${PYTHON_USEDEP}]"
140 # }
141 # @CODE
142 #
143 # Example value:
144 # @CODE
145 # python_targets_python2_7(-)?,python_single_target_python2_7(+)?
146 # @CODE
147
148 _python_any_set_globals() {
149         local usestr deps i PYTHON_PKG_DEP
150         [[ ${PYTHON_REQ_USE} ]] && usestr="[${PYTHON_REQ_USE}]"
151
152         _python_set_impls
153
154         for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
155                 python_export "${i}" PYTHON_PKG_DEP
156
157                 # note: need to strip '=' slot operator for || deps
158                 deps="${PYTHON_PKG_DEP%=} ${deps}"
159         done
160         deps="|| ( ${deps})"
161
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"
168                 fi
169         else
170                 PYTHON_DEPS=${deps}
171                 readonly PYTHON_DEPS
172         fi
173 }
174 _python_any_set_globals
175 unset -f _python_any_set_globals
176
177 if [[ ! ${_PYTHON_ANY_R1} ]]; then
178
179 # @FUNCTION: python_gen_any_dep
180 # @USAGE: <dependency-block>
181 # @DESCRIPTION:
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.
186 #
187 # This should be used along with an appropriate python_check_deps()
188 # that checks which of the any-of blocks were matched.
189 #
190 # Example use:
191 # @CODE
192 # DEPEND="$(python_gen_any_dep '
193 #       dev-python/foo[${PYTHON_USEDEP}]
194 #       || ( dev-python/bar[${PYTHON_USEDEP}]
195 #               dev-python/baz[${PYTHON_USEDEP}] )')"
196 #
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}]"; }
201 # }
202 # @CODE
203 #
204 # Example value:
205 # @CODE
206 # || (
207 #       (
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(+)?] )
212 #       )
213 #       (
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(+)?] )
218 #       )
219 # )
220 # @CODE
221 python_gen_any_dep() {
222         debug-print-function ${FUNCNAME} "${@}"
223
224         local depstr=${1}
225         [[ ${depstr} ]] || die "No dependency string provided"
226
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
231
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}"
235         done
236         echo "|| ( ${out})"
237 }
238
239 # @FUNCTION: _python_EPYTHON_supported
240 # @USAGE: <epython>
241 # @INTERNAL
242 # @DESCRIPTION:
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} "${@}"
247
248         local EPYTHON=${1}
249         local i=${EPYTHON/./_}
250
251         case "${i}" in
252                 python*|jython*|pypy*)
253                         ;;
254                 *)
255                         ewarn "Invalid EPYTHON: ${EPYTHON}"
256                         return 1
257                         ;;
258         esac
259
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}(+)"
264                                 python_check_deps
265                                 return ${?}
266                         fi
267
268                         return 0
269                 fi
270         elif ! has "${i}" "${_PYTHON_ALL_IMPLS[@]}"; then
271                 ewarn "Invalid EPYTHON: ${EPYTHON}"
272         fi
273         return 1
274 }
275
276 # @FUNCTION: python_setup
277 # @DESCRIPTION:
278 # Determine what the best installed (and supported) Python
279 # implementation is, and set the Python build environment up for it.
280 #
281 # This function will call python_check_deps() if defined.
282 python_setup() {
283         debug-print-function ${FUNCNAME} "${@}"
284
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"
289
290                 ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
291                 ewarn "implementation will be used:"
292                 ewarn
293                 ewarn " ${PYTHON_COMPAT_OVERRIDE}"
294                 ewarn
295                 ewarn "Dependencies won't be satisfied, and EPYTHON/eselect-python will be ignored."
296
297                 python_export "${impls[0]}" EPYTHON PYTHON
298                 python_wrapper_setup
299                 return
300         fi
301
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
306                         python_wrapper_setup
307                         return
308                 fi
309         fi
310
311         # then, try eselect-python
312         local variant i
313         for variant in '' '--python2' '--python3'; do
314                 i=$(eselect python --show ${variant} 2>/dev/null)
315
316                 if [[ ! ${i} ]]; then
317                         # no eselect-python?
318                         break
319                 elif _python_EPYTHON_supported "${i}"; then
320                         python_export "${i}" EPYTHON PYTHON
321                         python_wrapper_setup
322                         return
323                 fi
324         done
325
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
331                         python_wrapper_setup
332                         return
333                 fi
334         done
335
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."
339         echo
340         die "No supported Python implementation installed."
341 }
342
343 # @FUNCTION: python-any-r1_pkg_setup
344 # @DESCRIPTION:
345 # Runs python_setup during from-source installs.
346 #
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} "${@}"
351
352         [[ ${MERGE_TYPE} != binary ]] && python_setup
353 }
354
355 _PYTHON_ANY_R1=1
356 fi