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

Contents of /eclass/python-r1.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.22 - (hide annotations) (download)
Sat Nov 24 21:07:14 2012 UTC (19 months, 3 weeks ago) by mgorny
Branch: MAIN
Changes since 1.21: +24 -3 lines
Fix EAPI checks, add double- and colliding include guards.

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

  ViewVC Help
Powered by ViewVC 1.1.20