/[gentoo-x86]/eclass/python-r1.eclass
Gentoo

Contents of /eclass/python-r1.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.35 - (show annotations) (download)
Fri Jan 4 01:26:22 2013 UTC (21 months, 3 weeks ago) by floppym
Branch: MAIN
Changes since 1.34: +9 -1 lines
Don't tell the user to set USE_PYTHON when a package does not support python2.7 or python3.2.

1 # Copyright 1999-2013 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header: /var/cvsroot/gentoo-x86/eclass/python-r1.eclass,v 1.34 2013/01/02 21:12:44 mgorny Exp $
4
5 # @ECLASS: python-r1
6 # @MAINTAINER:
7 # Python team <python@gentoo.org>
8 # @AUTHOR:
9 # Author: Michał Górny <mgorny@gentoo.org>
10 # Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
11 # @BLURB: A common, simple eclass for Python packages.
12 # @DESCRIPTION:
13 # A common eclass providing helper functions to build and install
14 # packages supporting being installed for multiple Python
15 # implementations.
16 #
17 # This eclass sets correct IUSE and REQUIRED_USE. It exports PYTHON_DEPS
18 # and PYTHON_USEDEP so you can create correct dependencies for your
19 # package easily. It also provides methods to easily run a command for
20 # each enabled Python implementation and duplicate the sources for them.
21 #
22 # Please note that python-r1 will always inherit python-utils-r1 as
23 # well. Thus, all the functions defined there can be used
24 # in the packages using python-r1, and there is no need ever to inherit
25 # both.
26 #
27 # For more information, please see the python-r1 Developer's Guide:
28 # http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml
29
30 case "${EAPI:-0}" in
31 0|1|2|3|4)
32 die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
33 ;;
34 5)
35 # EAPI=5 is required for meaningful USE default deps
36 # on USE_EXPAND flags
37 ;;
38 *)
39 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
40 ;;
41 esac
42
43 if [[ ! ${_PYTHON_R1} ]]; then
44
45 if [[ ${_PYTHON_SINGLE_R1} ]]; then
46 die 'python-r1.eclass can not be used with python-single-r1.eclass.'
47 elif [[ ${_PYTHON_ANY_R1} ]]; then
48 die 'python-r1.eclass can not be used with python-any-r1.eclass.'
49 fi
50
51 inherit python-utils-r1
52
53 # @ECLASS-VARIABLE: PYTHON_COMPAT
54 # @REQUIRED
55 # @DESCRIPTION:
56 # This variable contains a list of Python implementations the package
57 # supports. It must be set before the `inherit' call. It has to be
58 # an array.
59 #
60 # Example:
61 # @CODE
62 # PYTHON_COMPAT=( python2_5 python2_6 python2_7 )
63 # @CODE
64 #
65 # Please note that you can also use bash brace expansion if you like:
66 # @CODE
67 # PYTHON_COMPAT=( python{2_5,2_6,2_7} )
68 # @CODE
69 if ! declare -p PYTHON_COMPAT &>/dev/null; then
70 if [[ ${CATEGORY}/${PN} == dev-python/python-exec ]]; then
71 PYTHON_COMPAT=( "${_PYTHON_ALL_IMPLS[@]}" )
72 else
73 die 'PYTHON_COMPAT not declared.'
74 fi
75 fi
76
77 # @ECLASS-VARIABLE: PYTHON_REQ_USE
78 # @DEFAULT_UNSET
79 # @DESCRIPTION:
80 # The list of USEflags required to be enabled on the chosen Python
81 # implementations, formed as a USE-dependency string. It should be valid
82 # for all implementations in PYTHON_COMPAT, so it may be necessary to
83 # use USE defaults.
84 #
85 # Example:
86 # @CODE
87 # PYTHON_REQ_USE="gdbm,ncurses(-)?"
88 # @CODE
89 #
90 # It will cause the Python dependencies to look like:
91 # @CODE
92 # python_targets_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?] )
93 # @CODE
94
95 # @ECLASS-VARIABLE: PYTHON_DEPS
96 # @DESCRIPTION:
97 # This is an eclass-generated Python dependency string for all
98 # implementations listed in PYTHON_COMPAT.
99 #
100 # Example use:
101 # @CODE
102 # RDEPEND="${PYTHON_DEPS}
103 # dev-foo/mydep"
104 # DEPEND="${RDEPEND}"
105 # @CODE
106 #
107 # Example value:
108 # @CODE
109 # dev-python/python-exec
110 # python_targets_python2_6? ( dev-lang/python:2.6[gdbm] )
111 # python_targets_python2_7? ( dev-lang/python:2.7[gdbm] )
112 # @CODE
113
114 # @ECLASS-VARIABLE: PYTHON_USEDEP
115 # @DESCRIPTION:
116 # This is an eclass-generated USE-dependency string which can be used to
117 # depend on another Python package being built for the same Python
118 # implementations.
119 #
120 # The generate USE-flag list is compatible with packages using python-r1
121 # and python-distutils-ng eclasses. It must not be used on packages
122 # using python.eclass.
123 #
124 # Example use:
125 # @CODE
126 # RDEPEND="dev-python/foo[${PYTHON_USEDEP}]"
127 # @CODE
128 #
129 # Example value:
130 # @CODE
131 # python_targets_python2_6?,python_targets_python2_7?
132 # @CODE
133
134 _python_set_globals() {
135 local flags=( "${PYTHON_COMPAT[@]/#/python_targets_}" )
136 local optflags=${flags[@]/%/?}
137
138 # A nice QA trick here. Since a python-single-r1 package has to have
139 # at least one PYTHON_SINGLE_TARGET enabled (REQUIRED_USE),
140 # the following check will always fail on those packages. Therefore,
141 # it should prevent developers from mistakenly depending on packages
142 # not supporting multiple Python implementations.
143
144 local flags_st=( "${PYTHON_COMPAT[@]/#/-python_single_target_}" )
145 optflags+=,${flags_st[@]/%/(-)}
146
147 IUSE=${flags[*]}
148 REQUIRED_USE="|| ( ${flags[*]} )"
149 PYTHON_USEDEP=${optflags// /,}
150
151 # 1) well, python-exec would suffice as an RDEP
152 # but no point in making this overcomplex, BDEP doesn't hurt anyone
153 # 2) python-exec should be built with all targets forced anyway
154 # but if new targets were added, we may need to force a rebuild
155 PYTHON_DEPS="dev-python/python-exec[${PYTHON_USEDEP}]"
156 local i PYTHON_PKG_DEP
157 for i in "${PYTHON_COMPAT[@]}"; do
158 python_export "${i}" PYTHON_PKG_DEP
159 PYTHON_DEPS+=" python_targets_${i}? ( ${PYTHON_PKG_DEP} )"
160 done
161 }
162 _python_set_globals
163
164 # @FUNCTION: python_gen_usedep
165 # @USAGE: <pattern> [...]
166 # @DESCRIPTION:
167 # Output a USE dependency string for Python implementations which
168 # are both in PYTHON_COMPAT and match any of the patterns passed
169 # as parameters to the function.
170 #
171 # When all implementations are requested, please use ${PYTHON_USEDEP}
172 # instead. Please also remember to set an appropriate REQUIRED_USE
173 # to avoid ineffective USE flags.
174 #
175 # Example:
176 # @CODE
177 # PYTHON_COMPAT=( python{2_7,3_2} )
178 # DEPEND="doc? ( dev-python/epydoc[$(python_gen_usedep python2*)] )"
179 # @CODE
180 #
181 # It will cause the dependency to look like:
182 # @CODE
183 # DEPEND="doc? ( dev-python/epydoc[python_targets_python2_7?] )"
184 # @CODE
185 python_gen_usedep() {
186 debug-print-function ${FUNCNAME} "${@}"
187
188 local impl pattern
189 local matches=()
190
191 for impl in "${PYTHON_COMPAT[@]}"; do
192 for pattern; do
193 if [[ ${impl} == ${pattern} ]]; then
194 matches+=(
195 "python_targets_${impl}?"
196 "-python_single_target_${impl}(-)"
197 )
198 break
199 fi
200 done
201 done
202
203 local out=${matches[@]}
204 echo ${out// /,}
205 }
206
207 # @FUNCTION: python_gen_useflags
208 # @USAGE: <pattern> [...]
209 # @DESCRIPTION:
210 # Output a list of USE flags for Python implementations which
211 # are both in PYTHON_COMPAT and match any of the patterns passed
212 # as parameters to the function.
213 #
214 # Example:
215 # @CODE
216 # PYTHON_COMPAT=( python{2_7,3_2} )
217 # REQUIRED_USE="doc? ( || ( $(python_gen_useflags python2*) ) )"
218 # @CODE
219 #
220 # It will cause the variable to look like:
221 # @CODE
222 # REQUIRED_USE="doc? ( || ( python_targets_python2_7 ) )"
223 # @CODE
224 python_gen_useflags() {
225 debug-print-function ${FUNCNAME} "${@}"
226
227 local impl pattern
228 local matches=()
229
230 for impl in "${PYTHON_COMPAT[@]}"; do
231 for pattern; do
232 if [[ ${impl} == ${pattern} ]]; then
233 matches+=( "python_targets_${impl}" )
234 break
235 fi
236 done
237 done
238
239 echo ${matches[@]}
240 }
241
242 # @FUNCTION: python_gen_cond_dep
243 # @USAGE: <dependency> <pattern> [...]
244 # @DESCRIPTION:
245 # Output a list of <dependency>-ies made conditional to USE flags
246 # of Python implementations which are both in PYTHON_COMPAT and match
247 # any of the patterns passed as the remaining parameters.
248 #
249 # Please note that USE constraints on the package need to be enforced
250 # separately. Therefore, the dependency usually needs to use
251 # python_gen_usedep as well.
252 #
253 # Example:
254 # @CODE
255 # PYTHON_COMPAT=( python{2_5,2_6,2_7} )
256 # RDEPEND="$(python_gen_cond_dep dev-python/unittest2 python{2_5,2_6})"
257 # @CODE
258 #
259 # It will cause the variable to look like:
260 # @CODE
261 # RDEPEND="python_targets_python2_5? ( dev-python/unittest2 )
262 # python_targets_python2_6? ( dev-python/unittest2 )"
263 # @CODE
264 python_gen_cond_dep() {
265 debug-print-function ${FUNCNAME} "${@}"
266
267 local impl pattern
268 local matches=()
269
270 local dep=${1}
271 shift
272
273 for impl in "${PYTHON_COMPAT[@]}"; do
274 for pattern; do
275 if [[ ${impl} == ${pattern} ]]; then
276 matches+=( "python_targets_${impl}? ( ${dep} )" )
277 break
278 fi
279 done
280 done
281
282 echo ${matches[@]}
283 }
284
285 # @ECLASS-VARIABLE: BUILD_DIR
286 # @DESCRIPTION:
287 # The current build directory. In global scope, it is supposed to
288 # contain an initial build directory; if unset, it defaults to ${S}.
289 #
290 # In functions run by python_foreach_impl(), the BUILD_DIR is locally
291 # set to an implementation-specific build directory. That path is
292 # created through appending a hyphen and the implementation name
293 # to the final component of the initial BUILD_DIR.
294 #
295 # Example value:
296 # @CODE
297 # ${WORKDIR}/foo-1.3-python2_6
298 # @CODE
299
300 # @FUNCTION: python_copy_sources
301 # @DESCRIPTION:
302 # Create a single copy of the package sources (${S}) for each enabled
303 # Python implementation.
304 #
305 # The sources are always copied from S to implementation-specific build
306 # directories respecting BUILD_DIR.
307 python_copy_sources() {
308 debug-print-function ${FUNCNAME} "${@}"
309
310 local impl
311 local bdir=${BUILD_DIR:-${S}}
312
313 debug-print "${FUNCNAME}: bdir = ${bdir}"
314 einfo "Will copy sources from ${S}"
315 # the order is irrelevant here
316 for impl in "${PYTHON_COMPAT[@]}"; do
317 if use "python_targets_${impl}"
318 then
319 local BUILD_DIR=${bdir%%/}-${impl}
320
321 einfo "${impl}: copying to ${BUILD_DIR}"
322 debug-print "${FUNCNAME}: [${impl}] cp ${S} => ${BUILD_DIR}"
323 cp -pr "${S}" "${BUILD_DIR}" || die
324 fi
325 done
326 }
327
328 # @FUNCTION: _python_check_USE_PYTHON
329 # @INTERNAL
330 # @DESCRIPTION:
331 # Check whether USE_PYTHON and PYTHON_TARGETS are in sync. Output
332 # warnings if they are not.
333 _python_check_USE_PYTHON() {
334 debug-print-function ${FUNCNAME} "${@}"
335
336 if [[ ! ${_PYTHON_USE_PYTHON_CHECKED} ]]; then
337 _PYTHON_USE_PYTHON_CHECKED=1
338
339 # python-exec has profile-forced flags.
340 if [[ ${CATEGORY}/${PN} == dev-python/python-exec ]]; then
341 return
342 fi
343
344 _try_eselect() {
345 # The eselect solution will work only with one py2 & py3.
346
347 local impl py2 py3 dis_py2 dis_py3
348 for impl in "${PYTHON_COMPAT[@]}"; do
349 if use "python_targets_${impl}"; then
350 case "${impl}" in
351 python2_*)
352 if [[ ${py2+1} ]]; then
353 debug-print "${FUNCNAME}: -> more than one py2: ${py2} ${impl}"
354 return 1
355 fi
356 py2=${impl/_/.}
357 ;;
358 python3_*)
359 if [[ ${py3+1} ]]; then
360 debug-print "${FUNCNAME}: -> more than one py3: ${py3} ${impl}"
361 return 1
362 fi
363 py3=${impl/_/.}
364 ;;
365 *)
366 return 1
367 ;;
368 esac
369 else
370 case "${impl}" in
371 python2_*)
372 dis_py2=1
373 ;;
374 python3_*)
375 dis_py3=1
376 ;;
377 esac
378 fi
379 done
380
381 # The eselect solution won't work if the disabled Python version
382 # is installed.
383 if [[ ! ${py2+1} && ${dis_py2} ]]; then
384 debug-print "${FUNCNAME}: -> all py2 versions disabled"
385 if ! has python2_7 "${PYTHON_COMPAT[@]}"; then
386 debug-print "${FUNCNAME}: ---> package does not support 2.7"
387 return 0
388 fi
389 if has_version '=dev-lang/python-2*'; then
390 debug-print "${FUNCNAME}: ---> but =python-2* installed!"
391 return 1
392 fi
393 fi
394 if [[ ! ${py3+1} && ${dis_py3} ]]; then
395 debug-print "${FUNCNAME}: -> all py3 versions disabled"
396 if ! has python3_2 "${PYTHON_COMPAT[@]}"; then
397 debug-print "${FUNCNAME}: ---> package does not support 3.2"
398 return 0
399 fi
400 if has_version '=dev-lang/python-3*'; then
401 debug-print "${FUNCNAME}: ---> but =python-3* installed!"
402 return 1
403 fi
404 fi
405
406 local warned
407
408 # Now check whether the correct implementations are active.
409 if [[ ${py2+1} ]]; then
410 local sel_py2=$(eselect python show --python2)
411
412 debug-print "${FUNCNAME}: -> py2 built: ${py2}, active: ${sel_py2}"
413 if [[ ${py2} != ${sel_py2} ]]; then
414 ewarn "Building package for ${py2} only while ${sel_py2} is active."
415 ewarn "Please consider switching the active Python 2 interpreter:"
416 ewarn
417 ewarn " eselect python set --python2 ${py2}"
418 warned=1
419 fi
420 fi
421
422 if [[ ${py3+1} ]]; then
423 local sel_py3=$(eselect python show --python3)
424
425 debug-print "${FUNCNAME}: -> py3 built: ${py3}, active: ${sel_py3}"
426 if [[ ${py3} != ${sel_py3} ]]; then
427 [[ ${warned} ]] && ewarn
428 ewarn "Building package for ${py3} only while ${sel_py3} is active."
429 ewarn "Please consider switching the active Python 3 interpreter:"
430 ewarn
431 ewarn " eselect python set --python3 ${py3}"
432 warned=1
433 fi
434 fi
435
436 if [[ ${warned} ]]; then
437 ewarn
438 ewarn "Please note that after switching the active Python interpreter,"
439 ewarn "you may need to run 'python-updater' to rebuild affected packages."
440 ewarn
441 ewarn "For more information on python.eclass compatibility, please see"
442 ewarn "the appropriate python-r1 User's Guide chapter [1]."
443 ewarn
444 ewarn "[1] http://www.gentoo.org/proj/en/Python/python-r1/user-guide.xml#doc_chap2"
445 fi
446 }
447
448 # If user has no USE_PYTHON, try to avoid it.
449 if [[ ! ${USE_PYTHON} ]]; then
450 debug-print "${FUNCNAME}: trying eselect solution ..."
451 _try_eselect && return
452 fi
453
454 debug-print "${FUNCNAME}: trying USE_PYTHON solution ..."
455 debug-print "${FUNCNAME}: -> USE_PYTHON=${USE_PYTHON}"
456
457 local impl old=${USE_PYTHON} new=() removed=()
458
459 for impl in "${PYTHON_COMPAT[@]}"; do
460 local abi
461 case "${impl}" in
462 python*)
463 abi=${impl#python}
464 ;;
465 jython*)
466 abi=${impl#jython}-jython
467 ;;
468 pypy*)
469 abi=2.7-pypy-${impl#pypy}
470 ;;
471 *)
472 die "Unexpected Python implementation: ${impl}"
473 ;;
474 esac
475 abi=${abi/_/.}
476
477 has "${abi}" ${USE_PYTHON}
478 local has_abi=${?}
479 use "python_targets_${impl}"
480 local has_impl=${?}
481
482 # 0 = has, 1 = does not have
483 if [[ ${has_abi} == 0 && ${has_impl} == 1 ]]; then
484 debug-print "${FUNCNAME}: ---> remove ${abi}"
485 # remove from USE_PYTHON
486 old=${old/${abi}/}
487 removed+=( ${abi} )
488 elif [[ ${has_abi} == 1 && ${has_impl} == 0 ]]; then
489 debug-print "${FUNCNAME}: ---> add ${abi}"
490 # add to USE_PYTHON
491 new+=( ${abi} )
492 fi
493 done
494
495 if [[ ${removed[@]} || ${new[@]} ]]; then
496 old=( ${old} )
497
498 debug-print "${FUNCNAME}: -> old: ${old[@]}"
499 debug-print "${FUNCNAME}: -> new: ${new[@]}"
500 debug-print "${FUNCNAME}: -> removed: ${removed[@]}"
501
502 if [[ ${USE_PYTHON} ]]; then
503 ewarn "It seems that your USE_PYTHON setting lists different Python"
504 ewarn "implementations than your PYTHON_TARGETS variable. Please consider"
505 ewarn "using the following value instead:"
506 ewarn
507 ewarn " USE_PYTHON='\033[35m${old[@]}${new[@]+ \033[1m${new[@]}}\033[0m'"
508
509 if [[ ${removed[@]} ]]; then
510 ewarn
511 ewarn "(removed \033[31m${removed[@]}\033[0m)"
512 fi
513 else
514 ewarn "It seems that you need to set USE_PYTHON to make sure that legacy"
515 ewarn "packages will be built with respect to PYTHON_TARGETS correctly:"
516 ewarn
517 ewarn " USE_PYTHON='\033[35;1m${new[@]}\033[0m'"
518 fi
519
520 ewarn
521 ewarn "Please note that after changing the USE_PYTHON variable, you may need"
522 ewarn "to run 'python-updater' to rebuild affected packages."
523 ewarn
524 ewarn "For more information on python.eclass compatibility, please see"
525 ewarn "the appropriate python-r1 User's Guide chapter [1]."
526 ewarn
527 ewarn "[1] http://www.gentoo.org/proj/en/Python/python-r1/user-guide.xml#doc_chap2"
528 fi
529 fi
530 }
531
532 # @FUNCTION: python_foreach_impl
533 # @USAGE: <command> [<args>...]
534 # @DESCRIPTION:
535 # Run the given command for each of the enabled Python implementations.
536 # If additional parameters are passed, they will be passed through
537 # to the command. If the command fails, python_foreach_impl dies.
538 # If necessary, use ':' to force a successful return.
539 #
540 # For each command being run, EPYTHON, PYTHON and BUILD_DIR are set
541 # locally, and the former two are exported to the command environment.
542 python_foreach_impl() {
543 debug-print-function ${FUNCNAME} "${@}"
544
545 _python_check_USE_PYTHON
546
547 local impl
548 local bdir=${BUILD_DIR:-${S}}
549
550 debug-print "${FUNCNAME}: bdir = ${bdir}"
551 for impl in "${_PYTHON_ALL_IMPLS[@]}"; do
552 if has "${impl}" "${PYTHON_COMPAT[@]}" && use "python_targets_${impl}"
553 then
554 local EPYTHON PYTHON
555 python_export "${impl}" EPYTHON PYTHON
556 local BUILD_DIR=${bdir%%/}-${impl}
557 export EPYTHON PYTHON
558
559 einfo "${EPYTHON}: running ${@}"
560 "${@}" || die "${EPYTHON}: ${1} failed"
561 fi
562 done
563 }
564
565 # @FUNCTION: python_export_best
566 # @USAGE: [<variable>...]
567 # @DESCRIPTION:
568 # Find the best (most preferred) Python implementation enabled
569 # and export given variables for it. If no variables are provided,
570 # EPYTHON & PYTHON will be exported.
571 python_export_best() {
572 debug-print-function ${FUNCNAME} "${@}"
573
574 [[ ${#} -gt 0 ]] || set -- EPYTHON PYTHON
575
576 local impl best
577 for impl in "${_PYTHON_ALL_IMPLS[@]}"; do
578 if has "${impl}" "${PYTHON_COMPAT[@]}" && use "python_targets_${impl}"
579 then
580 best=${impl}
581 fi
582 done
583
584 [[ ${best+1} ]] || die "python_export_best(): no implementation found!"
585
586 debug-print "${FUNCNAME}: Best implementation is: ${impl}"
587 python_export "${impl}" "${@}"
588 }
589
590 # @FUNCTION: python_replicate_script
591 # @USAGE: <path>...
592 # @DESCRIPTION:
593 # Copy the given script to variants for all enabled Python
594 # implementations, then replace it with a symlink to the wrapper.
595 #
596 # All specified files must start with a 'python' shebang. A file not
597 # having a matching shebang will be refused.
598 python_replicate_script() {
599 debug-print-function ${FUNCNAME} "${@}"
600
601 local suffixes=()
602
603 _add_suffix() {
604 suffixes+=( "${EPYTHON}" )
605 }
606 python_foreach_impl _add_suffix
607 debug-print "${FUNCNAME}: suffixes = ( ${suffixes[@]} )"
608
609 local f suffix
610 for suffix in "${suffixes[@]}"; do
611 for f; do
612 local newf=${f}-${suffix}
613
614 debug-print "${FUNCNAME}: ${f} -> ${newf}"
615 cp "${f}" "${newf}" || die
616 done
617
618 _python_rewrite_shebang "${suffix}" "${@/%/-${suffix}}"
619 done
620
621 for f; do
622 _python_ln_rel "${ED}"/usr/bin/python-exec "${f}" || die
623 done
624 }
625
626 _PYTHON_R1=1
627 fi

  ViewVC Help
Powered by ViewVC 1.1.20