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

Contents of /eclass/python-r1.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.22 - (show annotations) (download)
Sat Nov 24 21:07:14 2012 UTC (21 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 # Copyright 1999-2012 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.21 2012/11/24 20:51:14 mgorny Exp $
4
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 #
23 # 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
31 case "${EAPI:-0}" in
32 0|1|2|3)
33 die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
34 ;;
35 4|5)
36 # EAPI=4 needed for REQUIRED_USE
37 ;;
38 *)
39 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
40 ;;
41 esac
42
43 if [[ ! ${_PYTHON_R1} ]]; then
44
45 inherit python-utils-r1
46
47 # @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 python3_1 python3_2 python3_3
55 python2_5 python2_6 python2_7
56 )
57
58 # @ECLASS-VARIABLE: PYTHON_COMPAT
59 # @REQUIRED
60 # @DESCRIPTION:
61 # This variable contains a list of Python implementations the package
62 # 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 #
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 if ! declare -p PYTHON_COMPAT &>/dev/null; then
75 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 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 # It will cause the Python dependencies to look like:
96 # @CODE
97 # python_targets_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?] )
98 # @CODE
99
100 # @ECLASS-VARIABLE: PYTHON_DEPS
101 # @DESCRIPTION:
102 # This is an eclass-generated Python dependency string for all
103 # implementations listed in PYTHON_COMPAT.
104 #
105 # Example use:
106 # @CODE
107 # RDEPEND="${PYTHON_DEPS}
108 # dev-foo/mydep"
109 # DEPEND="${RDEPEND}"
110 # @CODE
111 #
112 # Example value:
113 # @CODE
114 # 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 # @CODE
118
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 # 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 #
129 # Example use:
130 # @CODE
131 # RDEPEND="dev-python/foo[${PYTHON_USEDEP}]"
132 # @CODE
133 #
134 # Example value:
135 # @CODE
136 # python_targets_python2_6?,python_targets_python2_7?
137 # @CODE
138
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 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 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 PYTHON_DEPS+=" python_targets_${i}? ( ${d}:${v/_/.}${usestr} )"
171 done
172 }
173 _python_set_globals
174
175 # @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 # @FUNCTION: python_copy_sources
191 # @DESCRIPTION:
192 # Create a single copy of the package sources (${S}) for each enabled
193 # Python implementation.
194 #
195 # The sources are always copied from S to implementation-specific build
196 # directories respecting BUILD_DIR.
197 python_copy_sources() {
198 debug-print-function ${FUNCNAME} "${@}"
199
200 if [[ ${_PYTHON_SINGLE_R1} ]]; then
201 die "${FUNCNAME} must not be used with python-single-r1 eclass."
202 fi
203
204 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 # @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 # @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 # 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 python_foreach_impl() {
429 debug-print-function ${FUNCNAME} "${@}"
430
431 if [[ ${_PYTHON_SINGLE_R1} ]]; then
432 die "${FUNCNAME} must not be used with python-single-r1 eclass."
433 fi
434
435 _python_check_USE_PYTHON
436
437 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 python_export "${impl}" EPYTHON PYTHON
446 local BUILD_DIR=${bdir%%/}-${impl}
447 export EPYTHON PYTHON
448
449 einfo "${EPYTHON}: running ${@}"
450 "${@}" || die "${EPYTHON}: ${1} failed"
451 fi
452 done
453 }
454
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 if [[ ${_PYTHON_SINGLE_R1} ]]; then
465 die "${FUNCNAME} must not be used with python-single-r1 eclass."
466 fi
467
468 [[ ${#} -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
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 if [[ ${_PYTHON_SINGLE_R1} ]]; then
496 die "${FUNCNAME} must not be used with python-single-r1 eclass."
497 fi
498
499 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
524 _PYTHON_R1=1
525 fi

  ViewVC Help
Powered by ViewVC 1.1.20