/[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.13 - (show annotations) (download)
Sat Jan 5 10:01:20 2013 UTC (3 years, 6 months ago) by mgorny
Branch: MAIN
Changes since 1.12: +19 -3 lines
Support converting files with python2 and python3 shebangs.

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

  ViewVC Help
Powered by ViewVC 1.1.20