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

Diff of /eclass/python.eclass

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

Revision 1.60 Revision 1.83
1# Copyright 1999-2009 Gentoo Foundation 1# Copyright 1999-2010 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.60 2009/08/05 18:31:30 arfrever Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.83 2010/01/10 17:03:08 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
14if ! has "${EAPI:-0}" 0 1 2; then
15 die "API of python.eclass in EAPI=\"${EAPI}\" not established"
16fi
17
16if [[ -n "${NEED_PYTHON}" ]] ; then 18if [[ -n "${NEED_PYTHON}" ]]; then
17 PYTHON_ATOM=">=dev-lang/python-${NEED_PYTHON}" 19 PYTHON_ATOM=">=dev-lang/python-${NEED_PYTHON}"
18 DEPEND="${PYTHON_ATOM}" 20 DEPEND="${PYTHON_ATOM}"
19 RDEPEND="${DEPEND}" 21 RDEPEND="${DEPEND}"
20else 22else
21 PYTHON_ATOM="dev-lang/python" 23 PYTHON_ATOM="dev-lang/python"
22fi 24fi
23 25
24if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
25 DEPEND="${DEPEND} >=app-admin/eselect-python-20090804" 26DEPEND+=" >=app-admin/eselect-python-20090804"
26fi
27 27
28__python_eclass_test() { 28__python_eclass_test() {
29 __python_version_extract 2.3 29 __python_version_extract 2.3
30 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR" 30 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR"
31 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO" 31 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO"
59 59
60python_version() { 60python_version() {
61 [[ -n "${PYVER}" ]] && return 0 61 [[ -n "${PYVER}" ]] && return 0
62 local tmpstr 62 local tmpstr
63 python=${python:-/usr/bin/python} 63 python=${python:-/usr/bin/python}
64 tmpstr="$(${python} -V 2>&1 )" 64 tmpstr="$(EPYTHON= ${python} -V 2>&1 )"
65 export PYVER_ALL="${tmpstr#Python }" 65 export PYVER_ALL="${tmpstr#Python }"
66 __python_version_extract $PYVER_ALL 66 __python_version_extract $PYVER_ALL
67} 67}
68 68
69# @FUNCTION: PYTHON 69# @FUNCTION: PYTHON
70# @USAGE: [-a|--absolute-path] <Python_ABI="${PYTHON_ABI}"> 70# @USAGE: [-2] [-3] [--ABI] [-A|--active] [-a|--absolute-path] [-f|--final-ABI] [--] <Python_ABI="${PYTHON_ABI}">
71# @DESCRIPTION: 71# @DESCRIPTION:
72# Get Python interpreter filename for specified Python ABI. If Python_ABI argument 72# Get Python interpreter filename for specified Python ABI. If Python_ABI argument
73# is ommitted, then PYTHON_ABI environment variable must be set and is used. 73# is ommitted, then PYTHON_ABI environment variable must be set and is used.
74# If -2 option is specified, then active version of Python 2 is used.
75# If -3 option is specified, then active version of Python 3 is used.
76# If --active option is specified, then active version of Python is used.
77# Active version of Python can be set by python_set_active_version().
78# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
79# -2, -3, --active and --final-ABI options and Python_ABI argument cannot be specified simultaneously.
80# If --ABI option is specified, then only specified Python ABI is printed instead of
81# Python interpreter filename.
82# --ABI and --absolute-path options cannot be specified simultaneously.
74PYTHON() { 83PYTHON() {
75 local absolute_path="0" slot= 84 local ABI_output="0" absolute_path_output="0" active="0" final_ABI="0" python2="0" python3="0" slot=
76 85
77 while (($#)); do 86 while (($#)); do
78 case "$1" in 87 case "$1" in
88 -2)
89 python2="1"
90 ;;
91 -3)
92 python3="1"
93 ;;
94 --ABI)
95 ABI_output="1"
96 ;;
97 -A|--active)
98 active="1"
99 ;;
79 -a|--absolute-path) 100 -a|--absolute-path)
80 absolute_path="1" 101 absolute_path_output="1"
102 ;;
103 -f|--final-ABI)
104 final_ABI="1"
105 ;;
106 --)
107 break
81 ;; 108 ;;
82 -*) 109 -*)
83 die "${FUNCNAME}(): Unrecognized option $1" 110 die "${FUNCNAME}(): Unrecognized option '$1'"
84 ;; 111 ;;
85 *) 112 *)
86 break 113 break
87 ;; 114 ;;
88 esac 115 esac
89 shift 116 shift
90 done 117 done
91 118
119 if [[ "${ABI_output}" == "1" && "${absolute_path_output}" == "1" ]]; then
120 die "${FUNCNAME}(): '--ABI and '--absolute-path' options cannot be specified simultaneously"
121 fi
122
123 if [[ "$((${python2} + ${python3} + ${active} + ${final_ABI}))" -gt 1 ]]; then
124 die "${FUNCNAME}(): '-2', '-3', '--active' or '--final-ABI' options cannot be specified simultaneously"
125 fi
126
92 if [[ "$#" -eq "0" ]]; then 127 if [[ "$#" -eq 0 ]]; then
128 if [[ "${active}" == "1" ]]; then
129 if [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
130 die "${FUNCNAME}(): '--active' option cannot be used in ebuilds of packages supporting installation for multiple versions of Python"
131 fi
132 slot="$(/usr/bin/python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
133 elif [[ "${final_ABI}" == "1" ]]; then
134 validate_PYTHON_ABIS
135 slot="${PYTHON_ABIS##* }"
136 elif [[ "${python2}" == "1" ]]; then
137 slot="$(eselect python show --python2)"
138 if [[ -z "${slot}" ]]; then
139 die "${FUNCNAME}(): Active Python 2 interpreter not set"
140 elif [[ "${slot}" != "python2."* ]]; then
141 die "${FUNCNAME}(): Internal error in \`eselect python show --python2\`"
142 fi
143 slot="${slot#python}"
144 elif [[ "${python3}" == "1" ]]; then
145 slot="$(eselect python show --python3)"
146 if [[ -z "${slot}" ]]; then
147 die "${FUNCNAME}(): Active Python 3 interpreter not set"
148 elif [[ "${slot}" != "python3."* ]]; then
149 die "${FUNCNAME}(): Internal error in \`eselect python show --python3\`"
150 fi
151 slot="${slot#python}"
93 if [[ -n "${PYTHON_ABI}" ]]; then 152 elif [[ -n "${PYTHON_ABI}" ]]; then
94 slot="${PYTHON_ABI}" 153 slot="${PYTHON_ABI}"
95 else 154 else
96 die "${FUNCNAME}(): Invalid usage" 155 die "${FUNCNAME}(): Invalid usage"
97 fi 156 fi
98 elif [[ "$#" -eq "1" ]]; then 157 elif [[ "$#" -eq 1 ]]; then
158 if [[ "${active}" == "1" ]]; then
159 die "${FUNCNAME}(): '--active' option and Python ABI cannot be specified simultaneously"
160 fi
161 if [[ "${final_ABI}" == "1" ]]; then
162 die "${FUNCNAME}(): '--final-ABI' option and Python ABI cannot be specified simultaneously"
163 fi
164 if [[ "${python2}" == "1" ]]; then
165 die "${FUNCNAME}(): '-2' option and Python ABI cannot be specified simultaneously"
166 fi
167 if [[ "${python3}" == "1" ]]; then
168 die "${FUNCNAME}(): '-3' option and Python ABI cannot be specified simultaneously"
169 fi
99 slot="$1" 170 slot="$1"
100 else 171 else
101 die "${FUNCNAME}(): Invalid usage" 172 die "${FUNCNAME}(): Invalid usage"
102 fi 173 fi
103 174
175 if [[ "${ABI_output}" == "1" ]]; then
176 echo -n "${slot}"
177 return
104 if [[ "${absolute_path}" == "1" ]]; then 178 elif [[ "${absolute_path_output}" == "1" ]]; then
105 echo -n "/usr/bin/python${slot}" 179 echo -n "/usr/bin/python${slot}"
106 else 180 else
107 echo -n "python${slot}" 181 echo -n "python${slot}"
108 fi 182 fi
183
184 if [[ -n "${ABI}" && "${ABI}" != "${DEFAULT_ABI}" && "${DEFAULT_ABI}" != "default" ]]; then
185 echo -n "-${ABI}"
186 fi
109} 187}
188
189# @FUNCTION: python_set_active_version
190# @USAGE: <Python_ABI|2|3>
191# @DESCRIPTION:
192# Set active version of Python.
193python_set_active_version() {
194 if [[ "$#" -ne "1" ]]; then
195 die "${FUNCNAME}() requires 1 argument"
196 fi
197
198 if [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then
199 if ! has_version "dev-lang/python:$1"; then
200 die "${FUNCNAME}(): 'dev-lang/python:$1' isn't installed"
201 fi
202 export EPYTHON="$(PYTHON "$1")"
203 elif [[ "$1" == "2" ]]; then
204 if ! has_version "=dev-lang/python-2*"; then
205 die "${FUNCNAME}(): '=dev-lang/python-2*' isn't installed"
206 fi
207 export EPYTHON="$(PYTHON -2)"
208 elif [[ "$1" == "3" ]]; then
209 if ! has_version "=dev-lang/python-3*"; then
210 die "${FUNCNAME}(): '=dev-lang/python-3*' isn't installed"
211 fi
212 export EPYTHON="$(PYTHON -3)"
213 else
214 die "${FUNCNAME}(): Unrecognized argument '$1'"
215 fi
216
217 # PYTHON_ABI variable is intended to be used only in ebuilds/eclasses,
218 # so it doesn't need to be exported to subprocesses.
219 PYTHON_ABI="${EPYTHON#python}"
220 PYTHON_ABI="${PYTHON_ABI%%-*}"
221}
222
223unset PYTHON_ABIS
224unset PYTHON_ABIS_SANITY_CHECKS
110 225
111# @FUNCTION: validate_PYTHON_ABIS 226# @FUNCTION: validate_PYTHON_ABIS
112# @DESCRIPTION: 227# @DESCRIPTION:
113# Make sure PYTHON_ABIS variable has valid value. 228# Ensure that PYTHON_ABIS variable has valid value.
114validate_PYTHON_ABIS() { 229validate_PYTHON_ABIS() {
230 # Ensure that some functions cannot be accidentally successfully used in EAPI <= 2 without setting SUPPORT_PYTHON_ABIS variable.
231 if has "${EAPI:-0}" 0 1 2 && [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then
232 die "${FUNCNAME}() cannot be used in this EAPI without setting SUPPORT_PYTHON_ABIS variable"
233 fi
234
115 # Ensure that /usr/bin/python and /usr/bin/python-config are valid. 235 # Ensure that /usr/bin/python and /usr/bin/python-config are valid.
116 if [[ "$(</usr/bin/python)" != *"Gentoo Python wrapper program"* ]]; then 236 if [[ "$(readlink /usr/bin/python)" != "python-wrapper" ]]; then
237 eerror "'/usr/bin/python' is not valid symlink."
238 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
117 die "/usr/bin/python isn't valid program" 239 die "'/usr/bin/python' is not valid symlink"
118 fi 240 fi
119 if [[ "$(</usr/bin/python-config)" != *"Gentoo python-config wrapper script"* ]]; then 241 if [[ "$(</usr/bin/python-config)" != *"Gentoo python-config wrapper script"* ]]; then
242 eerror "'/usr/bin/python-config' is not valid script"
243 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
120 die "/usr/bin/python-config isn't valid script" 244 die "'/usr/bin/python-config' is not valid script"
121 fi 245 fi
122 246
123 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 4. 247 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 5.
124 if [[ -z "${PYTHON_ABIS}" ]] && has "${EAPI:-0}" 0 1 2 3; then 248 if [[ "$(declare -p PYTHON_ABIS 2> /dev/null)" != "declare -x PYTHON_ABIS="* ]] && has "${EAPI:-0}" 0 1 2 3 4; then
125 local ABI support_ABI supported_PYTHON_ABIS= restricted_ABI 249 local PYTHON_ABI python2_supported_versions python3_supported_versions restricted_ABI support_ABI supported_PYTHON_ABIS=
126 PYTHON_ABI_SUPPORTED_VALUES="2.4 2.5 2.6 2.7 3.0 3.1 3.2" 250 PYTHON_ABI_SUPPORTED_VALUES="2.4 2.5 2.6 2.7 3.0 3.1 3.2"
251 python2_supported_versions="2.4 2.5 2.6 2.7"
252 python3_supported_versions="3.0 3.1 3.2"
253
254 if [[ "$(declare -p USE_PYTHON 2> /dev/null)" == "declare -x USE_PYTHON="* ]]; then
255 local python2_enabled="0" python3_enabled="0"
256
257 if [[ -z "${USE_PYTHON}" ]]; then
258 die "USE_PYTHON variable is empty"
259 fi
260
127 for ABI in ${USE_PYTHON}; do 261 for PYTHON_ABI in ${USE_PYTHON}; do
128 if ! has "${ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then 262 if ! has "${PYTHON_ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then
129 ewarn "Ignoring unsupported Python ABI '${ABI}'" 263 die "USE_PYTHON variable contains invalid value '${PYTHON_ABI}'"
130 continue
131 fi 264 fi
265
266 if has "${PYTHON_ABI}" ${python2_supported_versions}; then
267 python2_enabled="1"
268 fi
269 if has "${PYTHON_ABI}" ${python3_supported_versions}; then
270 python3_enabled="1"
271 fi
272
132 support_ABI="1" 273 support_ABI="1"
133 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do 274 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
134 if python -c "from fnmatch import fnmatch; exit(not fnmatch('${ABI}', '${restricted_ABI}'))"; then 275 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
135 support_ABI="0" 276 support_ABI="0"
136 break 277 break
137 fi 278 fi
279 done
280 [[ "${support_ABI}" == "1" ]] && export PYTHON_ABIS+="${PYTHON_ABIS:+ }${PYTHON_ABI}"
138 done 281 done
139 [[ "${support_ABI}" == "1" ]] && supported_PYTHON_ABIS+=" ${ABI}" 282
283 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
284 die "USE_PYTHON variable doesn't enable any version of Python supported by ${CATEGORY}/${PF}"
285 fi
286
287 if [[ "${python2_enabled}" == "0" ]]; then
288 ewarn "USE_PYTHON variable doesn't enable any version of Python 2. This configuration is unsupported."
289 fi
290 if [[ "${python3_enabled}" == "0" ]]; then
291 ewarn "USE_PYTHON variable doesn't enable any version of Python 3. This configuration is unsupported."
292 fi
293 else
294 local python_version python2_version= python3_version= support_python_major_version
295
296 python_version="$(/usr/bin/python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
297
298 if has_version "=dev-lang/python-2*"; then
299 if [[ "$(readlink /usr/bin/python2)" != "python2."* ]]; then
300 die "'/usr/bin/python2' isn't valid symlink"
301 fi
302
303 python2_version="$(/usr/bin/python2 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
304
305 for PYTHON_ABI in ${python2_supported_versions}; do
306 support_python_major_version="1"
307 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
308 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
309 support_python_major_version="0"
310 fi
311 done
312 [[ "${support_python_major_version}" == "1" ]] && break
313 done
314 if [[ "${support_python_major_version}" == "1" ]]; then
315 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
316 if [[ "${python2_version}" == ${restricted_ABI} ]]; then
317 die "Active version of Python 2 isn't supported by ${CATEGORY}/${PF}"
318 fi
319 done
320 else
321 python2_version=""
322 fi
323 fi
324
325 if has_version "=dev-lang/python-3*"; then
326 if [[ "$(readlink /usr/bin/python3)" != "python3."* ]]; then
327 die "'/usr/bin/python3' isn't valid symlink"
328 fi
329
330 python3_version="$(/usr/bin/python3 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
331
332 for PYTHON_ABI in ${python3_supported_versions}; do
333 support_python_major_version="1"
334 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
335 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
336 support_python_major_version="0"
337 fi
338 done
339 [[ "${support_python_major_version}" == "1" ]] && break
340 done
341 if [[ "${support_python_major_version}" == "1" ]]; then
342 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
343 if [[ "${python3_version}" == ${restricted_ABI} ]]; then
344 die "Active version of Python 3 isn't supported by ${CATEGORY}/${PF}"
345 fi
346 done
347 else
348 python3_version=""
349 fi
350 fi
351
352 if [[ -n "${python2_version}" && "${python_version}" == "2."* && "${python_version}" != "${python2_version}" ]]; then
353 eerror "Python wrapper is configured incorrectly or /usr/bin/python2 symlink"
354 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
355 die "Incorrect configuration of Python"
356 fi
357 if [[ -n "${python3_version}" && "${python_version}" == "3."* && "${python_version}" != "${python3_version}" ]]; then
358 eerror "Python wrapper is configured incorrectly or /usr/bin/python3 symlink"
359 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
360 die "Incorrect configuration of Python"
361 fi
362
363 PYTHON_ABIS="${python2_version} ${python3_version}"
364 PYTHON_ABIS="${PYTHON_ABIS# }"
365 export PYTHON_ABIS="${PYTHON_ABIS% }"
366 fi
367 fi
368
369 if [[ "$(declare -p PYTHON_ABIS_SANITY_CHECKS 2> /dev/null)" != "declare -- PYTHON_ABIS_SANITY_CHECKS="* ]]; then
370 local PYTHON_ABI
371 for PYTHON_ABI in ${PYTHON_ABIS}; do
372 # Ensure that appropriate version of Python is installed.
373 if ! has_version "dev-lang/python:${PYTHON_ABI}"; then
374 die "dev-lang/python:${PYTHON_ABI} isn't installed"
375 fi
376
377 # Ensure that EPYTHON variable is respected.
378 if [[ "$(EPYTHON="$(PYTHON)" python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')" != "${PYTHON_ABI}" ]]; then
379 eerror "python: '$(type -p python)'"
380 eerror "ABI: '${ABI}'"
381 eerror "DEFAULT_ABI: '${DEFAULT_ABI}'"
382 eerror "EPYTHON: '$(PYTHON)'"
383 eerror "PYTHON_ABI: '${PYTHON_ABI}'"
384 eerror "Version of enabled Python: '$(EPYTHON="$(PYTHON)" python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')'"
385 die "'python' doesn't respect EPYTHON variable"
386 fi
140 done 387 done
141 export PYTHON_ABIS="${supported_PYTHON_ABIS# }" 388 PYTHON_ABIS_SANITY_CHECKS="1"
142 fi
143
144 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
145 python_version
146 export PYTHON_ABIS="${PYVER}"
147 fi 389 fi
148} 390}
149 391
150# @FUNCTION: python_copy_sources 392# @FUNCTION: python_copy_sources
151# @USAGE: [directory] 393# @USAGE: [--no-link] [--] [directory]
152# @DESCRIPTION: 394# @DESCRIPTION:
153# Copy unpacked sources of given package for each Python ABI. 395# Copy unpacked sources of given package for each Python ABI.
154python_copy_sources() { 396python_copy_sources() {
155 local dir dirs=() PYTHON_ABI 397 local dir dirs=() no_link="0" PYTHON_ABI
156 398
399 while (($#)); do
400 case "$1" in
401 --no-link)
402 no_link="1"
403 ;;
404 --)
405 break
406 ;;
407 -*)
408 die "${FUNCNAME}(): Unrecognized option '$1'"
409 ;;
410 *)
411 break
412 ;;
413 esac
414 shift
415 done
416
157 if [[ "$#" -eq "0" ]]; then 417 if [[ "$#" -eq 0 ]]; then
158 if [[ "${WORKDIR}" == "${S}" ]]; then 418 if [[ "${WORKDIR}" == "${S}" ]]; then
159 die "${FUNCNAME}() cannot be used" 419 die "${FUNCNAME}() cannot be used"
160 fi 420 fi
161 dirs="${S}" 421 dirs="${S}"
162 else 422 else
164 fi 424 fi
165 425
166 validate_PYTHON_ABIS 426 validate_PYTHON_ABIS
167 for PYTHON_ABI in ${PYTHON_ABIS}; do 427 for PYTHON_ABI in ${PYTHON_ABIS}; do
168 for dir in "${dirs[@]}"; do 428 for dir in "${dirs[@]}"; do
429 if [[ "${no_link}" == "1" ]]; then
430 cp -pr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
431 else
169 cp -lpr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed" 432 cp -lpr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
433 fi
170 done 434 done
171 done 435 done
172} 436}
173 437
174# @FUNCTION: python_set_build_dir_symlink 438# @FUNCTION: python_set_build_dir_symlink
176# @DESCRIPTION: 440# @DESCRIPTION:
177# Create build directory symlink. 441# Create build directory symlink.
178python_set_build_dir_symlink() { 442python_set_build_dir_symlink() {
179 local dir="$1" 443 local dir="$1"
180 444
181 [[ -z "${PYTHON_ABIS}" ]] && die "PYTHON_ABIS variable not set" 445 [[ -z "${PYTHON_ABI}" ]] && die "PYTHON_ABI variable not set"
182 [[ -z "${dir}" ]] && dir="build" 446 [[ -z "${dir}" ]] && dir="build"
183 447
184 # Don't delete preexistent directories. 448 # Don't delete preexistent directories.
185 rm -f "${dir}" || die "Deletion of '${dir}' failed" 449 rm -f "${dir}" || die "Deletion of '${dir}' failed"
186 ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed" 450 ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed"
187} 451}
188 452
189# @FUNCTION: python_execute_function 453# @FUNCTION: python_execute_function
190# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] <function> [arguments] 454# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] [--source-dir source_directory] [--] <function> [arguments]
191# @DESCRIPTION: 455# @DESCRIPTION:
192# Execute specified function for each value of PYTHON_ABIS, optionally passing additional 456# Execute specified function for each value of PYTHON_ABIS, optionally passing additional
193# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables. 457# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables.
194python_execute_function() { 458python_execute_function() {
195 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" 459 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" source_dir=
196 460
197 while (($#)); do 461 while (($#)); do
198 case "$1" in 462 case "$1" in
199 --action-message) 463 --action-message)
200 action_message_template="$2" 464 action_message_template="$2"
214 quiet="1" 478 quiet="1"
215 ;; 479 ;;
216 -s|--separate-build-dirs) 480 -s|--separate-build-dirs)
217 separate_build_dirs="1" 481 separate_build_dirs="1"
218 ;; 482 ;;
483 --source-dir)
484 source_dir="$2"
485 shift
486 ;;
487 --)
488 break
489 ;;
219 -*) 490 -*)
220 die "${FUNCNAME}(): Unrecognized option $1" 491 die "${FUNCNAME}(): Unrecognized option '$1'"
221 ;; 492 ;;
222 *) 493 *)
223 break 494 break
224 ;; 495 ;;
225 esac 496 esac
226 shift 497 shift
227 done 498 done
228 499
500 if [[ -n "${source_dir}" && "${separate_build_dirs}" == 0 ]]; then
501 die "${FUNCNAME}(): '--source-dir' option can be specified only with '--separate-build-dirs' option"
502 fi
503
229 if [[ "${default_function}" == "0" ]]; then 504 if [[ "${default_function}" == "0" ]]; then
230 if [[ "$#" -eq "0" ]]; then 505 if [[ "$#" -eq 0 ]]; then
231 die "${FUNCNAME}(): Missing function name" 506 die "${FUNCNAME}(): Missing function name"
232 fi 507 fi
233 function="$1" 508 function="$1"
234 shift 509 shift
510
511 if [[ -z "$(type -t "${function}")" ]]; then
512 die "${FUNCNAME}(): '${function}' function isn't defined"
513 fi
235 else 514 else
236 if [[ "$#" -ne "0" ]]; then 515 if [[ "$#" -ne "0" ]]; then
237 die "${FUNCNAME}(): --default-function option and function name cannot be specified simultaneously" 516 die "${FUNCNAME}(): '--default-function' option and function name cannot be specified simultaneously"
238 fi 517 fi
239 if has "${EAPI:-0}" 0 1; then 518 if has "${EAPI:-0}" 0 1; then
240 die "${FUNCNAME}(): --default-function option cannot be used in this EAPI" 519 die "${FUNCNAME}(): '--default-function' option cannot be used in this EAPI"
241 fi 520 fi
242 521
243 if [[ "${EBUILD_PHASE}" == "configure" ]]; then 522 if [[ "${EBUILD_PHASE}" == "configure" ]]; then
523 if has "${EAPI}" 2 3; then
244 python_default_function() { 524 python_default_function() {
245 econf 525 econf
246 } 526 }
527 else
528 python_default_function() {
529 nonfatal econf
530 }
531 fi
247 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then 532 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then
248 python_default_function() { 533 python_default_function() {
249 emake 534 emake
250 } 535 }
251 elif [[ "${EBUILD_PHASE}" == "test" ]]; then 536 elif [[ "${EBUILD_PHASE}" == "test" ]]; then
259 elif [[ "${EBUILD_PHASE}" == "install" ]]; then 544 elif [[ "${EBUILD_PHASE}" == "install" ]]; then
260 python_default_function() { 545 python_default_function() {
261 emake DESTDIR="${D}" install 546 emake DESTDIR="${D}" install
262 } 547 }
263 else 548 else
264 die "${FUNCNAME}(): --default-function option cannot be used in this ebuild phase" 549 die "${FUNCNAME}(): '--default-function' option cannot be used in this ebuild phase"
265 fi 550 fi
266 function="python_default_function" 551 function="python_default_function"
267 fi 552 fi
268 553
269 if [[ "${quiet}" == "0" ]]; then 554 if [[ "${quiet}" == "0" ]]; then
301 else 586 else
302 action_message="${action} of ${CATEGORY}/${PF} with Python ${PYTHON_ABI}..." 587 action_message="${action} of ${CATEGORY}/${PF} with Python ${PYTHON_ABI}..."
303 fi 588 fi
304 echo " ${GREEN}*${NORMAL} ${BLUE}${action_message}${NORMAL}" 589 echo " ${GREEN}*${NORMAL} ${BLUE}${action_message}${NORMAL}"
305 fi 590 fi
591
306 if [[ "${separate_build_dirs}" == "1" ]]; then 592 if [[ "${separate_build_dirs}" == "1" ]]; then
593 if [[ -n "${source_dir}" ]]; then
594 export BUILDDIR="${S}/${source_dir}-${PYTHON_ABI}"
595 else
307 export BUILDDIR="${S}-${PYTHON_ABI}" 596 export BUILDDIR="${S}-${PYTHON_ABI}"
597 fi
308 pushd "${BUILDDIR}" > /dev/null || die "pushd failed" 598 pushd "${BUILDDIR}" > /dev/null || die "pushd failed"
309 else 599 else
310 export BUILDDIR="${S}" 600 export BUILDDIR="${S}"
311 fi 601 fi
602
603 previous_directory="$(pwd)"
604 previous_directory_stack="$(dirs -p)"
605 previous_directory_stack_length="$(dirs -p | wc -l)"
606
607 if ! has "${EAPI}" 0 1 2 3 && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
608 EPYTHON="$(PYTHON)" nonfatal "${function}" "$@"
609 else
312 if ! EPYTHON="$(PYTHON)" "${function}" "$@"; then 610 EPYTHON="$(PYTHON)" "${function}" "$@"
611 fi
612
613 if [[ "$?" != "0" ]]; then
313 if [[ -n "${failure_message_template}" ]]; then 614 if [[ -n "${failure_message_template}" ]]; then
314 failure_message="$(eval echo -n "${failure_message_template}")" 615 failure_message="$(eval echo -n "${failure_message_template}")"
315 else 616 else
316 failure_message="${action} failed with Python ${PYTHON_ABI} in ${function}() function" 617 failure_message="${action} failed with Python ${PYTHON_ABI} in ${function}() function"
317 fi 618 fi
318 if [[ "${nonfatal}" == "1" ]] || has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then 619
319 local ABI enabled_PYTHON_ABIS 620 if [[ "${nonfatal}" == "1" ]]; then
320 for ABI in ${PYTHON_ABIS}; do
321 [[ "${ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+=" ${ABI}"
322 done
323 export PYTHON_ABIS="${enabled_PYTHON_ABIS# }"
324 if [[ "${quiet}" == "0" ]]; then 621 if [[ "${quiet}" == "0" ]]; then
325 ewarn "${RED}${failure_message}${NORMAL}" 622 ewarn "${RED}${failure_message}${NORMAL}"
326 fi 623 fi
624 elif has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
625 if [[ "${EBUILD_PHASE}" != "test" ]] || ! has test-fail-continue ${FEATURES}; then
626 local enabled_PYTHON_ABIS= other_PYTHON_ABI
627 for other_PYTHON_ABI in ${PYTHON_ABIS}; do
628 [[ "${other_PYTHON_ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+="${enabled_PYTHON_ABIS:+ }${other_PYTHON_ABI}"
629 done
630 export PYTHON_ABIS="${enabled_PYTHON_ABIS}"
631 fi
632 if [[ "${quiet}" == "0" ]]; then
633 ewarn "${RED}${failure_message}${NORMAL}"
634 fi
635 if [[ -z "${PYTHON_ABIS}" ]]; then
636 die "${function}() function failed with all enabled versions of Python"
637 fi
327 else 638 else
328 die "${failure_message}" 639 die "${failure_message}"
329 fi 640 fi
330 fi 641 fi
642
643 # Ensure that directory stack hasn't been decreased.
644 if [[ "$(dirs -p | wc -l)" -lt "${previous_directory_stack_length}" ]]; then
645 die "Directory stack decreased illegally"
646 fi
647
648 # Avoid side effects of earlier returning from the specified function.
649 while [[ "$(dirs -p | wc -l)" -gt "${previous_directory_stack_length}" ]]; do
650 popd > /dev/null || die "popd failed"
651 done
652
653 # Ensure that the bottom part of directory stack hasn't been changed. Restore
654 # previous directory (from before running of the specified function) before
655 # comparison of directory stacks to avoid mismatch of directory stacks after
656 # potential using of 'cd' to change current directory. Restoration of previous
657 # directory allows to safely use 'cd' to change current directory in the
658 # specified function without changing it back to original directory.
659 cd "${previous_directory}"
660 if [[ "$(dirs -p)" != "${previous_directory_stack}" ]]; then
661 die "Directory stack changed illegally"
662 fi
663
331 if [[ "${separate_build_dirs}" == "1" ]]; then 664 if [[ "${separate_build_dirs}" == "1" ]]; then
332 popd > /dev/null || die "popd failed" 665 popd > /dev/null || die "popd failed"
333 fi 666 fi
334 unset BUILDDIR 667 unset BUILDDIR
335 done 668 done
337 if [[ "${default_function}" == "1" ]]; then 670 if [[ "${default_function}" == "1" ]]; then
338 unset -f python_default_function 671 unset -f python_default_function
339 fi 672 fi
340} 673}
341 674
675# @FUNCTION: python_convert_shebangs
676# @USAGE: [-q|--quiet] [-r|--recursive] [-x|--only-executables] [--] <Python_version> <file|directory> [files|directories]
677# @DESCRIPTION:
678# Convert shebangs in specified files. Directories can be specified only with --recursive option.
679python_convert_shebangs() {
680 local argument file files=() only_executables="0" python_version quiet="0" recursive="0"
681
682 while (($#)); do
683 case "$1" in
684 -r|--recursive)
685 recursive="1"
686 ;;
687 -q|--quiet)
688 quiet="1"
689 ;;
690 -x|--only-executables)
691 only_executables="1"
692 ;;
693 --)
694 break
695 ;;
696 -*)
697 die "${FUNCNAME}(): Unrecognized option '$1'"
698 ;;
699 *)
700 break
701 ;;
702 esac
703 shift
704 done
705
706 if [[ "$#" -eq 0 ]]; then
707 die "${FUNCNAME}(): Missing Python version and files or directories"
708 elif [[ "$#" -eq 1 ]]; then
709 die "${FUNCNAME}(): Missing files or directories"
710 fi
711
712 python_version="$1"
713 shift
714
715 for argument in "$@"; do
716 if [[ ! -e "${argument}" ]]; then
717 die "${FUNCNAME}(): '${argument}' doesn't exist"
718 elif [[ -f "${argument}" ]]; then
719 files+=("${argument}")
720 elif [[ -d "${argument}" ]]; then
721 if [[ "${recursive}" == "1" ]]; then
722 if [[ "${only_executables}" == "1" ]]; then
723 files+=($(find "${argument}" -perm /111 -type f))
724 else
725 files+=($(find "${argument}" -type f))
726 fi
727 else
728 die "${FUNCNAME}(): '${argument}' isn't a regular file"
729 fi
730 else
731 die "${FUNCNAME}(): '${argument}' isn't a regular file or a directory"
732 fi
733 done
734
735 for file in "${files[@]}"; do
736 file="${file#./}"
737 [[ "${only_executables}" == "1" && ! -x "${file}" ]] && continue
738
739 if [[ "$(head -n1 "${file}")" =~ ^'#!'.*python ]]; then
740 if [[ "${quiet}" == "0" ]]; then
741 einfo "Converting shebang in '${file}'"
742 fi
743 sed -e "1s/python\([[:digit:]]\+\(\.[[:digit:]]\+\)\?\)\?/python${python_version}/" -i "${file}" || die "Conversion of shebang in '${file}' failed"
744
745 # Delete potential whitespace after "#!".
746 sed -e '1s/\(^#!\)[[:space:]]*/\1/' -i "${file}" || die "sed '${file}' failed"
747 fi
748 done
749}
750
751# @FUNCTION: python_generate_wrapper_scripts
752# @USAGE: [-E|--respect-EPYTHON] [-f|--force] [-q|--quiet] [--] <file> [files]
753# @DESCRIPTION:
754# Generate wrapper scripts. Existing files are overwritten only with --force option.
755# If --respect-EPYTHON option is specified, then generated wrapper scripts will
756# respect EPYTHON variable at run time.
757python_generate_wrapper_scripts() {
758 local eselect_python_option file force="0" quiet="0" PYTHON_ABI python2_enabled="0" python2_supported_versions python3_enabled="0" python3_supported_versions respect_EPYTHON="0"
759 python2_supported_versions="2.4 2.5 2.6 2.7"
760 python3_supported_versions="3.0 3.1 3.2"
761
762 while (($#)); do
763 case "$1" in
764 -E|--respect-EPYTHON)
765 respect_EPYTHON="1"
766 ;;
767 -f|--force)
768 force="1"
769 ;;
770 -q|--quiet)
771 quiet="1"
772 ;;
773 --)
774 break
775 ;;
776 -*)
777 die "${FUNCNAME}(): Unrecognized option '$1'"
778 ;;
779 *)
780 break
781 ;;
782 esac
783 shift
784 done
785
786 if [[ "$#" -eq 0 ]]; then
787 die "${FUNCNAME}(): Missing arguments"
788 fi
789
790 validate_PYTHON_ABIS
791 for PYTHON_ABI in ${python2_supported_versions}; do
792 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
793 python2_enabled="1"
794 fi
795 done
796 for PYTHON_ABI in ${python3_supported_versions}; do
797 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
798 python3_enabled="1"
799 fi
800 done
801
802 if [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "1" ]]; then
803 eselect_python_option=
804 elif [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "0" ]]; then
805 eselect_python_option="--python2"
806 elif [[ "${python2_enabled}" == "0" && "${python3_enabled}" == "1" ]]; then
807 eselect_python_option="--python3"
808 else
809 die "${FUNCNAME}(): Unsupported environment"
810 fi
811
812 for file in "$@"; do
813 if [[ -f "${file}" && "${force}" == "0" ]]; then
814 die "${FUNCNAME}(): '$1' already exists"
815 fi
816
817 if [[ "${quiet}" == "0" ]]; then
818 einfo "Generating '${file#${D%/}}' wrapper script"
819 fi
820
821 cat << EOF > "${file}"
822#!/usr/bin/env python
823# Gentoo '${file##*/}' wrapper script
824
825import os
826import re
827import subprocess
828import sys
829
830EPYTHON_re = re.compile(r"^python(\d+\.\d+)$")
831
832EOF
833 if [[ "$?" != "0" ]]; then
834 die "${FUNCNAME}(): Generation of '$1' failed"
835 fi
836 if [[ "${respect_EPYTHON}" == "1" ]]; then
837 cat << EOF >> "${file}"
838EPYTHON = os.environ.get("EPYTHON")
839if EPYTHON:
840 EPYTHON_matched = EPYTHON_re.match(EPYTHON)
841 if EPYTHON_matched:
842 PYTHON_ABI = EPYTHON_matched.group(1)
843 else:
844 sys.stderr.write("EPYTHON variable has unrecognized value '%s'\n" % EPYTHON)
845 sys.exit(1)
846else:
847 try:
848 eselect_process = subprocess.Popen(["/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
849 if eselect_process.wait() != 0:
850 raise ValueError
851 except (OSError, ValueError):
852 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
853 sys.exit(1)
854
855 eselect_output = eselect_process.stdout.read()
856 if not isinstance(eselect_output, str):
857 # Python 3
858 eselect_output = eselect_output.decode()
859
860 EPYTHON_matched = EPYTHON_re.match(eselect_output)
861 if EPYTHON_matched:
862 PYTHON_ABI = EPYTHON_matched.group(1)
863 else:
864 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output)
865 sys.exit(1)
866EOF
867 if [[ "$?" != "0" ]]; then
868 die "${FUNCNAME}(): Generation of '$1' failed"
869 fi
870 else
871 cat << EOF >> "${file}"
872try:
873 eselect_process = subprocess.Popen(["/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
874 if eselect_process.wait() != 0:
875 raise ValueError
876except (OSError, ValueError):
877 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
878 sys.exit(1)
879
880eselect_output = eselect_process.stdout.read()
881if not isinstance(eselect_output, str):
882 # Python 3
883 eselect_output = eselect_output.decode()
884
885EPYTHON_matched = EPYTHON_re.match(eselect_output)
886if EPYTHON_matched:
887 PYTHON_ABI = EPYTHON_matched.group(1)
888else:
889 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output)
890 sys.exit(1)
891EOF
892 if [[ "$?" != "0" ]]; then
893 die "${FUNCNAME}(): Generation of '$1' failed"
894 fi
895 fi
896 cat << EOF >> "${file}"
897
898os.environ["PYTHON_PROCESS_NAME"] = sys.argv[0]
899target_executable = "%s-%s" % (os.path.realpath(sys.argv[0]), PYTHON_ABI)
900if not os.path.exists(target_executable):
901 sys.stderr.write("'%s' does not exist\n" % target_executable)
902 sys.exit(1)
903
904os.execv(target_executable, sys.argv)
905EOF
906 if [[ "$?" != "0" ]]; then
907 die "${FUNCNAME}(): Generation of '$1' failed"
908 fi
909 fperms +x "${file#${D%/}}" || die "fperms '${file}' failed"
910 done
911}
342 912
343# @ECLASS-VARIABLE: PYTHON_USE_WITH 913# @ECLASS-VARIABLE: PYTHON_USE_WITH
344# @DESCRIPTION: 914# @DESCRIPTION:
345# Set this to a space separated list of use flags 915# Set this to a space separated list of use flags
346# the python slot in use must be built with. 916# the python slot in use must be built with.
358 928
359# @FUNCTION: python_pkg_setup 929# @FUNCTION: python_pkg_setup
360# @DESCRIPTION: 930# @DESCRIPTION:
361# Makes sure PYTHON_USE_WITH or PYTHON_USE_WITH_OR listed use flags 931# Makes sure PYTHON_USE_WITH or PYTHON_USE_WITH_OR listed use flags
362# are respected. Only exported if one of those variables is set. 932# are respected. Only exported if one of those variables is set.
363if ! has ${EAPI} 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then 933if ! has "${EAPI:-0}" 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then
934 python_pkg_setup() {
364 python_pkg_setup_fail() { 935 python_pkg_setup_fail() {
365 eerror "${1}" 936 eerror "${1}"
366 die "${1}" 937 die "${1}"
938 }
939
940 [[ ${PYTHON_USE_WITH_OPT} ]] && use !${PYTHON_USE_WITH_OPT} && return
941
942 python_pkg_setup_check_USE_flags() {
943 local pyatom use
944 if [[ -n "${PYTHON_ABI}" ]]; then
945 pyatom="dev-lang/python:${PYTHON_ABI}"
946 else
947 pyatom="dev-lang/python:$(PYTHON -A --ABI)"
948 fi
949
950 for use in ${PYTHON_USE_WITH}; do
951 if ! has_version "${pyatom}[${use}]"; then
952 python_pkg_setup_fail "Please rebuild ${pyatom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
953 fi
954 done
955
956 for use in ${PYTHON_USE_WITH_OR}; do
957 if has_version "${pyatom}[${use}]"; then
958 return
959 fi
960 done
961
962 if [[ ${PYTHON_USE_WITH_OR} ]]; then
963 python_pkg_setup_fail "Please rebuild ${pyatom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
964 fi
965 }
966
967 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
968 python_execute_function -q python_pkg_setup_check_USE_flags
969 else
970 python_pkg_setup_check_USE_flags
971 fi
367 } 972 }
368 973
369 python_pkg_setup() {
370 [[ ${PYTHON_USE_WITH_OPT} ]] && use !${PYTHON_USE_WITH_OPT} && return
371
372 python_version
373 local failed
374 local pyatom="dev-lang/python:${PYVER}"
375
376 for use in ${PYTHON_USE_WITH}; do
377 if ! has_version "${pyatom}[${use}]"; then
378 python_pkg_setup_fail \
379 "Please rebuild ${pyatom} with use flags: ${PYTHON_USE_WITH}"
380 fi
381 done
382
383 for use in ${PYTHON_USE_WITH_OR}; do
384 if has_version "${pyatom}[${use}]"; then
385 return
386 fi
387 done
388
389 if [[ ${PYTHON_USE_WITH_OR} ]]; then
390 python_pkg_setup_fail \
391 "Please rebuild ${pyatom} with one of: ${PYTHON_USE_WITH_OR}"
392 fi
393 }
394
395 EXPORT_FUNCTIONS pkg_setup 974 EXPORT_FUNCTIONS pkg_setup
396 975
397 if [[ ${PYTHON_USE_WITH} ]]; then 976 if [[ -n "${PYTHON_USE_WITH}" ]]; then
398 PYTHON_USE_WITH_ATOM="${PYTHON_ATOM}[${PYTHON_USE_WITH/ /,}]" 977 PYTHON_USE_WITH_ATOM="${PYTHON_ATOM}[${PYTHON_USE_WITH/ /,}]"
399 elif [[ ${PYTHON_USE_WITH_OR} ]]; then 978 elif [[ -n "${PYTHON_USE_WITH_OR}" ]]; then
400 PYTHON_USE_WITH_ATOM="|| ( " 979 PYTHON_USE_WITH_ATOM="|| ( "
401 for use in ${PYTHON_USE_WITH_OR}; do 980 for use in ${PYTHON_USE_WITH_OR}; do
402 PYTHON_USE_WITH_ATOM=" 981 PYTHON_USE_WITH_ATOM+=" ${PYTHON_ATOM}[${use}]"
403 ${PYTHON_USE_WITH_ATOM}
404 ${PYTHON_ATOM}[${use}]"
405 done 982 done
406 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_ATOM} )" 983 unset use
984 PYTHON_USE_WITH_ATOM+=" )"
407 fi 985 fi
408 if [[ ${PYTHON_USE_WITH_OPT} ]]; then 986 if [[ -n "${PYTHON_USE_WITH_OPT}" ]]; then
409 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_OPT}? ( ${PYTHON_USE_WITH_ATOM} )" 987 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_OPT}? ( ${PYTHON_USE_WITH_ATOM} )"
410 fi 988 fi
411 DEPEND="${PYTHON_USE_WITH_ATOM}" 989 DEPEND+=" ${PYTHON_USE_WITH_ATOM}"
412 RDEPEND="${PYTHON_USE_WITH_ATOM}" 990 RDEPEND+=" ${PYTHON_USE_WITH_ATOM}"
413fi 991fi
414 992
993# @ECLASS-VARIABLE: PYTHON_DEFINE_DEFAULT_FUNCTIONS
994# @DESCRIPTION:
995# Set this to define default functions for the following ebuild phases:
996# src_prepare, src_configure, src_compile, src_test, src_install.
997if ! has "${EAPI:-0}" 0 1 && [[ -n "${PYTHON_DEFINE_DEFAULT_FUNCTIONS}" ]]; then
998 python_src_prepare() {
999 python_copy_sources
1000 }
1001
1002 for python_default_function in src_configure src_compile src_test src_install; do
1003 eval "python_${python_default_function}() { python_execute_function -d -s; }"
1004 done
1005 unset python_default_function
1006
1007 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
1008fi
1009
415# @FUNCTION: python_disable_pyc 1010# @FUNCTION: python_disable_pyc
416# @DESCRIPTION: 1011# @DESCRIPTION:
417# Tells python not to automatically recompile modules to .pyc/.pyo 1012# Tell Python not to automatically recompile modules to .pyc/.pyo
418# even if the timestamps/version stamps don't match. This is done 1013# even if the timestamps/version stamps don't match. This is done
419# to protect sandbox. 1014# to protect sandbox.
420#
421# note: supported by >=dev-lang/python-2.2.3-r3 only.
422#
423python_disable_pyc() { 1015python_disable_pyc() {
424 export PYTHONDONTWRITEBYTECODE=1 # For 2.6 and above 1016 export PYTHONDONTWRITEBYTECODE="1"
425 export PYTHON_DONTCOMPILE=1 # For 2.5 and below
426} 1017}
427 1018
428# @FUNCTION: python_enable_pyc 1019# @FUNCTION: python_enable_pyc
429# @DESCRIPTION: 1020# @DESCRIPTION:
430# Tells python to automatically recompile modules to .pyc/.pyo if the 1021# Tell Python to automatically recompile modules to .pyc/.pyo if the
431# timestamps/version stamps change 1022# timestamps/version stamps have changed.
432python_enable_pyc() { 1023python_enable_pyc() {
433 unset PYTHONDONTWRITEBYTECODE 1024 unset PYTHONDONTWRITEBYTECODE
434 unset PYTHON_DONTCOMPILE
435} 1025}
436
437python_disable_pyc
438 1026
439# @FUNCTION: python_need_rebuild 1027# @FUNCTION: python_need_rebuild
440# @DESCRIPTION: Run without arguments, specifies that the package should be 1028# @DESCRIPTION: Run without arguments, specifies that the package should be
441# rebuilt after a python upgrade. 1029# rebuilt after a python upgrade.
442python_need_rebuild() { 1030python_need_rebuild() {
443 python_version 1031 export PYTHON_NEED_REBUILD="$(PYTHON -A --ABI)"
444 export PYTHON_NEED_REBUILD=${PYVER}
445} 1032}
446 1033
447# @FUNCTION: python_get_includedir 1034# @FUNCTION: python_get_includedir
448# @DESCRIPTION: 1035# @DESCRIPTION:
449# Run without arguments, returns the Python include directory. 1036# Run without arguments, returns the Python include directory.
450python_get_includedir() { 1037python_get_includedir() {
451 if [[ -n "${PYTHON_ABI}" ]]; then 1038 if [[ -n "${PYTHON_ABI}" ]]; then
452 echo "/usr/include/python${PYTHON_ABI}" 1039 echo "/usr/include/python${PYTHON_ABI}"
453 else 1040 else
454 python_version
455 echo "/usr/include/python${PYVER}" 1041 echo "/usr/include/python$(PYTHON -A --ABI)"
456 fi 1042 fi
457} 1043}
458 1044
459# @FUNCTION: python_get_libdir 1045# @FUNCTION: python_get_libdir
460# @DESCRIPTION: 1046# @DESCRIPTION:
461# Run without arguments, returns the Python library directory. 1047# Run without arguments, returns the Python library directory.
462python_get_libdir() { 1048python_get_libdir() {
463 if [[ -n "${PYTHON_ABI}" ]]; then 1049 if [[ -n "${PYTHON_ABI}" ]]; then
464 echo "/usr/$(get_libdir)/python${PYTHON_ABI}" 1050 echo "/usr/$(get_libdir)/python${PYTHON_ABI}"
465 else 1051 else
466 python_version
467 echo "/usr/$(get_libdir)/python${PYVER}" 1052 echo "/usr/$(get_libdir)/python$(PYTHON -A --ABI)"
468 fi 1053 fi
469} 1054}
470 1055
471# @FUNCTION: python_get_sitedir 1056# @FUNCTION: python_get_sitedir
472# @DESCRIPTION: 1057# @DESCRIPTION:
473# Run without arguments, returns the Python site-packages directory. 1058# Run without arguments, returns the Python site-packages directory.
474python_get_sitedir() { 1059python_get_sitedir() {
475 echo "$(python_get_libdir)/site-packages" 1060 echo "$(python_get_libdir)/site-packages"
476}
477
478# @FUNCTION: python_makesym
479# @DESCRIPTION:
480# Run without arguments, it will create the /usr/bin/python symlinks
481# to the latest installed version
482python_makesym() {
483 alternatives_auto_makesym "/usr/bin/python" "python[0-9].[0-9]"
484 alternatives_auto_makesym "/usr/bin/python2" "python2.[0-9]"
485} 1061}
486 1062
487# @FUNCTION: python_tkinter_exists 1063# @FUNCTION: python_tkinter_exists
488# @DESCRIPTION: 1064# @DESCRIPTION:
489# Run without arguments, checks if python was compiled with Tkinter 1065# Run without arguments, checks if python was compiled with Tkinter
533 1109
534 # Check if phase is pkg_postinst() 1110 # Check if phase is pkg_postinst()
535 [[ ${EBUILD_PHASE} != postinst ]] &&\ 1111 [[ ${EBUILD_PHASE} != postinst ]] &&\
536 die "${FUNCNAME} should only be run in pkg_postinst()" 1112 die "${FUNCNAME} should only be run in pkg_postinst()"
537 1113
538 # allow compiling for older python versions
539 if [[ "${PYTHON_OVERRIDE_PYVER}" ]]; then
540 PYVER=${PYTHON_OVERRIDE_PYVER}
541 else
542 python_version
543 fi
544
545 # strip trailing slash 1114 # strip trailing slash
546 myroot="${ROOT%/}" 1115 myroot="${ROOT%/}"
547 1116
548 # respect ROOT 1117 # respect ROOT
549 for f in "$@"; do 1118 for f in "$@"; do
550 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}") 1119 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}")
551 done 1120 done
552 1121
553 if ((${#myfiles[@]})); then 1122 if ((${#myfiles[@]})); then
554 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 1123 "$(PYTHON -A)" "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}"
555 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 1124 "$(PYTHON -A)" -O "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}" &> /dev/null
556 else 1125 else
557 ewarn "No files to compile!" 1126 ewarn "No files to compile!"
558 fi 1127 fi
559} 1128}
560 1129
607 ewarn "'${root}/$1' is not a file or a directory!" 1176 ewarn "'${root}/$1' is not a file or a directory!"
608 else 1177 else
609 ewarn "'${root}/$1' doesn't exist!" 1178 ewarn "'${root}/$1' doesn't exist!"
610 fi 1179 fi
611 else 1180 else
612 for PYTHON_ABI in ${PYTHON_ABIS}; do 1181 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI-$(PYTHON -A --ABI)}}; do
613 if [[ -d "${root}/$(python_get_sitedir)/$1" ]]; then 1182 if [[ -d "${root}$(python_get_sitedir)/$1" ]]; then
614 site_packages_dirs+=("$1") 1183 site_packages_dirs+=("$1")
615 break 1184 break
616 elif [[ -f "${root}/$(python_get_sitedir)/$1" ]]; then 1185 elif [[ -f "${root}$(python_get_sitedir)/$1" ]]; then
617 site_packages_files+=("$1") 1186 site_packages_files+=("$1")
618 break 1187 break
619 elif [[ -e "${root}/$(python_get_sitedir)/$1" ]]; then 1188 elif [[ -e "${root}$(python_get_sitedir)/$1" ]]; then
620 ewarn "'$1' is not a file or a directory!" 1189 ewarn "'$1' is not a file or a directory!"
621 else 1190 else
622 ewarn "'$1' doesn't exist!" 1191 ewarn "'$1' doesn't exist!"
623 fi 1192 fi
624 done 1193 done
629 done 1198 done
630 1199
631 # Set additional options. 1200 # Set additional options.
632 options+=("-q") 1201 options+=("-q")
633 1202
634 for PYTHON_ABI in ${PYTHON_ABIS}; do 1203 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI-$(PYTHON -A --ABI)}}; do
635 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then 1204 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then
636 return_code="0" 1205 return_code="0"
637 ebegin "Compilation and optimization of Python modules for Python ${PYTHON_ABI}" 1206 ebegin "Compilation and optimization of Python modules for Python ${PYTHON_ABI}"
638 if ((${#site_packages_dirs[@]})); then 1207 if ((${#site_packages_dirs[@]})); then
639 for dir in "${site_packages_dirs[@]}"; do 1208 for dir in "${site_packages_dirs[@]}"; do
640 site_packages_absolute_dirs+=("${root}/$(python_get_sitedir)/${dir}") 1209 site_packages_absolute_dirs+=("${root}$(python_get_sitedir)/${dir}")
641 done 1210 done
642 "$(PYTHON)" "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1" 1211 "$(PYTHON)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1"
643 "$(PYTHON)" -O "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1" 1212 "$(PYTHON)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" &> /dev/null || return_code="1"
644 fi 1213 fi
645 if ((${#site_packages_files[@]})); then 1214 if ((${#site_packages_files[@]})); then
646 for file in "${site_packages_files[@]}"; do 1215 for file in "${site_packages_files[@]}"; do
647 site_packages_absolute_files+=("${root}/$(python_get_sitedir)/${file}") 1216 site_packages_absolute_files+=("${root}$(python_get_sitedir)/${file}")
648 done 1217 done
649 "$(PYTHON)" "${root}/$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1" 1218 "$(PYTHON)" "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1"
650 "$(PYTHON)" -O "${root}/$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1" 1219 "$(PYTHON)" -O "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" &> /dev/null || return_code="1"
651 fi 1220 fi
652 eend "${return_code}" 1221 eend "${return_code}"
653 fi 1222 fi
654 unset site_packages_absolute_dirs site_packages_absolute_files 1223 unset site_packages_absolute_dirs site_packages_absolute_files
655 done 1224 done
657 # Don't use PYTHON_ABI in next calls to python_get_libdir(). 1226 # Don't use PYTHON_ABI in next calls to python_get_libdir().
658 unset PYTHON_ABI 1227 unset PYTHON_ABI
659 1228
660 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then 1229 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then
661 return_code="0" 1230 return_code="0"
662 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for Python ${PYVER}..." 1231 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for Python $(PYTHON -A --ABI)"
663 if ((${#other_dirs[@]})); then 1232 if ((${#other_dirs[@]})); then
664 python${PYVER} "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
665 python${PYVER} -O "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1" 1233 "$(PYTHON -A)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
1234 "$(PYTHON -A)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" &> /dev/null || return_code="1"
666 fi 1235 fi
667 if ((${#other_files[@]})); then 1236 if ((${#other_files[@]})); then
668 python${PYVER} "${root}/$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
669 python${PYVER} -O "${root}/$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1" 1237 "$(PYTHON -A)" "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
1238 "$(PYTHON -A)" -O "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" &> /dev/null || return_code="1"
670 fi 1239 fi
671 eend "${return_code}" 1240 eend "${return_code}"
672 fi 1241 fi
673 else 1242 else
674 local myroot mydirs=() myfiles=() myopts=() 1243 local myroot mydirs=() myfiles=() myopts=() return_code="0"
675 1244
676 # strip trailing slash 1245 # strip trailing slash
677 myroot="${ROOT%/}" 1246 myroot="${ROOT%/}"
678 1247
679 # respect ROOT and options passed to compileall.py 1248 # respect ROOT and options passed to compileall.py
703 ;; 1272 ;;
704 esac 1273 esac
705 shift 1274 shift
706 done 1275 done
707 1276
708 # allow compiling for older python versions
709 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then
710 PYVER=${PYTHON_OVERRIDE_PYVER}
711 else
712 python_version
713 fi
714
715 # set additional opts 1277 # set additional opts
716 myopts+=(-q) 1278 myopts+=(-q)
717 1279
718 ebegin "Byte compiling python modules for python-${PYVER} .." 1280 ebegin "Compilation and optimization of Python modules for Python $(PYTHON -A --ABI)"
719 if ((${#mydirs[@]})); then 1281 if ((${#mydirs[@]})); then
720 python${PYVER} \ 1282 "$(PYTHON -A)" "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" || return_code="1"
721 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \ 1283 "$(PYTHON -A)" -O "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" &> /dev/null || return_code="1"
722 "${myopts[@]}" "${mydirs[@]}"
723 python${PYVER} -O \
724 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
725 "${myopts[@]}" "${mydirs[@]}"
726 fi 1284 fi
727 1285
728 if ((${#myfiles[@]})); then 1286 if ((${#myfiles[@]})); then
729 python_mod_compile "${myfiles[@]}" 1287 python_mod_compile "${myfiles[@]}"
730 fi 1288 fi
731 1289
732 eend $? 1290 eend "${return_code}"
733 fi 1291 fi
734} 1292}
735 1293
736# @FUNCTION: python_mod_cleanup 1294# @FUNCTION: python_mod_cleanup
737# @USAGE: [directory] 1295# @USAGE: [directory|file]
738# @DESCRIPTION: 1296# @DESCRIPTION:
739# Run with optional arguments, where arguments are directories of 1297# Run with optional arguments, where arguments are Python modules. If none given,
740# python modules. If none given, it will look in /usr/lib/python[0-9].[0-9]. 1298# it will look in /usr/lib/python[0-9].[0-9].
741# 1299#
742# It will recursively scan all compiled Python modules in the directories and 1300# It will recursively scan all compiled Python modules in the directories and
743# determine if they are orphaned (i.e. their corresponding .py files are missing.) 1301# determine if they are orphaned (i.e. their corresponding .py files are missing.)
744# If they are, then it will remove their corresponding .pyc and .pyo files. 1302# If they are, then it will remove their corresponding .pyc and .pyo files.
745# 1303#
746# This function should only be run in pkg_postrm(). 1304# This function should only be run in pkg_postrm().
747python_mod_cleanup() { 1305python_mod_cleanup() {
748 local PYTHON_ABI SEARCH_PATH=() root src_py 1306 local path py_file PYTHON_ABI SEARCH_PATH=() root
749 1307
750 # Check if phase is pkg_postrm(). 1308 # Check if phase is pkg_postrm().
751 [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME} should only be run in pkg_postrm()" 1309 [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME} should only be run in pkg_postrm()"
752 1310
753 # Strip trailing slash from ROOT. 1311 # Strip trailing slash from ROOT.
759 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then 1317 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
760 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories" 1318 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
761 elif [[ "$1" =~ ^/ ]]; then 1319 elif [[ "$1" =~ ^/ ]]; then
762 SEARCH_PATH+=("${root}/${1#/}") 1320 SEARCH_PATH+=("${root}/${1#/}")
763 else 1321 else
764 for PYTHON_ABI in ${PYTHON_ABIS}; do 1322 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI-$(PYTHON -A --ABI)}}; do
765 SEARCH_PATH+=("${root}/$(python_get_sitedir)/$1") 1323 SEARCH_PATH+=("${root}$(python_get_sitedir)/$1")
766 done 1324 done
767 fi 1325 fi
768 shift 1326 shift
769 done 1327 done
770 else 1328 else
771 SEARCH_PATH=("${@#/}") 1329 SEARCH_PATH=("${@#/}")
772 SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}") 1330 SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}")
773 fi 1331 fi
774 else 1332 else
775 SEARCH_PATH=("${root}"/usr/lib*/python*/site-packages) 1333 local dir sitedir
1334 for dir in "${root}"/usr/lib*; do
1335 if [[ -d "${dir}" && ! -L "${dir}" ]]; then
1336 for sitedir in "${dir}"/python*/site-packages; do
1337 if [[ -d "${sitedir}" ]]; then
1338 SEARCH_PATH+=("${sitedir}")
1339 fi
1340 done
1341 fi
1342 done
1343 fi
1344
1345 local BLUE CYAN NORMAL
1346 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
1347 BLUE=$'\e[1;34m'
1348 CYAN=$'\e[1;36m'
1349 NORMAL=$'\e[0m'
1350 else
1351 BLUE=
1352 CYAN=
1353 NORMAL=
776 fi 1354 fi
777 1355
778 for path in "${SEARCH_PATH[@]}"; do 1356 for path in "${SEARCH_PATH[@]}"; do
779 einfo "Cleaning orphaned Python bytecode from ${path} .." 1357 if [[ -d "${path}" ]]; then
780 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do 1358 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do
781 src_py="${REPLY%[co]}" 1359 py_file="${REPLY%[co]}"
782 [[ -f "${src_py}" ]] && continue 1360 [[ -f "${py_file}" || (! -f "${py_file}c" && ! -f "${py_file}o") ]] && continue
783 einfo "Purging ${src_py}[co]" 1361 einfo "${BLUE}<<< ${py_file}[co]${NORMAL}"
784 rm -f "${src_py}"[co] 1362 rm -f "${py_file}"[co]
785 done 1363 done
786 1364
787 # Attempt to remove directories that may be empty. 1365 # Attempt to delete directories, which may be empty.
788 find "${path}" -type d | sort -r | while read -r dir; do 1366 find "${path}" -type d | sort -r | while read -r dir; do
789 rmdir "${dir}" 2>/dev/null 1367 rmdir "${dir}" 2>/dev/null && einfo "${CYAN}<<< ${dir}${NORMAL}"
790 done 1368 done
1369 elif [[ "${path}" == *.py && ! -f "${path}" && (-f "${path}c" || -f "${path}o") ]]; then
1370 einfo "${BLUE}<<< ${path}[co]${NORMAL}"
1371 rm -f "${path}"[co]
1372 fi
791 done 1373 done
792} 1374}

Legend:
Removed from v.1.60  
changed lines
  Added in v.1.83

  ViewVC Help
Powered by ViewVC 1.1.20