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

Diff of /eclass/python.eclass

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

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

Legend:
Removed from v.1.41  
changed lines
  Added in v.1.69

  ViewVC Help
Powered by ViewVC 1.1.20