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

Diff of /eclass/python.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.53 Revision 1.74
1# Copyright 1999-2008 Gentoo Foundation 1# Copyright 1999-2009 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.53 2008/10/27 12:23:50 hawking Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.74 2009/10/02 02:02:24 arfrever Exp $
4 4
5# @ECLASS: python.eclass 5# @ECLASS: python.eclass
6# @MAINTAINER: 6# @MAINTAINER:
7# python@gentoo.org 7# python@gentoo.org
8#
9# original author: Alastair Tse <liquidx@gentoo.org>
10# @BLURB: A Utility Eclass that should be inherited by anything that deals with Python or Python modules. 8# @BLURB: A utility eclass that should be inherited by anything that deals with Python or Python modules.
11# @DESCRIPTION: 9# @DESCRIPTION:
12# Some useful functions for dealing with python. 10# Some useful functions for dealing with Python.
13inherit alternatives multilib
14 11
12inherit multilib
15 13
16if [[ -n "${NEED_PYTHON}" ]] ; then 14if [[ -n "${NEED_PYTHON}" ]] ; then
17 DEPEND=">=dev-lang/python-${NEED_PYTHON}" 15 PYTHON_ATOM=">=dev-lang/python-${NEED_PYTHON}"
16 DEPEND="${PYTHON_ATOM}"
18 RDEPEND="${DEPEND}" 17 RDEPEND="${DEPEND}"
18else
19 PYTHON_ATOM="dev-lang/python"
19fi 20fi
21
22DEPEND+=" >=app-admin/eselect-python-20090804
23 >=app-shells/bash-3.2"
20 24
21__python_eclass_test() { 25__python_eclass_test() {
22 __python_version_extract 2.3 26 __python_version_extract 2.3
23 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR" 27 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR"
24 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO" 28 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO"
57 tmpstr="$(${python} -V 2>&1 )" 61 tmpstr="$(${python} -V 2>&1 )"
58 export PYVER_ALL="${tmpstr#Python }" 62 export PYVER_ALL="${tmpstr#Python }"
59 __python_version_extract $PYVER_ALL 63 __python_version_extract $PYVER_ALL
60} 64}
61 65
66# @FUNCTION: PYTHON
67# @USAGE: [-a|--absolute-path] [--] <Python_ABI="${PYTHON_ABI}">
68# @DESCRIPTION:
69# Get Python interpreter filename for specified Python ABI. If Python_ABI argument
70# is ommitted, then PYTHON_ABI environment variable must be set and is used.
71PYTHON() {
72 local absolute_path="0" slot=
73
74 while (($#)); do
75 case "$1" in
76 -a|--absolute-path)
77 absolute_path="1"
78 ;;
79 --)
80 break
81 ;;
82 -*)
83 die "${FUNCNAME}(): Unrecognized option $1"
84 ;;
85 *)
86 break
87 ;;
88 esac
89 shift
90 done
91
92 if [[ "$#" -eq "0" ]]; then
93 if [[ -n "${PYTHON_ABI}" ]]; then
94 slot="${PYTHON_ABI}"
95 else
96 die "${FUNCNAME}(): Invalid usage"
97 fi
98 elif [[ "$#" -eq "1" ]]; then
99 slot="$1"
100 else
101 die "${FUNCNAME}(): Invalid usage"
102 fi
103
104 if [[ "${absolute_path}" == "1" ]]; then
105 echo -n "/usr/bin/python${slot}"
106 else
107 echo -n "python${slot}"
108 fi
109}
110
111# @FUNCTION: validate_PYTHON_ABIS
112# @DESCRIPTION:
113# Make sure PYTHON_ABIS variable has valid value.
114validate_PYTHON_ABIS() {
115 # Ensure that some functions cannot be accidentally successfully used in EAPI <= 2 without setting SUPPORT_PYTHON_ABIS variable.
116 if has "${EAPI:-0}" 0 1 2 && [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then
117 die "${FUNCNAME}() cannot be used in this EAPI without setting SUPPORT_PYTHON_ABIS variable"
118 fi
119
120 # Ensure that /usr/bin/python and /usr/bin/python-config are valid.
121 if [[ "$(readlink /usr/bin/python)" != "python-wrapper" ]]; then
122 die "'/usr/bin/python' isn't valid symlink"
123 fi
124 if [[ "$(</usr/bin/python-config)" != *"Gentoo python-config wrapper script"* ]]; then
125 die "'/usr/bin/python-config' isn't valid script"
126 fi
127
128 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 4.
129 if [[ "$(declare -p PYTHON_ABIS 2> /dev/null)" != "declare -x PYTHON_ABIS="* ]] && has "${EAPI:-0}" 0 1 2 3; then
130 local ABI restricted_ABI support_ABI supported_PYTHON_ABIS=
131 PYTHON_ABI_SUPPORTED_VALUES="2.4 2.5 2.6 2.7 3.0 3.1 3.2"
132
133 if [[ "$(declare -p USE_PYTHON 2> /dev/null)" == "declare -x USE_PYTHON="* ]]; then
134 if [[ -z "${USE_PYTHON}" ]]; then
135 die "USE_PYTHON variable is empty"
136 fi
137
138 for ABI in ${USE_PYTHON}; do
139 if ! has "${ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then
140 die "USE_PYTHON variable contains invalid value '${ABI}'"
141 fi
142 support_ABI="1"
143 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
144 if python -c "from fnmatch import fnmatch; exit(not fnmatch('${ABI}', '${restricted_ABI}'))"; then
145 support_ABI="0"
146 break
147 fi
148 done
149 [[ "${support_ABI}" == "1" ]] && supported_PYTHON_ABIS+=" ${ABI}"
150 done
151 export PYTHON_ABIS="${supported_PYTHON_ABIS# }"
152
153 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
154 die "USE_PYTHON variable doesn't enable any version of Python supported by ${CATEGORY}/${PF}"
155 fi
156 else
157 local ABI python2_version= python2_supported_versions python3_version= python3_supported_versions restricted_ABI support_python_major_version
158
159 if has_version "=dev-lang/python-2*"; then
160 if [[ "$(readlink /usr/bin/python2)" != "python2."* ]]; then
161 die "'/usr/bin/python2' isn't valid symlink"
162 fi
163
164 python2_version="$(/usr/bin/python2 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
165 python2_supported_versions="2.4 2.5 2.6 2.7"
166
167 for ABI in ${python2_supported_versions}; do
168 support_python_major_version="1"
169 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
170 if python -c "from fnmatch import fnmatch; exit(not fnmatch('${ABI}', '${restricted_ABI}'))"; then
171 support_python_major_version="0"
172 fi
173 done
174 [[ "${support_python_major_version}" == "1" ]] && break
175 done
176 if [[ "${support_python_major_version}" == "1" ]]; then
177 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
178 if python -c "from fnmatch import fnmatch; exit(not fnmatch('${python2_version}', '${restricted_ABI}'))"; then
179 die "Active version of Python 2 isn't supported by ${CATEGORY}/${PF}"
180 fi
181 done
182 else
183 python2_version=""
184 fi
185 fi
186
187 if has_version "=dev-lang/python-3*"; then
188 if [[ "$(readlink /usr/bin/python3)" != "python3."* ]]; then
189 die "'/usr/bin/python3' isn't valid symlink"
190 fi
191
192 python3_version="$(/usr/bin/python3 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
193 python3_supported_versions="3.0 3.1 3.2"
194
195 for ABI in ${python3_supported_versions}; do
196 support_python_major_version="1"
197 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
198 if python -c "from fnmatch import fnmatch; exit(not fnmatch('${ABI}', '${restricted_ABI}'))"; then
199 support_python_major_version="0"
200 fi
201 done
202 [[ "${support_python_major_version}" == "1" ]] && break
203 done
204 if [[ "${support_python_major_version}" == "1" ]]; then
205 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
206 if python -c "from fnmatch import fnmatch; exit(not fnmatch('${python3_version}', '${restricted_ABI}'))"; then
207 die "Active version of Python 3 isn't supported by ${CATEGORY}/${PF}"
208 fi
209 done
210 else
211 python3_version=""
212 fi
213 fi
214
215 PYTHON_ABIS="${python2_version} ${python3_version}"
216 PYTHON_ABIS="${PYTHON_ABIS# }"
217 export PYTHON_ABIS="${PYTHON_ABIS% }"
218 fi
219 fi
220
221 local PYTHON_ABI
222 for PYTHON_ABI in ${PYTHON_ABIS}; do
223 # Ensure that appropriate Python version is installed.
224 if ! has_version "dev-lang/python:${PYTHON_ABI}"; then
225 die "dev-lang/python:${PYTHON_ABI} isn't installed"
226 fi
227
228 # Ensure that EPYTHON variable is respected.
229 if [[ "$(EPYTHON="$(PYTHON)" python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')" != "${PYTHON_ABI}" ]]; then
230 die "'python' doesn't respect EPYTHON variable"
231 fi
232 done
233}
234
235# @FUNCTION: python_copy_sources
236# @USAGE: [--no-link] [--] [directory]
237# @DESCRIPTION:
238# Copy unpacked sources of given package for each Python ABI.
239python_copy_sources() {
240 local dir dirs=() no_link="0" PYTHON_ABI
241
242 while (($#)); do
243 case "$1" in
244 --no-link)
245 no_link="1"
246 ;;
247 --)
248 break
249 ;;
250 -*)
251 die "${FUNCNAME}(): Unrecognized option '$1'"
252 ;;
253 *)
254 break
255 ;;
256 esac
257 shift
258 done
259
260 if [[ "$#" -eq "0" ]]; then
261 if [[ "${WORKDIR}" == "${S}" ]]; then
262 die "${FUNCNAME}() cannot be used"
263 fi
264 dirs="${S}"
265 else
266 dirs="$@"
267 fi
268
269 validate_PYTHON_ABIS
270 for PYTHON_ABI in ${PYTHON_ABIS}; do
271 for dir in "${dirs[@]}"; do
272 if [[ "${no_link}" == "1" ]]; then
273 cp -pr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
274 else
275 cp -lpr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
276 fi
277 done
278 done
279}
280
281# @FUNCTION: python_set_build_dir_symlink
282# @USAGE: [directory="build"]
283# @DESCRIPTION:
284# Create build directory symlink.
285python_set_build_dir_symlink() {
286 local dir="$1"
287
288 [[ -z "${PYTHON_ABI}" ]] && die "PYTHON_ABI variable not set"
289 [[ -z "${dir}" ]] && dir="build"
290
291 # Don't delete preexistent directories.
292 rm -f "${dir}" || die "Deletion of '${dir}' failed"
293 ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed"
294}
295
296# @FUNCTION: python_execute_function
297# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] [--] <function> [arguments]
298# @DESCRIPTION:
299# Execute specified function for each value of PYTHON_ABIS, optionally passing additional
300# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables.
301python_execute_function() {
302 local action action_message action_message_template= default_function="0" failure_message failure_message_template= function nonfatal="0" previous_directory previous_directory_stack previous_directory_stack_length PYTHON_ABI quiet="0" separate_build_dirs="0"
303
304 while (($#)); do
305 case "$1" in
306 --action-message)
307 action_message_template="$2"
308 shift
309 ;;
310 -d|--default-function)
311 default_function="1"
312 ;;
313 --failure-message)
314 failure_message_template="$2"
315 shift
316 ;;
317 --nonfatal)
318 nonfatal="1"
319 ;;
320 -q|--quiet)
321 quiet="1"
322 ;;
323 -s|--separate-build-dirs)
324 separate_build_dirs="1"
325 ;;
326 --)
327 break
328 ;;
329 -*)
330 die "${FUNCNAME}(): Unrecognized option '$1'"
331 ;;
332 *)
333 break
334 ;;
335 esac
336 shift
337 done
338
339 if [[ "${default_function}" == "0" ]]; then
340 if [[ "$#" -eq "0" ]]; then
341 die "${FUNCNAME}(): Missing function name"
342 fi
343 function="$1"
344 shift
345
346 if [[ -z "$(type -t "${function}")" ]]; then
347 die "${FUNCNAME}(): '${function}' function isn't defined"
348 fi
349 else
350 if [[ "$#" -ne "0" ]]; then
351 die "${FUNCNAME}(): '--default-function' option and function name cannot be specified simultaneously"
352 fi
353 if has "${EAPI:-0}" 0 1; then
354 die "${FUNCNAME}(): '--default-function' option cannot be used in this EAPI"
355 fi
356
357 if [[ "${EBUILD_PHASE}" == "configure" ]]; then
358 if has "${EAPI}" 2; then
359 python_default_function() {
360 econf
361 }
362 else
363 python_default_function() {
364 nonfatal econf
365 }
366 fi
367 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then
368 python_default_function() {
369 emake
370 }
371 elif [[ "${EBUILD_PHASE}" == "test" ]]; then
372 python_default_function() {
373 if emake -j1 -n check &> /dev/null; then
374 emake -j1 check
375 elif emake -j1 -n test &> /dev/null; then
376 emake -j1 test
377 fi
378 }
379 elif [[ "${EBUILD_PHASE}" == "install" ]]; then
380 python_default_function() {
381 emake DESTDIR="${D}" install
382 }
383 else
384 die "${FUNCNAME}(): --default-function option cannot be used in this ebuild phase"
385 fi
386 function="python_default_function"
387 fi
388
389 if [[ "${quiet}" == "0" ]]; then
390 [[ "${EBUILD_PHASE}" == "setup" ]] && action="Setting up"
391 [[ "${EBUILD_PHASE}" == "unpack" ]] && action="Unpacking"
392 [[ "${EBUILD_PHASE}" == "prepare" ]] && action="Preparation"
393 [[ "${EBUILD_PHASE}" == "configure" ]] && action="Configuration"
394 [[ "${EBUILD_PHASE}" == "compile" ]] && action="Building"
395 [[ "${EBUILD_PHASE}" == "test" ]] && action="Testing"
396 [[ "${EBUILD_PHASE}" == "install" ]] && action="Installation"
397 [[ "${EBUILD_PHASE}" == "preinst" ]] && action="Preinstallation"
398 [[ "${EBUILD_PHASE}" == "postinst" ]] && action="Postinstallation"
399 [[ "${EBUILD_PHASE}" == "prerm" ]] && action="Preuninstallation"
400 [[ "${EBUILD_PHASE}" == "postrm" ]] && action="Postuninstallation"
401 fi
402
403 local RED GREEN BLUE NORMAL
404 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
405 RED=$'\e[1;31m'
406 GREEN=$'\e[1;32m'
407 BLUE=$'\e[1;34m'
408 NORMAL=$'\e[0m'
409 else
410 RED=
411 GREEN=
412 BLUE=
413 NORMAL=
414 fi
415
416 validate_PYTHON_ABIS
417 for PYTHON_ABI in ${PYTHON_ABIS}; do
418 if [[ "${quiet}" == "0" ]]; then
419 if [[ -n "${action_message_template}" ]]; then
420 action_message="$(eval echo -n "${action_message_template}")"
421 else
422 action_message="${action} of ${CATEGORY}/${PF} with Python ${PYTHON_ABI}..."
423 fi
424 echo " ${GREEN}*${NORMAL} ${BLUE}${action_message}${NORMAL}"
425 fi
426
427 if [[ "${separate_build_dirs}" == "1" ]]; then
428 export BUILDDIR="${S}-${PYTHON_ABI}"
429 pushd "${BUILDDIR}" > /dev/null || die "pushd failed"
430 else
431 export BUILDDIR="${S}"
432 fi
433
434 previous_directory="$(pwd)"
435 previous_directory_stack="$(dirs -p)"
436 previous_directory_stack_length="$(dirs -p | wc -l)"
437
438 if ! has "${EAPI}" 0 1 2 && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
439 EPYTHON="$(PYTHON)" nonfatal "${function}" "$@"
440 else
441 EPYTHON="$(PYTHON)" "${function}" "$@"
442 fi
443
444 if [[ "$?" != "0" ]]; then
445 if [[ -n "${failure_message_template}" ]]; then
446 failure_message="$(eval echo -n "${failure_message_template}")"
447 else
448 failure_message="${action} failed with Python ${PYTHON_ABI} in ${function}() function"
449 fi
450
451 if [[ "${nonfatal}" == "1" ]]; then
452 if [[ "${quiet}" == "0" ]]; then
453 ewarn "${RED}${failure_message}${NORMAL}"
454 fi
455 elif has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
456 if [[ "${EBUILD_PHASE}" != "test" ]] || ! has test-fail-continue ${FEATURES}; then
457 local ABI enabled_PYTHON_ABIS=
458 for ABI in ${PYTHON_ABIS}; do
459 [[ "${ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+=" ${ABI}"
460 done
461 export PYTHON_ABIS="${enabled_PYTHON_ABIS# }"
462 fi
463 if [[ "${quiet}" == "0" ]]; then
464 ewarn "${RED}${failure_message}${NORMAL}"
465 fi
466 if [[ -z "${PYTHON_ABIS}" ]]; then
467 die "${function}() function failed with all enabled versions of Python"
468 fi
469 else
470 die "${failure_message}"
471 fi
472 fi
473
474 # Ensure that directory stack hasn't been decreased.
475 if [[ "$(dirs -p | wc -l)" -lt "${previous_directory_stack_length}" ]]; then
476 die "Directory stack decreased illegally"
477 fi
478
479 # Avoid side effects of earlier returning from the specified function.
480 while [[ "$(dirs -p | wc -l)" -gt "${previous_directory_stack_length}" ]]; do
481 popd > /dev/null || die "popd failed"
482 done
483
484 # Ensure that the bottom part of directory stack hasn't been changed. Restore
485 # previous directory (from before running of the specified function) before
486 # comparison of directory stacks to avoid mismatch of directory stacks after
487 # potential using of 'cd' to change current directory. Restoration of previous
488 # directory allows to safely use 'cd' to change current directory in the
489 # specified function without changing it back to original directory.
490 cd "${previous_directory}"
491 if [[ "$(dirs -p)" != "${previous_directory_stack}" ]]; then
492 die "Directory stack changed illegally"
493 fi
494
495 if [[ "${separate_build_dirs}" == "1" ]]; then
496 popd > /dev/null || die "popd failed"
497 fi
498 unset BUILDDIR
499 done
500
501 if [[ "${default_function}" == "1" ]]; then
502 unset -f python_default_function
503 fi
504}
505
506
507# @ECLASS-VARIABLE: PYTHON_USE_WITH
508# @DESCRIPTION:
509# Set this to a space separated list of use flags
510# the python slot in use must be built with.
511
512# @ECLASS-VARIABLE: PYTHON_USE_WITH_OR
513# @DESCRIPTION:
514# Set this to a space separated list of use flags
515# of which one must be turned on for the slot of
516# in use.
517
518# @ECLASS-VARIABLE: PYTHON_USE_WITH_OPT
519# @DESCRIPTION:
520# Set this if you need to make either PYTHON_USE_WITH or
521# PYTHON_USE_WITH_OR atoms conditional under a use flag.
522
523# @FUNCTION: python_pkg_setup
524# @DESCRIPTION:
525# Makes sure PYTHON_USE_WITH or PYTHON_USE_WITH_OR listed use flags
526# are respected. Only exported if one of those variables is set.
527if ! has "${EAPI:-0}" 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then
528 python_pkg_setup() {
529 python_pkg_setup_fail() {
530 eerror "${1}"
531 die "${1}"
532 }
533
534 [[ ${PYTHON_USE_WITH_OPT} ]] && use !${PYTHON_USE_WITH_OPT} && return
535
536 python_pkg_setup_check_USE_flags() {
537 local pyatom use
538 if [[ -n "${PYTHON_ABI}" ]]; then
539 pyatom="dev-lang/python:${PYTHON_ABI}"
540 else
541 python_version
542 pyatom="dev-lang/python:${PYVER}"
543 fi
544
545 for use in ${PYTHON_USE_WITH}; do
546 if ! has_version "${pyatom}[${use}]"; then
547 python_pkg_setup_fail "Please rebuild ${pyatom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
548 fi
549 done
550
551 for use in ${PYTHON_USE_WITH_OR}; do
552 if has_version "${pyatom}[${use}]"; then
553 return
554 fi
555 done
556
557 if [[ ${PYTHON_USE_WITH_OR} ]]; then
558 python_pkg_setup_fail "Please rebuild ${pyatom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
559 fi
560 }
561
562 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
563 python_execute_function -q python_pkg_setup_check_USE_flags
564 else
565 python_pkg_setup_check_USE_flags
566 fi
567 }
568
569 EXPORT_FUNCTIONS pkg_setup
570
571 if [[ -n "${PYTHON_USE_WITH}" ]]; then
572 PYTHON_USE_WITH_ATOM="${PYTHON_ATOM}[${PYTHON_USE_WITH/ /,}]"
573 elif [[ -n "${PYTHON_USE_WITH_OR}" ]]; then
574 PYTHON_USE_WITH_ATOM="|| ( "
575 for use in ${PYTHON_USE_WITH_OR}; do
576 PYTHON_USE_WITH_ATOM+=" ${PYTHON_ATOM}[${use}]"
577 done
578 unset use
579 PYTHON_USE_WITH_ATOM+=" )"
580 fi
581 if [[ -n "${PYTHON_USE_WITH_OPT}" ]]; then
582 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_OPT}? ( ${PYTHON_USE_WITH_ATOM} )"
583 fi
584 DEPEND+=" ${PYTHON_USE_WITH_ATOM}"
585 RDEPEND+=" ${PYTHON_USE_WITH_ATOM}"
586fi
587
588# @ECLASS-VARIABLE: PYTHON_DEFINE_DEFAULT_FUNCTIONS
589# @DESCRIPTION:
590# Set this to define default functions for the following ebuild phases:
591# src_prepare, src_configure, src_compile, src_test, src_install.
592if ! has "${EAPI:-0}" 0 1 && [[ -n "${PYTHON_DEFINE_DEFAULT_FUNCTIONS}" ]]; then
593 python_src_prepare() {
594 python_copy_sources
595 }
596
597 for python_default_function in src_configure src_compile src_test src_install; do
598 eval "python_${python_default_function}() { python_execute_function -d -s; }"
599 done
600 unset python_default_function
601
602 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
603fi
604
62# @FUNCTION: python_disable_pyc 605# @FUNCTION: python_disable_pyc
63# @DESCRIPTION: 606# @DESCRIPTION:
64# Tells python not to automatically recompile modules to .pyc/.pyo 607# Tell Python not to automatically recompile modules to .pyc/.pyo
65# even if the timestamps/version stamps don't match. This is done 608# even if the timestamps/version stamps don't match. This is done
66# to protect sandbox. 609# to protect sandbox.
67#
68# note: supported by >=dev-lang/python-2.2.3-r3 only.
69#
70python_disable_pyc() { 610python_disable_pyc() {
71 export PYTHONDONTWRITEBYTECODE=1 # For 2.6 and above 611 export PYTHONDONTWRITEBYTECODE="1"
72 export PYTHON_DONTCOMPILE=1 # For 2.5 and below
73} 612}
74 613
75# @FUNCTION: python_enable_pyc 614# @FUNCTION: python_enable_pyc
76# @DESCRIPTION: 615# @DESCRIPTION:
77# Tells python to automatically recompile modules to .pyc/.pyo if the 616# Tell Python to automatically recompile modules to .pyc/.pyo if the
78# timestamps/version stamps change 617# timestamps/version stamps have changed.
79python_enable_pyc() { 618python_enable_pyc() {
80 unset PYTHONDONTWRITEBYTECODE 619 unset PYTHONDONTWRITEBYTECODE
81 unset PYTHON_DONTCOMPILE
82} 620}
83 621
84python_disable_pyc 622python_disable_pyc
85 623
86# @FUNCTION: python_need_rebuild 624# @FUNCTION: python_need_rebuild
89python_need_rebuild() { 627python_need_rebuild() {
90 python_version 628 python_version
91 export PYTHON_NEED_REBUILD=${PYVER} 629 export PYTHON_NEED_REBUILD=${PYVER}
92} 630}
93 631
632# @FUNCTION: python_get_includedir
633# @DESCRIPTION:
634# Run without arguments, returns the Python include directory.
635python_get_includedir() {
636 if [[ -n "${PYTHON_ABI}" ]]; then
637 echo "/usr/include/python${PYTHON_ABI}"
638 else
639 python_version
640 echo "/usr/include/python${PYVER}"
641 fi
642}
643
94# @FUNCTION: python_get_libdir 644# @FUNCTION: python_get_libdir
95# @DESCRIPTION: 645# @DESCRIPTION:
96# Run without arguments, returns the python library dir 646# Run without arguments, returns the Python library directory.
97python_get_libdir() { 647python_get_libdir() {
648 if [[ -n "${PYTHON_ABI}" ]]; then
649 echo "/usr/$(get_libdir)/python${PYTHON_ABI}"
650 else
98 python_version 651 python_version
99 echo "/usr/$(get_libdir)/python${PYVER}" 652 echo "/usr/$(get_libdir)/python${PYVER}"
653 fi
100} 654}
101 655
102# @FUNCTION: python_get_sitedir 656# @FUNCTION: python_get_sitedir
103# @DESCRIPTION: 657# @DESCRIPTION:
104# Run without arguments, returns the python site-packages dir 658# Run without arguments, returns the Python site-packages directory.
105python_get_sitedir() { 659python_get_sitedir() {
106 echo "$(python_get_libdir)/site-packages" 660 echo "$(python_get_libdir)/site-packages"
107}
108
109# @FUNCTION: python_makesym
110# @DESCRIPTION:
111# Run without arguments, it will create the /usr/bin/python symlinks
112# to the latest installed version
113python_makesym() {
114 alternatives_auto_makesym "/usr/bin/python" "python[0-9].[0-9]"
115 alternatives_auto_makesym "/usr/bin/python2" "python2.[0-9]"
116} 661}
117 662
118# @FUNCTION: python_tkinter_exists 663# @FUNCTION: python_tkinter_exists
119# @DESCRIPTION: 664# @DESCRIPTION:
120# Run without arguments, checks if python was compiled with Tkinter 665# Run without arguments, checks if python was compiled with Tkinter
128 die "missing tkinter support with installed python" 673 die "missing tkinter support with installed python"
129 fi 674 fi
130} 675}
131 676
132# @FUNCTION: python_mod_exists 677# @FUNCTION: python_mod_exists
133# @USAGE: < module > 678# @USAGE: <module>
134# @DESCRIPTION: 679# @DESCRIPTION:
135# Run with the module name as an argument. it will check if a 680# Run with the module name as an argument. it will check if a
136# python module is installed and loadable. it will return 681# python module is installed and loadable. it will return
137# TRUE(0) if the module exists, and FALSE(1) if the module does 682# TRUE(0) if the module exists, and FALSE(1) if the module does
138# not exist. 683# not exist.
140# Example: 685# Example:
141# if python_mod_exists gtk; then 686# if python_mod_exists gtk; then
142# echo "gtk support enabled" 687# echo "gtk support enabled"
143# fi 688# fi
144python_mod_exists() { 689python_mod_exists() {
145 [[ "$1" ]] && die "${FUNCNAME} requires an argument!" 690 [[ "$1" ]] || die "${FUNCNAME} requires an argument!"
146 python -c "import $1" >/dev/null 2>&1 691 python -c "import $1" &>/dev/null
147} 692}
148 693
149# @FUNCTION: python_mod_compile 694# @FUNCTION: python_mod_compile
150# @USAGE: < file > [more files ...] 695# @USAGE: <file> [more files ...]
151# @DESCRIPTION: 696# @DESCRIPTION:
152# Given filenames, it will pre-compile the module's .pyc and .pyo. 697# Given filenames, it will pre-compile the module's .pyc and .pyo.
153# This function should only be run in pkg_postinst() 698# This function should only be run in pkg_postinst()
154# 699#
155# Example: 700# Example:
156# python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py 701# python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py
157# 702#
158python_mod_compile() { 703python_mod_compile() {
704 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
705 die "${FUNCNAME}() cannot be used in this EAPI"
706 fi
707
159 local f myroot myfiles=() 708 local f myroot myfiles=()
160 709
161 # Check if phase is pkg_postinst() 710 # Check if phase is pkg_postinst()
162 [[ ${EBUILD_PHASE} != postinst ]] &&\ 711 [[ ${EBUILD_PHASE} != postinst ]] &&\
163 die "${FUNCNAME} should only be run in pkg_postinst()" 712 die "${FUNCNAME} should only be run in pkg_postinst()"
177 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}") 726 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}")
178 done 727 done
179 728
180 if ((${#myfiles[@]})); then 729 if ((${#myfiles[@]})); then
181 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 730 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}"
182 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 731 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" &> /dev/null
183 else 732 else
184 ewarn "No files to compile!" 733 ewarn "No files to compile!"
185 fi 734 fi
186} 735}
187 736
188# @FUNCTION: python_mod_optimize 737# @FUNCTION: python_mod_optimize
189# @USAGE: [ path ] 738# @USAGE: [options] [directory|file]
190# @DESCRIPTION: 739# @DESCRIPTION:
191# If no arguments supplied, it will recompile all modules under 740# If no arguments supplied, it will recompile not recursively all modules
192# sys.path (eg. /usr/lib/python2.3, /usr/lib/python2.3/site-packages/ ..) 741# under sys.path (eg. /usr/lib/python2.6, /usr/lib/python2.6/site-packages).
193# no recursively
194# 742#
195# If supplied with arguments, it will recompile all modules recursively 743# If supplied with arguments, it will recompile all modules recursively
196# in the supplied directory 744# in the supplied directory.
197# This function should only be run in pkg_postinst() 745# This function should only be run in pkg_postinst().
198# 746#
199# Options passed to this function are passed to compileall.py 747# Options passed to this function are passed to compileall.py.
200# 748#
201# Example: 749# Example:
202# python_mod_optimize /usr/share/codegen 750# python_mod_optimize ctypesgencore
203python_mod_optimize() { 751python_mod_optimize() {
204 local myroot mydirs=() myfiles=() myopts=()
205
206 # Check if phase is pkg_postinst() 752 # Check if phase is pkg_postinst().
207 [[ ${EBUILD_PHASE} != postinst ]] &&\ 753 [[ ${EBUILD_PHASE} != "postinst" ]] && die "${FUNCNAME} should only be run in pkg_postinst()"
208 die "${FUNCNAME} should only be run in pkg_postinst()"
209 754
755 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
756 local dir file options=() other_dirs=() other_files=() PYTHON_ABI return_code root site_packages_absolute_dirs=() site_packages_dirs=() site_packages_absolute_files=() site_packages_files=()
757
758 # Strip trailing slash from ROOT.
759 root="${ROOT%/}"
760
761 # Respect ROOT and options passed to compileall.py.
762 while (($#)); do
763 case "$1" in
764 -l|-f|-q)
765 options+=("$1")
766 ;;
767 -d|-x)
768 options+=("$1" "$2")
769 shift
770 ;;
771 -*)
772 ewarn "${FUNCNAME}: Ignoring compile option $1"
773 ;;
774 *)
775 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
776 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
777 elif [[ "$1" =~ ^/ ]]; then
778 if [[ -d "${root}/$1" ]]; then
779 other_dirs+=("${root}/$1")
780 elif [[ -f "${root}/$1" ]]; then
781 other_files+=("${root}/$1")
782 elif [[ -e "${root}/$1" ]]; then
783 ewarn "'${root}/$1' is not a file or a directory!"
784 else
785 ewarn "'${root}/$1' doesn't exist!"
786 fi
787 else
788 for PYTHON_ABI in ${PYTHON_ABIS}; do
789 if [[ -d "${root}$(python_get_sitedir)/$1" ]]; then
790 site_packages_dirs+=("$1")
791 break
792 elif [[ -f "${root}$(python_get_sitedir)/$1" ]]; then
793 site_packages_files+=("$1")
794 break
795 elif [[ -e "${root}$(python_get_sitedir)/$1" ]]; then
796 ewarn "'$1' is not a file or a directory!"
797 else
798 ewarn "'$1' doesn't exist!"
799 fi
800 done
801 fi
802 ;;
803 esac
804 shift
805 done
806
807 # Set additional options.
808 options+=("-q")
809
810 for PYTHON_ABI in ${PYTHON_ABIS}; do
811 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then
812 return_code="0"
813 ebegin "Compilation and optimization of Python modules for Python ${PYTHON_ABI}"
814 if ((${#site_packages_dirs[@]})); then
815 for dir in "${site_packages_dirs[@]}"; do
816 site_packages_absolute_dirs+=("${root}$(python_get_sitedir)/${dir}")
817 done
818 "$(PYTHON)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1"
819 "$(PYTHON)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" &> /dev/null || return_code="1"
820 fi
821 if ((${#site_packages_files[@]})); then
822 for file in "${site_packages_files[@]}"; do
823 site_packages_absolute_files+=("${root}$(python_get_sitedir)/${file}")
824 done
825 "$(PYTHON)" "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1"
826 "$(PYTHON)" -O "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" &> /dev/null || return_code="1"
827 fi
828 eend "${return_code}"
829 fi
830 unset site_packages_absolute_dirs site_packages_absolute_files
831 done
832
833 # Don't use PYTHON_ABI in next calls to python_get_libdir().
834 unset PYTHON_ABI
835
836 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then
837 return_code="0"
838 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for Python ${PYVER}..."
839 if ((${#other_dirs[@]})); then
840 python${PYVER} "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
841 python${PYVER} -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" &> /dev/null || return_code="1"
842 fi
843 if ((${#other_files[@]})); then
844 python${PYVER} "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
845 python${PYVER} -O "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" &> /dev/null || return_code="1"
846 fi
847 eend "${return_code}"
848 fi
849 else
850 local myroot mydirs=() myfiles=() myopts=() return_code="0"
851
210 # strip trailing slash 852 # strip trailing slash
211 myroot="${ROOT%/}" 853 myroot="${ROOT%/}"
212 854
213 # respect ROOT and options passed to compileall.py 855 # respect ROOT and options passed to compileall.py
214 while (($#)); do 856 while (($#)); do
215 case $1 in 857 case "$1" in
216 -l|-f|-q) 858 -l|-f|-q)
217 myopts+=("$1") 859 myopts+=("$1")
218 ;; 860 ;;
219 -d|-x) 861 -d|-x)
220 myopts+=("$1" "$2") 862 myopts+=("$1" "$2")
863 shift
864 ;;
865 -*)
866 ewarn "${FUNCNAME}: Ignoring compile option $1"
867 ;;
868 *)
869 if [[ -d "${myroot}"/$1 ]]; then
870 mydirs+=("${myroot}/$1")
871 elif [[ -f "${myroot}"/$1 ]]; then
872 # Files are passed to python_mod_compile which is ROOT-aware
873 myfiles+=("$1")
874 elif [[ -e "${myroot}/$1" ]]; then
875 ewarn "${myroot}/$1 is not a file or directory!"
876 else
877 ewarn "${myroot}/$1 doesn't exist!"
878 fi
879 ;;
880 esac
881 shift
882 done
883
884 # allow compiling for older python versions
885 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then
886 PYVER=${PYTHON_OVERRIDE_PYVER}
887 else
888 python_version
889 fi
890
891 # set additional opts
892 myopts+=(-q)
893
894 ebegin "Byte compiling python modules for python-${PYVER} .."
895 if ((${#mydirs[@]})); then
896 python${PYVER} \
897 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
898 "${myopts[@]}" "${mydirs[@]}" || return_code="1"
899 python${PYVER} -O \
900 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
901 "${myopts[@]}" "${mydirs[@]}" &> /dev/null || return_code="1"
902 fi
903
904 if ((${#myfiles[@]})); then
905 python_mod_compile "${myfiles[@]}"
906 fi
907
908 eend "${return_code}"
909 fi
910}
911
912# @FUNCTION: python_mod_cleanup
913# @USAGE: [directory]
914# @DESCRIPTION:
915# Run with optional arguments, where arguments are directories of
916# python modules. If none given, it will look in /usr/lib/python[0-9].[0-9].
917#
918# It will recursively scan all compiled Python modules in the directories and
919# determine if they are orphaned (i.e. their corresponding .py files are missing.)
920# If they are, then it will remove their corresponding .pyc and .pyo files.
921#
922# This function should only be run in pkg_postrm().
923python_mod_cleanup() {
924 local PYTHON_ABI SEARCH_PATH=() root src_py
925
926 # Check if phase is pkg_postrm().
927 [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME} should only be run in pkg_postrm()"
928
929 # Strip trailing slash from ROOT.
930 root="${ROOT%/}"
931
932 if (($#)); then
933 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
934 while (($#)); do
935 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
936 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
937 elif [[ "$1" =~ ^/ ]]; then
938 SEARCH_PATH+=("${root}/${1#/}")
939 else
940 for PYTHON_ABI in ${PYTHON_ABIS}; do
941 SEARCH_PATH+=("${root}$(python_get_sitedir)/$1")
942 done
943 fi
221 shift 944 shift
222 ;;
223 -*)
224 ewarn "${FUNCNAME}: Ignoring compile option $1"
225 ;;
226 *)
227 if [[ -d "${myroot}"/$1 ]]; then
228 mydirs+=("${myroot}/$1")
229 elif [[ -f "${myroot}"/$1 ]]; then
230 # Files are passed to python_mod_compile which is ROOT-aware
231 myfiles+=("$1")
232 elif [[ -e "${myroot}/$1" ]]; then
233 ewarn "${myroot}/$1 is not a file or directory!"
234 else
235 ewarn "${myroot}/$1 doesn't exist!"
236 fi
237 ;;
238 esac
239 shift
240 done 945 done
241
242 # allow compiling for older python versions
243 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then
244 PYVER=${PYTHON_OVERRIDE_PYVER}
245 else 946 else
246 python_version
247 fi
248
249 # set additional opts
250 myopts+=(-q)
251
252 ebegin "Byte compiling python modules for python-${PYVER} .."
253 if ((${#mydirs[@]})); then
254 python${PYVER} \
255 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
256 "${myopts[@]}" "${mydirs[@]}"
257 python${PYVER} -O \
258 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
259 "${myopts[@]}" "${mydirs[@]}"
260 fi
261
262 if ((${#myfiles[@]})); then
263 python_mod_compile "${myfiles[@]}"
264 fi
265
266 eend $?
267}
268
269# @FUNCTION: python_mod_cleanup
270# @USAGE: [ dir ]
271# @DESCRIPTION:
272# Run with optional arguments, where arguments are directories of
273# python modules. if none given, it will look in /usr/lib/python[0-9].[0-9]
274#
275# It will recursively scan all compiled python modules in the directories
276# and determine if they are orphaned (eg. their corresponding .py is missing.)
277# if they are, then it will remove their corresponding .pyc and .pyo
278#
279# This function should only be run in pkg_postrm()
280python_mod_cleanup() {
281 local SEARCH_PATH=() myroot src_py
282
283 # Check if phase is pkg_postrm()
284 [[ ${EBUILD_PHASE} != postrm ]] &&\
285 die "${FUNCNAME} should only be run in pkg_postrm()"
286
287 # strip trailing slash
288 myroot="${ROOT%/}"
289
290 if (($#)); then
291 SEARCH_PATH=("${@#/}") 947 SEARCH_PATH=("${@#/}")
292 SEARCH_PATH=("${SEARCH_PATH[@]/#/$myroot/}") 948 SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}")
949 fi
293 else 950 else
294 SEARCH_PATH=("${myroot}"/usr/lib*/python*/site-packages) 951 SEARCH_PATH=("${root}"/usr/lib*/python*/site-packages)
295 fi 952 fi
296 953
297 for path in "${SEARCH_PATH[@]}"; do 954 for path in "${SEARCH_PATH[@]}"; do
955 [[ ! -d "${path}" ]] && continue
298 einfo "Cleaning orphaned Python bytecode from ${path} .." 956 einfo "Cleaning orphaned Python bytecode from ${path} .."
299 while read -rd ''; do 957 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do
300 src_py="${REPLY%[co]}" 958 src_py="${REPLY%[co]}"
301 [[ -f "${src_py}" ]] && continue 959 [[ -f "${src_py}" || (! -f "${src_py}c" && ! -f "${src_py}o") ]] && continue
302 einfo "Purging ${src_py}[co]" 960 einfo "Purging ${src_py}[co]"
303 rm -f "${src_py}"[co] 961 rm -f "${src_py}"[co]
304 done < <(find "${path}" -name '*.py[co]' -print0) 962 done
305 963
306 # attempt to remove directories that maybe empty 964 # Attempt to remove directories that may be empty.
307 while read -r dir; do 965 find "${path}" -type d | sort -r | while read -r dir; do
308 rmdir "${dir}" 2>/dev/null 966 rmdir "${dir}" 2>/dev/null && einfo "Removing empty directory ${dir}"
309 done < <(find "${path}" -type d | sort -r) 967 done
310 done 968 done
311} 969}

Legend:
Removed from v.1.53  
changed lines
  Added in v.1.74

  ViewVC Help
Powered by ViewVC 1.1.20