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

Diff of /eclass/python.eclass

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

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

Legend:
Removed from v.1.54  
changed lines
  Added in v.1.67

  ViewVC Help
Powered by ViewVC 1.1.20