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

Contents of /eclass/python-utils-r1.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.16 - (hide annotations) (download)
Tue Jan 29 21:12:33 2013 UTC (5 years, 5 months ago) by mgorny
Branch: MAIN
Changes since 1.15: +6 -6 lines
Disable pypy1.8 globally.

1 mgorny 1.12 # Copyright 1999-2013 Gentoo Foundation
2 mgorny 1.1 # Distributed under the terms of the GNU General Public License v2
3 mgorny 1.16 # $Header: /var/cvsroot/gentoo-x86/eclass/python-utils-r1.eclass,v 1.15 2013/01/27 16:35:33 mgorny Exp $
4 mgorny 1.1
5     # @ECLASS: python-utils-r1
6     # @MAINTAINER:
7 mgorny 1.12 # Python team <python@gentoo.org>
8 mgorny 1.1 # @AUTHOR:
9     # Author: Michał Górny <mgorny@gentoo.org>
10     # Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
11     # @BLURB: Utility functions for packages with Python parts.
12     # @DESCRIPTION:
13     # An utility eclass providing functions to query Python implementations,
14     # install Python modules and scripts.
15     #
16     # This eclass does not set any metadata variables nor export any phase
17     # functions. It can be inherited safely.
18     #
19     # For more information, please see the python-r1 Developer's Guide:
20     # http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml
21    
22 mgorny 1.2 case "${EAPI:-0}" in
23 mgorny 1.5 0|1|2|3|4|5)
24 mgorny 1.1 # EAPI=4 makes die behavior clear
25     ;;
26     *)
27     die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
28     ;;
29     esac
30    
31 mgorny 1.2 if [[ ${_PYTHON_ECLASS_INHERITED} ]]; then
32     die 'python-r1 suite eclasses can not be used with python.eclass.'
33     fi
34    
35     if [[ ! ${_PYTHON_UTILS_R1} ]]; then
36    
37 mgorny 1.1 inherit multilib
38    
39 mgorny 1.4 # @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS
40     # @INTERNAL
41     # @DESCRIPTION:
42     # All supported Python implementations, most preferred last.
43     _PYTHON_ALL_IMPLS=(
44     jython2_5
45 mgorny 1.16 pypy1_9 pypy2_0
46 mgorny 1.4 python3_1 python3_2 python3_3
47     python2_5 python2_6 python2_7
48     )
49    
50 mgorny 1.14 # @FUNCTION: _python_impl_supported
51     # @USAGE: <impl>
52     # @INTERNAL
53     # @DESCRIPTION:
54     # Check whether the implementation <impl> (PYTHON_COMPAT-form)
55     # is still supported.
56     #
57     # Returns 0 if the implementation is valid and supported. If it is
58     # unsupported, returns 1 -- and the caller should ignore the entry.
59     # If it is invalid, dies with an appopriate error messages.
60     _python_impl_supported() {
61     debug-print-function ${FUNCNAME} "${@}"
62    
63     [[ ${#} -eq 1 ]] || die "${FUNCNAME}: takes exactly 1 argument (impl)."
64    
65     local impl=${1}
66    
67     # keep in sync with _PYTHON_ALL_IMPLS!
68     # (not using that list because inline patterns shall be faster)
69     case "${impl}" in
70 mgorny 1.16 python2_[567]|python3_[123]|pypy1_9|pypy2_0|jython2_5)
71 mgorny 1.14 return 0
72     ;;
73 mgorny 1.16 pypy1_8)
74     return 1
75     ;;
76 mgorny 1.14 *)
77     die "Invalid implementation in PYTHON_COMPAT: ${impl}"
78     esac
79     }
80    
81 mgorny 1.1 # @ECLASS-VARIABLE: PYTHON
82     # @DESCRIPTION:
83     # The absolute path to the current Python interpreter.
84     #
85     # Set and exported only in commands run by python_foreach_impl().
86     #
87     # Example value:
88     # @CODE
89     # /usr/bin/python2.6
90     # @CODE
91    
92     # @ECLASS-VARIABLE: EPYTHON
93     # @DESCRIPTION:
94     # The executable name of the current Python interpreter.
95     #
96     # This variable is used consistently with python.eclass.
97     #
98     # Set and exported only in commands run by python_foreach_impl().
99     #
100     # Example value:
101     # @CODE
102     # python2.6
103     # @CODE
104    
105     # @ECLASS-VARIABLE: PYTHON_SITEDIR
106     # @DESCRIPTION:
107     # The path to Python site-packages directory.
108     #
109     # Set and exported on request using python_export().
110     #
111     # Example value:
112     # @CODE
113     # /usr/lib64/python2.6/site-packages
114     # @CODE
115    
116 mgorny 1.10 # @ECLASS-VARIABLE: PYTHON_INCLUDEDIR
117     # @DESCRIPTION:
118     # The path to Python include directory.
119     #
120     # Set and exported on request using python_export().
121     #
122     # Example value:
123     # @CODE
124     # /usr/include/python2.6
125     # @CODE
126    
127 mgorny 1.9 # @ECLASS-VARIABLE: PYTHON_PKG_DEP
128     # @DESCRIPTION:
129     # The complete dependency on a particular Python package as a string.
130     #
131     # Set and exported on request using python_export().
132     #
133     # Example value:
134     # @CODE
135     # dev-lang/python:2.7[xml]
136     # @CODE
137    
138 mgorny 1.1 # @FUNCTION: python_export
139     # @USAGE: [<impl>] <variables>...
140     # @DESCRIPTION:
141     # Set and export the Python implementation-relevant variables passed
142     # as parameters.
143     #
144     # The optional first parameter may specify the requested Python
145     # implementation (either as PYTHON_TARGETS value, e.g. python2_7,
146     # or an EPYTHON one, e.g. python2.7). If no implementation passed,
147     # the current one will be obtained from ${EPYTHON}.
148     #
149     # The variables which can be exported are: PYTHON, EPYTHON,
150     # PYTHON_SITEDIR. They are described more completely in the eclass
151     # variable documentation.
152     python_export() {
153     debug-print-function ${FUNCNAME} "${@}"
154    
155     local impl var
156    
157     case "${1}" in
158     python*|jython*)
159     impl=${1/_/.}
160     shift
161     ;;
162     pypy-c*)
163     impl=${1}
164     shift
165     ;;
166     pypy*)
167     local v=${1#pypy}
168     impl=pypy-c${v/_/.}
169     shift
170     ;;
171     *)
172     impl=${EPYTHON}
173     [[ ${impl} ]] || die "python_export: no impl nor EPYTHON"
174     ;;
175     esac
176     debug-print "${FUNCNAME}: implementation: ${impl}"
177    
178     for var; do
179     case "${var}" in
180     EPYTHON)
181     export EPYTHON=${impl}
182     debug-print "${FUNCNAME}: EPYTHON = ${EPYTHON}"
183     ;;
184     PYTHON)
185     export PYTHON=${EPREFIX}/usr/bin/${impl}
186     debug-print "${FUNCNAME}: PYTHON = ${PYTHON}"
187     ;;
188     PYTHON_SITEDIR)
189     local dir
190     case "${impl}" in
191     python*)
192     dir=/usr/$(get_libdir)/${impl}
193     ;;
194     jython*)
195     dir=/usr/share/${impl}/Lib
196     ;;
197     pypy*)
198     dir=/usr/$(get_libdir)/${impl/-c/}
199     ;;
200     esac
201    
202     export PYTHON_SITEDIR=${EPREFIX}${dir}/site-packages
203     debug-print "${FUNCNAME}: PYTHON_SITEDIR = ${PYTHON_SITEDIR}"
204     ;;
205 mgorny 1.10 PYTHON_INCLUDEDIR)
206     local dir
207     case "${impl}" in
208     python*)
209     dir=/usr/include/${impl}
210     ;;
211     jython*)
212     dir=/usr/share/${impl}/Include
213     ;;
214     pypy*)
215     dir=/usr/$(get_libdir)/${impl/-c/}/include
216     ;;
217     esac
218    
219     export PYTHON_INCLUDEDIR=${EPREFIX}${dir}
220     debug-print "${FUNCNAME}: PYTHON_INCLUDEDIR = ${PYTHON_INCLUDEDIR}"
221     ;;
222 mgorny 1.9 PYTHON_PKG_DEP)
223     local d
224     case ${impl} in
225     python*)
226     PYTHON_PKG_DEP='dev-lang/python';;
227     jython*)
228     PYTHON_PKG_DEP='dev-java/jython';;
229     pypy*)
230     PYTHON_PKG_DEP='dev-python/pypy';;
231     *)
232     die "Invalid implementation: ${impl}"
233     esac
234    
235     # slot
236     PYTHON_PKG_DEP+=:${impl##*[a-z-]}
237    
238     # use-dep
239     if [[ ${PYTHON_REQ_USE} ]]; then
240     PYTHON_PKG_DEP+=[${PYTHON_REQ_USE}]
241     fi
242    
243     export PYTHON_PKG_DEP
244     debug-print "${FUNCNAME}: PYTHON_PKG_DEP = ${PYTHON_PKG_DEP}"
245     ;;
246 mgorny 1.1 *)
247     die "python_export: unknown variable ${var}"
248     esac
249     done
250     }
251    
252     # @FUNCTION: python_get_PYTHON
253     # @USAGE: [<impl>]
254     # @DESCRIPTION:
255     # Obtain and print the path to the Python interpreter for the given
256     # implementation. If no implementation is provided, ${EPYTHON} will
257     # be used.
258     #
259     # If you just need to have PYTHON set (and exported), then it is better
260     # to use python_export() directly instead.
261     python_get_PYTHON() {
262     debug-print-function ${FUNCNAME} "${@}"
263    
264     python_export "${@}" PYTHON
265     echo "${PYTHON}"
266     }
267    
268     # @FUNCTION: python_get_EPYTHON
269     # @USAGE: <impl>
270     # @DESCRIPTION:
271     # Obtain and print the EPYTHON value for the given implementation.
272     #
273     # If you just need to have EPYTHON set (and exported), then it is better
274     # to use python_export() directly instead.
275     python_get_EPYTHON() {
276     debug-print-function ${FUNCNAME} "${@}"
277    
278     python_export "${@}" EPYTHON
279     echo "${EPYTHON}"
280     }
281    
282     # @FUNCTION: python_get_sitedir
283     # @USAGE: [<impl>]
284     # @DESCRIPTION:
285     # Obtain and print the 'site-packages' path for the given
286     # implementation. If no implementation is provided, ${EPYTHON} will
287     # be used.
288     #
289     # If you just need to have PYTHON_SITEDIR set (and exported), then it is
290     # better to use python_export() directly instead.
291     python_get_sitedir() {
292     debug-print-function ${FUNCNAME} "${@}"
293    
294     python_export "${@}" PYTHON_SITEDIR
295     echo "${PYTHON_SITEDIR}"
296     }
297    
298 mgorny 1.10 # @FUNCTION: python_get_includedir
299     # @USAGE: [<impl>]
300     # @DESCRIPTION:
301     # Obtain and print the include path for the given implementation. If no
302     # implementation is provided, ${EPYTHON} will be used.
303     #
304     # If you just need to have PYTHON_INCLUDEDIR set (and exported), then it
305     # is better to use python_export() directly instead.
306     python_get_includedir() {
307     debug-print-function ${FUNCNAME} "${@}"
308    
309     python_export "${@}" PYTHON_INCLUDEDIR
310     echo "${PYTHON_INCLUDEDIR}"
311     }
312    
313 mgorny 1.1 # @FUNCTION: _python_rewrite_shebang
314     # @INTERNAL
315     # @USAGE: [<EPYTHON>] <path>...
316     # @DESCRIPTION:
317     # Replaces 'python' executable in the shebang with the executable name
318     # of the specified interpreter. If no EPYTHON value (implementation) is
319     # used, the current ${EPYTHON} will be used.
320     #
321     # All specified files must start with a 'python' shebang. A file not
322     # having a matching shebang will be refused. The exact shebang style
323     # will be preserved in order not to break anything.
324     #
325     # Example conversions:
326     # @CODE
327     # From: #!/usr/bin/python -R
328     # To: #!/usr/bin/python2.7 -R
329     #
330     # From: #!/usr/bin/env FOO=bar python
331     # To: #!/usr/bin/env FOO=bar python2.7
332     # @CODE
333     _python_rewrite_shebang() {
334     debug-print-function ${FUNCNAME} "${@}"
335    
336     local impl
337     case "${1}" in
338     python*|jython*|pypy-c*)
339     impl=${1}
340     shift
341     ;;
342     *)
343     impl=${EPYTHON}
344     [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON"
345     ;;
346     esac
347     debug-print "${FUNCNAME}: implementation: ${impl}"
348    
349     local f
350     for f; do
351     local shebang=$(head -n 1 "${f}")
352 mgorny 1.13 local from
353 mgorny 1.1 debug-print "${FUNCNAME}: path = ${f}"
354     debug-print "${FUNCNAME}: shebang = ${shebang}"
355    
356 mgorny 1.13 if [[ "${shebang} " == *'python '* ]]; then
357     from=python
358     elif [[ "${shebang} " == *'python2 '* ]]; then
359     from=python2
360     elif [[ "${shebang} " == *'python3 '* ]]; then
361     from=python3
362     else
363 mgorny 1.1 eerror "A file does not seem to have a supported shebang:"
364     eerror " file: ${f}"
365     eerror " shebang: ${shebang}"
366     die "${FUNCNAME}: ${f} does not seem to have a valid shebang"
367     fi
368    
369 mgorny 1.13 if [[ ${from} == python2 && ${impl} == python3*
370     || ${from} == python3 && ${impl} != python3* ]]; then
371     eerror "A file does have shebang not supporting requested impl:"
372     eerror " file: ${f}"
373     eerror " shebang: ${shebang}"
374     eerror " impl: ${impl}"
375     die "${FUNCNAME}: ${f} does have shebang not supporting ${EPYTHON}"
376     fi
377    
378     sed -i -e "1s:${from}:${impl}:" "${f}" || die
379 mgorny 1.1 done
380     }
381    
382     # @FUNCTION: _python_ln_rel
383     # @INTERNAL
384     # @USAGE: <from> <to>
385     # @DESCRIPTION:
386     # Create a relative symlink.
387     _python_ln_rel() {
388     debug-print-function ${FUNCNAME} "${@}"
389    
390     local from=${1}
391     local to=${2}
392    
393     local frpath=${from%/*}/
394     local topath=${to%/*}/
395     local rel_path=
396    
397 mgorny 1.7 while [[ ${topath} ]]; do
398     local frseg= toseg=
399 mgorny 1.1
400 mgorny 1.7 while [[ ! ${frseg} && ${frpath} ]]; do
401     frseg=${frpath%%/*}
402     frpath=${frpath#${frseg}/}
403     done
404    
405     while [[ ! ${toseg} && ${topath} ]]; do
406     toseg=${topath%%/*}
407     topath=${topath#${toseg}/}
408     done
409 mgorny 1.1
410     if [[ ${frseg} != ${toseg} ]]; then
411     rel_path=../${rel_path}${frseg:+${frseg}/}
412     fi
413     done
414     rel_path+=${frpath}${1##*/}
415    
416     debug-print "${FUNCNAME}: ${from} -> ${to}"
417     debug-print "${FUNCNAME}: rel_path = ${rel_path}"
418    
419     ln -fs "${rel_path}" "${to}"
420     }
421    
422 mgorny 1.3 # @FUNCTION: python_optimize
423     # @USAGE: [<directory>...]
424     # @DESCRIPTION:
425     # Compile and optimize Python modules in specified directories (absolute
426     # paths). If no directories are provided, the default system paths
427     # are used (prepended with ${D}).
428     python_optimize() {
429     debug-print-function ${FUNCNAME} "${@}"
430    
431     [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
432    
433     local PYTHON=${PYTHON}
434     [[ ${PYTHON} ]] || python_export PYTHON
435    
436     # Note: python2.6 can't handle passing files to compileall...
437    
438     # default to sys.path
439     if [[ ${#} -eq 0 ]]; then
440     local f
441     while IFS= read -r -d '' f; do
442     # 1) accept only absolute paths
443     # (i.e. skip '', '.' or anything like that)
444     # 2) skip paths which do not exist
445     # (python2.6 complains about them verbosely)
446    
447     if [[ ${f} == /* && -d ${D}${f} ]]; then
448     set -- "${D}${f}" "${@}"
449     fi
450     done < <("${PYTHON}" -c 'import sys; print("\0".join(sys.path))')
451 mgorny 1.6
452     debug-print "${FUNCNAME}: using sys.path: ${*/%/;}"
453 mgorny 1.3 fi
454    
455     local d
456     for d; do
457     # make sure to get a nice path without //
458     local instpath=${d#${D}}
459     instpath=/${instpath##/}
460    
461     case "${EPYTHON}" in
462     python*)
463     "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
464     "${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
465     ;;
466     *)
467     "${PYTHON}" -m compileall -q -f -d "${instpath}" "${@}"
468     ;;
469     esac
470     done
471     }
472    
473 mgorny 1.1 # @ECLASS-VARIABLE: python_scriptroot
474     # @DEFAULT_UNSET
475     # @DESCRIPTION:
476     # The current script destination for python_doscript(). The path
477     # is relative to the installation root (${ED}).
478     #
479     # When unset, ${DESTTREE}/bin (/usr/bin by default) will be used.
480     #
481     # Can be set indirectly through the python_scriptinto() function.
482     #
483     # Example:
484     # @CODE
485     # src_install() {
486     # local python_scriptroot=${GAMES_BINDIR}
487     # python_foreach_impl python_doscript foo
488     # }
489     # @CODE
490    
491     # @FUNCTION: python_scriptinto
492     # @USAGE: <new-path>
493     # @DESCRIPTION:
494     # Set the current scriptroot. The new value will be stored
495     # in the 'python_scriptroot' environment variable. The new value need
496     # be relative to the installation root (${ED}).
497     #
498     # Alternatively, you can set the variable directly.
499     python_scriptinto() {
500     debug-print-function ${FUNCNAME} "${@}"
501    
502     python_scriptroot=${1}
503     }
504    
505     # @FUNCTION: python_doscript
506     # @USAGE: <files>...
507     # @DESCRIPTION:
508     # Install the given scripts into current python_scriptroot,
509     # for the current Python implementation (${EPYTHON}).
510     #
511     # All specified files must start with a 'python' shebang. The shebang
512     # will be converted, the file will be renamed to be EPYTHON-suffixed
513     # and a wrapper will be installed in place of the original name.
514     #
515     # Example:
516     # @CODE
517     # src_install() {
518     # python_foreach_impl python_doscript ${PN}
519     # }
520     # @CODE
521     python_doscript() {
522     debug-print-function ${FUNCNAME} "${@}"
523    
524     [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
525    
526     local d=${python_scriptroot:-${DESTTREE}/bin}
527     local INSDESTTREE INSOPTIONS
528    
529     insinto "${d}"
530     insopts -m755
531    
532     local f
533     for f; do
534     local oldfn=${f##*/}
535     local newfn=${oldfn}-${EPYTHON}
536    
537     debug-print "${FUNCNAME}: ${oldfn} -> ${newfn}"
538 mgorny 1.5 newins "${f}" "${newfn}" || die
539 mgorny 1.11 _python_rewrite_shebang "${ED}/${d}/${newfn}"
540 mgorny 1.1
541     # install the wrapper
542 mgorny 1.11 _python_ln_rel "${ED}"/usr/bin/python-exec "${ED}/${d}/${oldfn}" || die
543 mgorny 1.1 done
544     }
545    
546     # @ECLASS-VARIABLE: python_moduleroot
547     # @DEFAULT_UNSET
548     # @DESCRIPTION:
549     # The current module root for python_domodule(). The path can be either
550 mgorny 1.11 # an absolute system path (it must start with a slash, and ${ED} will be
551 mgorny 1.1 # prepended to it) or relative to the implementation's site-packages directory
552     # (then it must start with a non-slash character).
553     #
554     # When unset, the modules will be installed in the site-packages root.
555     #
556     # Can be set indirectly through the python_moduleinto() function.
557     #
558     # Example:
559     # @CODE
560     # src_install() {
561     # local python_moduleroot=bar
562     # # installs ${PYTHON_SITEDIR}/bar/baz.py
563     # python_foreach_impl python_domodule baz.py
564     # }
565     # @CODE
566    
567     # @FUNCTION: python_moduleinto
568     # @USAGE: <new-path>
569     # @DESCRIPTION:
570     # Set the current module root. The new value will be stored
571     # in the 'python_moduleroot' environment variable. The new value need
572     # be relative to the site-packages root.
573     #
574     # Alternatively, you can set the variable directly.
575     python_moduleinto() {
576     debug-print-function ${FUNCNAME} "${@}"
577    
578     python_moduleroot=${1}
579     }
580    
581     # @FUNCTION: python_domodule
582     # @USAGE: <files>...
583     # @DESCRIPTION:
584     # Install the given modules (or packages) into the current
585     # python_moduleroot. The list can mention both modules (files)
586     # and packages (directories). All listed files will be installed
587     # for all enabled implementations, and compiled afterwards.
588     #
589     # Example:
590     # @CODE
591     # src_install() {
592     # # (${PN} being a directory)
593     # python_foreach_impl python_domodule ${PN}
594     # }
595     # @CODE
596     python_domodule() {
597     debug-print-function ${FUNCNAME} "${@}"
598    
599     [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
600    
601     local d
602     if [[ ${python_moduleroot} == /* ]]; then
603     # absolute path
604     d=${python_moduleroot}
605     else
606     # relative to site-packages
607     local PYTHON_SITEDIR=${PYTHON_SITEDIR}
608     [[ ${PYTHON_SITEDIR} ]] || python_export PYTHON_SITEDIR
609    
610 mgorny 1.11 d=${PYTHON_SITEDIR#${EPREFIX}}/${python_moduleroot}
611 mgorny 1.1 fi
612    
613     local INSDESTTREE
614    
615     insinto "${d}"
616 mgorny 1.5 doins -r "${@}" || die
617 mgorny 1.1
618 mgorny 1.11 python_optimize "${ED}/${d}"
619 mgorny 1.1 }
620 mgorny 1.2
621 mgorny 1.15 # @FUNCTION: python_doheader
622     # @USAGE: <files>...
623     # @DESCRIPTION:
624     # Install the given headers into the implementation-specific include
625     # directory. This function is unconditionally recursive, i.e. you can
626     # pass directories instead of files.
627     #
628     # Example:
629     # @CODE
630     # src_install() {
631     # python_foreach_impl python_doheader foo.h bar.h
632     # }
633     # @CODE
634     python_doheader() {
635     debug-print-function ${FUNCNAME} "${@}"
636    
637     [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
638    
639     local d PYTHON_INCLUDEDIR=${PYTHON_INCLUDEDIR}
640     [[ ${PYTHON_INCLUDEDIR} ]] || python_export PYTHON_INCLUDEDIR
641    
642     d=${PYTHON_INCLUDEDIR#${EPREFIX}}
643    
644     local INSDESTTREE
645    
646     insinto "${d}"
647     doins -r "${@}" || die
648     }
649    
650 mgorny 1.2 _PYTHON_UTILS_R1=1
651     fi

  ViewVC Help
Powered by ViewVC 1.1.20