blob: f95981a41675b2eda09a03b48c1b7b7a81e082b0 [file] [log] [blame]
Craig Hesling34e58412020-01-20 20:34:27 -08001# Copyright 1999-2019 Gentoo Authors
Allen Webb7cfd3dc2019-01-28 13:27:13 -08002# Distributed under the terms of the GNU General Public License v2
3
4# @ECLASS: python-utils-r1.eclass
5# @MAINTAINER:
6# Python team <python@gentoo.org>
7# @AUTHOR:
8# Author: Michał Górny <mgorny@gentoo.org>
9# Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
Craig Hesling34e58412020-01-20 20:34:27 -080010# @SUPPORTED_EAPIS: 5 6 7
Allen Webb7cfd3dc2019-01-28 13:27:13 -080011# @BLURB: Utility functions for packages with Python parts.
12# @DESCRIPTION:
13# A utility eclass providing functions to query Python implementations,
14# install Python modules and scripts.
15#
16# This eclass does not set any metadata variables nor export any phase
17# functions. It can be inherited safely.
18#
19# For more information, please see the wiki:
20# https://wiki.gentoo.org/wiki/Project:Python/python-utils-r1
21
22case "${EAPI:-0}" in
Craig Hesling34e58412020-01-20 20:34:27 -080023 [0-4]) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
24 [5-7]) ;;
25 *) die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;;
Allen Webb7cfd3dc2019-01-28 13:27:13 -080026esac
27
28if [[ ${_PYTHON_ECLASS_INHERITED} ]]; then
29 die 'python-r1 suite eclasses can not be used with python.eclass.'
30fi
31
32if [[ ! ${_PYTHON_UTILS_R1} ]]; then
33
Craig Hesling34e58412020-01-20 20:34:27 -080034[[ ${EAPI} == 5 ]] && inherit eutils multilib
Allen Webb7cfd3dc2019-01-28 13:27:13 -080035inherit toolchain-funcs
36
37# @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS
38# @INTERNAL
39# @DESCRIPTION:
40# All supported Python implementations, most preferred last.
41_PYTHON_ALL_IMPLS=(
Craig Hesling34e58412020-01-20 20:34:27 -080042 pypy3
Allen Webb7cfd3dc2019-01-28 13:27:13 -080043 python2_7
Craig Hesling34e58412020-01-20 20:34:27 -080044 python3_6 python3_7 python3_8
Allen Webb7cfd3dc2019-01-28 13:27:13 -080045)
46readonly _PYTHON_ALL_IMPLS
47
48# @ECLASS-VARIABLE: PYTHON_COMPAT_NO_STRICT
49# @INTERNAL
50# @DESCRIPTION:
51# Set to a non-empty value in order to make eclass tolerate (ignore)
52# unknown implementations in PYTHON_COMPAT.
53#
54# This is intended to be set by the user when using ebuilds that may
55# have unknown (newer) implementations in PYTHON_COMPAT. The assumption
56# is that the ebuilds are intended to be used within multiple contexts
57# which can involve revisions of this eclass that support a different
58# set of Python implementations.
59
60# @FUNCTION: _python_impl_supported
61# @USAGE: <impl>
62# @INTERNAL
63# @DESCRIPTION:
64# Check whether the implementation <impl> (PYTHON_COMPAT-form)
65# is still supported.
66#
67# Returns 0 if the implementation is valid and supported. If it is
68# unsupported, returns 1 -- and the caller should ignore the entry.
69# If it is invalid, dies with an appopriate error messages.
70_python_impl_supported() {
71 debug-print-function ${FUNCNAME} "${@}"
72
73 [[ ${#} -eq 1 ]] || die "${FUNCNAME}: takes exactly 1 argument (impl)."
74
75 local impl=${1}
76
77 # keep in sync with _PYTHON_ALL_IMPLS!
78 # (not using that list because inline patterns shall be faster)
79 case "${impl}" in
Craig Hesling34e58412020-01-20 20:34:27 -080080 python2_7|python3_[678]|pypy3)
Allen Webb7cfd3dc2019-01-28 13:27:13 -080081 return 0
82 ;;
Craig Hesling34e58412020-01-20 20:34:27 -080083 jython2_7|pypy|pypy1_[89]|pypy2_0|python2_[56]|python3_[12345])
Allen Webb7cfd3dc2019-01-28 13:27:13 -080084 return 1
85 ;;
Allen Webb7cfd3dc2019-01-28 13:27:13 -080086 *)
87 [[ ${PYTHON_COMPAT_NO_STRICT} ]] && return 1
88 die "Invalid implementation in PYTHON_COMPAT: ${impl}"
89 esac
90}
91
92# @FUNCTION: _python_set_impls
93# @INTERNAL
94# @DESCRIPTION:
95# Check PYTHON_COMPAT for well-formedness and validity, then set
96# two global variables:
97#
98# - _PYTHON_SUPPORTED_IMPLS containing valid implementations supported
99# by the ebuild (PYTHON_COMPAT - dead implementations),
100#
101# - and _PYTHON_UNSUPPORTED_IMPLS containing valid implementations that
102# are not supported by the ebuild.
103#
104# Implementations in both variables are ordered using the pre-defined
105# eclass implementation ordering.
106#
107# This function must be called once in global scope by an eclass
108# utilizing PYTHON_COMPAT.
109_python_set_impls() {
110 local i
111
112 if ! declare -p PYTHON_COMPAT &>/dev/null; then
113 die 'PYTHON_COMPAT not declared.'
114 fi
115 if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
116 die 'PYTHON_COMPAT must be an array.'
117 fi
118 for i in "${PYTHON_COMPAT[@]}"; do
119 # trigger validity checks
120 _python_impl_supported "${i}"
121 done
122
123 local supp=() unsupp=()
124
125 for i in "${_PYTHON_ALL_IMPLS[@]}"; do
126 if has "${i}" "${PYTHON_COMPAT[@]}"; then
127 supp+=( "${i}" )
128 else
129 unsupp+=( "${i}" )
130 fi
131 done
132
133 if [[ ! ${supp[@]} ]]; then
134 die "No supported implementation in PYTHON_COMPAT."
135 fi
136
137 if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} ]]; then
138 # set once already, verify integrity
139 if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} != ${supp[@]} ]]; then
140 eerror "Supported impls (PYTHON_COMPAT) changed between inherits!"
141 eerror "Before: ${_PYTHON_SUPPORTED_IMPLS[*]}"
142 eerror "Now : ${supp[*]}"
143 die "_PYTHON_SUPPORTED_IMPLS integrity check failed"
144 fi
145 if [[ ${_PYTHON_UNSUPPORTED_IMPLS[@]} != ${unsupp[@]} ]]; then
146 eerror "Unsupported impls changed between inherits!"
147 eerror "Before: ${_PYTHON_UNSUPPORTED_IMPLS[*]}"
148 eerror "Now : ${unsupp[*]}"
149 die "_PYTHON_UNSUPPORTED_IMPLS integrity check failed"
150 fi
151 else
152 _PYTHON_SUPPORTED_IMPLS=( "${supp[@]}" )
153 _PYTHON_UNSUPPORTED_IMPLS=( "${unsupp[@]}" )
154 readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS
155 fi
156}
157
158# @FUNCTION: _python_impl_matches
Craig Hesling34e58412020-01-20 20:34:27 -0800159# @USAGE: <impl> [<pattern>...]
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800160# @INTERNAL
161# @DESCRIPTION:
162# Check whether the specified <impl> matches at least one
163# of the patterns following it. Return 0 if it does, 1 otherwise.
Craig Hesling34e58412020-01-20 20:34:27 -0800164# Matches if no patterns are provided.
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800165#
166# <impl> can be in PYTHON_COMPAT or EPYTHON form. The patterns can be
167# either:
168# a) fnmatch-style patterns, e.g. 'python2*', 'pypy'...
169# b) '-2' to indicate all Python 2 variants (= !python_is_python3)
170# c) '-3' to indicate all Python 3 variants (= python_is_python3)
171_python_impl_matches() {
Craig Hesling34e58412020-01-20 20:34:27 -0800172 [[ ${#} -ge 1 ]] || die "${FUNCNAME}: takes at least 1 parameter"
173 [[ ${#} -eq 1 ]] && return 0
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800174
175 local impl=${1} pattern
176 shift
177
178 for pattern; do
179 if [[ ${pattern} == -2 ]]; then
Craig Hesling34e58412020-01-20 20:34:27 -0800180 python_is_python3 "${impl}" || return 0
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800181 elif [[ ${pattern} == -3 ]]; then
Craig Hesling34e58412020-01-20 20:34:27 -0800182 python_is_python3 "${impl}" && return 0
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800183 return
184 # unify value style to allow lax matching
185 elif [[ ${impl/./_} == ${pattern/./_} ]]; then
186 return 0
187 fi
188 done
189
190 return 1
191}
192
193# @ECLASS-VARIABLE: PYTHON
194# @DEFAULT_UNSET
195# @DESCRIPTION:
196# The absolute path to the current Python interpreter.
197#
198# This variable is set automatically in the following contexts:
199#
200# python-r1: Set in functions called by python_foreach_impl() or after
201# calling python_export_best().
202#
203# python-single-r1: Set after calling python-single-r1_pkg_setup().
204#
205# distutils-r1: Set within any of the python sub-phase functions.
206#
207# Example value:
208# @CODE
209# /usr/bin/python2.7
210# @CODE
211
212# @ECLASS-VARIABLE: EPYTHON
213# @DEFAULT_UNSET
214# @DESCRIPTION:
215# The executable name of the current Python interpreter.
216#
217# This variable is set automatically in the following contexts:
218#
219# python-r1: Set in functions called by python_foreach_impl() or after
220# calling python_export_best().
221#
222# python-single-r1: Set after calling python-single-r1_pkg_setup().
223#
224# distutils-r1: Set within any of the python sub-phase functions.
225#
226# Example value:
227# @CODE
228# python2.7
229# @CODE
230
231# @ECLASS-VARIABLE: PYTHON_SITEDIR
232# @DEFAULT_UNSET
233# @DESCRIPTION:
234# The path to Python site-packages directory.
235#
236# Set and exported on request using python_export().
237# Requires a proper build-time dependency on the Python implementation.
238#
239# Example value:
240# @CODE
241# /usr/lib64/python2.7/site-packages
242# @CODE
243
244# @ECLASS-VARIABLE: PYTHON_INCLUDEDIR
245# @DEFAULT_UNSET
246# @DESCRIPTION:
247# The path to Python include directory.
248#
249# Set and exported on request using python_export().
250# Requires a proper build-time dependency on the Python implementation.
251#
252# Example value:
253# @CODE
254# /usr/include/python2.7
255# @CODE
256
257# @ECLASS-VARIABLE: PYTHON_LIBPATH
258# @DEFAULT_UNSET
259# @DESCRIPTION:
260# The path to Python library.
261#
262# Set and exported on request using python_export().
263# Valid only for CPython. Requires a proper build-time dependency
264# on the Python implementation.
265#
266# Example value:
267# @CODE
268# /usr/lib64/libpython2.7.so
269# @CODE
270
271# @ECLASS-VARIABLE: PYTHON_CFLAGS
272# @DEFAULT_UNSET
273# @DESCRIPTION:
274# Proper C compiler flags for building against Python. Obtained from
275# pkg-config or python-config.
276#
277# Set and exported on request using python_export().
278# Valid only for CPython. Requires a proper build-time dependency
279# on the Python implementation and on pkg-config.
280#
281# Example value:
282# @CODE
283# -I/usr/include/python2.7
284# @CODE
285
286# @ECLASS-VARIABLE: PYTHON_LIBS
287# @DEFAULT_UNSET
288# @DESCRIPTION:
289# Proper C compiler flags for linking against Python. Obtained from
290# pkg-config or python-config.
291#
292# Set and exported on request using python_export().
293# Valid only for CPython. Requires a proper build-time dependency
294# on the Python implementation and on pkg-config.
295#
296# Example value:
297# @CODE
298# -lpython2.7
299# @CODE
300
301# @ECLASS-VARIABLE: PYTHON_CONFIG
302# @DEFAULT_UNSET
303# @DESCRIPTION:
304# Path to the python-config executable.
305#
306# Set and exported on request using python_export().
307# Valid only for CPython. Requires a proper build-time dependency
308# on the Python implementation and on pkg-config.
309#
310# Example value:
311# @CODE
312# /usr/bin/python2.7-config
313# @CODE
314
315# @ECLASS-VARIABLE: PYTHON_PKG_DEP
316# @DEFAULT_UNSET
317# @DESCRIPTION:
318# The complete dependency on a particular Python package as a string.
319#
320# Set and exported on request using python_export().
321#
322# Example value:
323# @CODE
324# dev-lang/python:2.7[xml]
325# @CODE
326
327# @ECLASS-VARIABLE: PYTHON_SCRIPTDIR
328# @DEFAULT_UNSET
329# @DESCRIPTION:
330# The location where Python scripts must be installed for current impl.
331#
332# Set and exported on request using python_export().
333#
334# Example value:
335# @CODE
336# /usr/lib/python-exec/python2.7
337# @CODE
338
339# @FUNCTION: python_export
340# @USAGE: [<impl>] <variables>...
341# @DESCRIPTION:
342# Set and export the Python implementation-relevant variables passed
343# as parameters.
344#
345# The optional first parameter may specify the requested Python
346# implementation (either as PYTHON_TARGETS value, e.g. python2_7,
347# or an EPYTHON one, e.g. python2.7). If no implementation passed,
348# the current one will be obtained from ${EPYTHON}.
349#
350# The variables which can be exported are: PYTHON, EPYTHON,
351# PYTHON_SITEDIR. They are described more completely in the eclass
352# variable documentation.
353python_export() {
354 debug-print-function ${FUNCNAME} "${@}"
355
356 local impl var
357
358 case "${1}" in
359 python*|jython*)
360 impl=${1/_/.}
361 shift
362 ;;
363 pypy|pypy3)
364 impl=${1}
365 shift
366 ;;
367 *)
368 impl=${EPYTHON}
369 if [[ -z ${impl} ]]; then
370 die "python_export called without a python implementation and EPYTHON is unset"
371 fi
372 ;;
373 esac
374 debug-print "${FUNCNAME}: implementation: ${impl}"
375
376 for var; do
377 case "${var}" in
378 EPYTHON)
379 export EPYTHON=${impl}
380 debug-print "${FUNCNAME}: EPYTHON = ${EPYTHON}"
381 ;;
382 PYTHON)
383 export PYTHON=${EPREFIX}/usr/bin/${impl}
384 debug-print "${FUNCNAME}: PYTHON = ${PYTHON}"
385 ;;
386 PYTHON_SITEDIR)
387 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
388 # sysconfig can't be used because:
389 # 1) pypy doesn't give site-packages but stdlib
390 # 2) jython gives paths with wrong case
391 PYTHON_SITEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())') || die
392 export PYTHON_SITEDIR
393 debug-print "${FUNCNAME}: PYTHON_SITEDIR = ${PYTHON_SITEDIR}"
394 ;;
395 PYTHON_INCLUDEDIR)
396 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
397 PYTHON_INCLUDEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_inc())') || die
398 export PYTHON_INCLUDEDIR
399 debug-print "${FUNCNAME}: PYTHON_INCLUDEDIR = ${PYTHON_INCLUDEDIR}"
400
401 # Jython gives a non-existing directory
402 if [[ ! -d ${PYTHON_INCLUDEDIR} ]]; then
403 die "${impl} does not install any header files!"
404 fi
405 ;;
406 PYTHON_LIBPATH)
407 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
408 PYTHON_LIBPATH=$("${PYTHON}" -c 'import os.path, sysconfig; print(os.path.join(sysconfig.get_config_var("LIBDIR"), sysconfig.get_config_var("LDLIBRARY")) if sysconfig.get_config_var("LDLIBRARY") else "")') || die
409 export PYTHON_LIBPATH
410 debug-print "${FUNCNAME}: PYTHON_LIBPATH = ${PYTHON_LIBPATH}"
411
412 if [[ ! ${PYTHON_LIBPATH} ]]; then
413 die "${impl} lacks a (usable) dynamic library"
414 fi
415 ;;
416 PYTHON_CFLAGS)
417 local val
418
419 case "${impl}" in
420 python*)
421 # python-2.7, python-3.2, etc.
422 val=$($(tc-getPKG_CONFIG) --cflags ${impl/n/n-}) || die
423 ;;
424 *)
425 die "${impl}: obtaining ${var} not supported"
426 ;;
427 esac
428
429 export PYTHON_CFLAGS=${val}
430 debug-print "${FUNCNAME}: PYTHON_CFLAGS = ${PYTHON_CFLAGS}"
431 ;;
432 PYTHON_LIBS)
433 local val
434
435 case "${impl}" in
436 python*)
437 # python-2.7, python-3.2, etc.
438 val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-}) || die
439 ;;
440 *)
441 die "${impl}: obtaining ${var} not supported"
442 ;;
443 esac
444
445 export PYTHON_LIBS=${val}
446 debug-print "${FUNCNAME}: PYTHON_LIBS = ${PYTHON_LIBS}"
447 ;;
448 PYTHON_CONFIG)
449 local flags val
450
451 case "${impl}" in
452 python*)
453 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
454 flags=$("${PYTHON}" -c 'import sysconfig; print(sysconfig.get_config_var("ABIFLAGS") or "")') || die
455 val=${PYTHON}${flags}-config
456 ;;
457 *)
458 die "${impl}: obtaining ${var} not supported"
459 ;;
460 esac
461
462 export PYTHON_CONFIG=${val}
463 debug-print "${FUNCNAME}: PYTHON_CONFIG = ${PYTHON_CONFIG}"
464 ;;
465 PYTHON_PKG_DEP)
466 local d
467 case ${impl} in
468 python2.7)
469 PYTHON_PKG_DEP='>=dev-lang/python-2.7.5-r2:2.7';;
470 python3.3)
471 PYTHON_PKG_DEP='>=dev-lang/python-3.3.2-r2:3.3';;
472 python*)
473 PYTHON_PKG_DEP="dev-lang/python:${impl#python}";;
474 pypy)
Craig Hesling34e58412020-01-20 20:34:27 -0800475 PYTHON_PKG_DEP='>=dev-python/pypy-5:0=';;
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800476 pypy3)
Craig Hesling34e58412020-01-20 20:34:27 -0800477 PYTHON_PKG_DEP='>=dev-python/pypy3-5:0=';;
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800478 jython2.7)
479 PYTHON_PKG_DEP='dev-java/jython:2.7';;
480 *)
481 die "Invalid implementation: ${impl}"
482 esac
483
484 # use-dep
485 if [[ ${PYTHON_REQ_USE} ]]; then
486 PYTHON_PKG_DEP+=[${PYTHON_REQ_USE}]
487 fi
488
489 export PYTHON_PKG_DEP
490 debug-print "${FUNCNAME}: PYTHON_PKG_DEP = ${PYTHON_PKG_DEP}"
491 ;;
492 PYTHON_SCRIPTDIR)
493 local dir
494 export PYTHON_SCRIPTDIR=${EPREFIX}/usr/lib/python-exec/${impl}
495 debug-print "${FUNCNAME}: PYTHON_SCRIPTDIR = ${PYTHON_SCRIPTDIR}"
496 ;;
497 *)
498 die "python_export: unknown variable ${var}"
499 esac
500 done
501}
502
503# @FUNCTION: python_get_sitedir
504# @USAGE: [<impl>]
505# @DESCRIPTION:
506# Obtain and print the 'site-packages' path for the given
507# implementation. If no implementation is provided, ${EPYTHON} will
508# be used.
509#
510# If you just need to have PYTHON_SITEDIR set (and exported), then it is
511# better to use python_export() directly instead.
512python_get_sitedir() {
513 debug-print-function ${FUNCNAME} "${@}"
514
515 python_export "${@}" PYTHON_SITEDIR
516 echo "${PYTHON_SITEDIR}"
517}
518
519# @FUNCTION: python_get_includedir
520# @USAGE: [<impl>]
521# @DESCRIPTION:
522# Obtain and print the include path for the given implementation. If no
523# implementation is provided, ${EPYTHON} will be used.
524#
525# If you just need to have PYTHON_INCLUDEDIR set (and exported), then it
526# is better to use python_export() directly instead.
527python_get_includedir() {
528 debug-print-function ${FUNCNAME} "${@}"
529
530 python_export "${@}" PYTHON_INCLUDEDIR
531 echo "${PYTHON_INCLUDEDIR}"
532}
533
534# @FUNCTION: python_get_library_path
535# @USAGE: [<impl>]
536# @DESCRIPTION:
537# Obtain and print the Python library path for the given implementation.
538# If no implementation is provided, ${EPYTHON} will be used.
539#
540# Please note that this function can be used with CPython only. Use
541# in another implementation will result in a fatal failure.
542python_get_library_path() {
543 debug-print-function ${FUNCNAME} "${@}"
544
545 python_export "${@}" PYTHON_LIBPATH
546 echo "${PYTHON_LIBPATH}"
547}
548
549# @FUNCTION: python_get_CFLAGS
550# @USAGE: [<impl>]
551# @DESCRIPTION:
552# Obtain and print the compiler flags for building against Python,
553# for the given implementation. If no implementation is provided,
554# ${EPYTHON} will be used.
555#
556# Please note that this function can be used with CPython only.
557# It requires Python and pkg-config installed, and therefore proper
558# build-time dependencies need be added to the ebuild.
559python_get_CFLAGS() {
560 debug-print-function ${FUNCNAME} "${@}"
561
562 python_export "${@}" PYTHON_CFLAGS
563 echo "${PYTHON_CFLAGS}"
564}
565
566# @FUNCTION: python_get_LIBS
567# @USAGE: [<impl>]
568# @DESCRIPTION:
569# Obtain and print the compiler flags for linking against Python,
570# for the given implementation. If no implementation is provided,
571# ${EPYTHON} will be used.
572#
573# Please note that this function can be used with CPython only.
574# It requires Python and pkg-config installed, and therefore proper
575# build-time dependencies need be added to the ebuild.
576python_get_LIBS() {
577 debug-print-function ${FUNCNAME} "${@}"
578
579 python_export "${@}" PYTHON_LIBS
580 echo "${PYTHON_LIBS}"
581}
582
583# @FUNCTION: python_get_PYTHON_CONFIG
584# @USAGE: [<impl>]
585# @DESCRIPTION:
586# Obtain and print the PYTHON_CONFIG location for the given
587# implementation. If no implementation is provided, ${EPYTHON} will be
588# used.
589#
590# Please note that this function can be used with CPython only.
591# It requires Python installed, and therefore proper build-time
592# dependencies need be added to the ebuild.
593python_get_PYTHON_CONFIG() {
594 debug-print-function ${FUNCNAME} "${@}"
595
596 python_export "${@}" PYTHON_CONFIG
597 echo "${PYTHON_CONFIG}"
598}
599
600# @FUNCTION: python_get_scriptdir
601# @USAGE: [<impl>]
602# @DESCRIPTION:
603# Obtain and print the script install path for the given
604# implementation. If no implementation is provided, ${EPYTHON} will
605# be used.
606python_get_scriptdir() {
607 debug-print-function ${FUNCNAME} "${@}"
608
609 python_export "${@}" PYTHON_SCRIPTDIR
610 echo "${PYTHON_SCRIPTDIR}"
611}
612
613# @FUNCTION: _python_ln_rel
614# @USAGE: <from> <to>
615# @INTERNAL
616# @DESCRIPTION:
617# Create a relative symlink.
618_python_ln_rel() {
619 debug-print-function ${FUNCNAME} "${@}"
620
621 local target=${1}
622 local symname=${2}
623
624 local tgpath=${target%/*}/
625 local sympath=${symname%/*}/
626 local rel_target=
627
628 while [[ ${sympath} ]]; do
629 local tgseg= symseg=
630
631 while [[ ! ${tgseg} && ${tgpath} ]]; do
632 tgseg=${tgpath%%/*}
633 tgpath=${tgpath#${tgseg}/}
634 done
635
636 while [[ ! ${symseg} && ${sympath} ]]; do
637 symseg=${sympath%%/*}
638 sympath=${sympath#${symseg}/}
639 done
640
641 if [[ ${tgseg} != ${symseg} ]]; then
642 rel_target=../${rel_target}${tgseg:+${tgseg}/}
643 fi
644 done
645 rel_target+=${tgpath}${target##*/}
646
647 debug-print "${FUNCNAME}: ${symname} -> ${target}"
648 debug-print "${FUNCNAME}: rel_target = ${rel_target}"
649
650 ln -fs "${rel_target}" "${symname}"
651}
652
653# @FUNCTION: python_optimize
654# @USAGE: [<directory>...]
655# @DESCRIPTION:
656# Compile and optimize Python modules in specified directories (absolute
657# paths). If no directories are provided, the default system paths
658# are used (prepended with ${D}).
659python_optimize() {
660 debug-print-function ${FUNCNAME} "${@}"
661
662 if [[ ${EBUILD_PHASE} == pre* || ${EBUILD_PHASE} == post* ]]; then
663 eerror "The new Python eclasses expect the compiled Python files to"
664 eerror "be controlled by the Package Manager. For this reason,"
665 eerror "the python_optimize function can be used only during src_* phases"
666 eerror "(src_install most commonly) and not during pkg_* phases."
667 echo
668 die "python_optimize is not to be used in pre/post* phases"
669 fi
670
671 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
672
673 local PYTHON=${PYTHON}
674 [[ ${PYTHON} ]] || python_export PYTHON
675
676 # default to sys.path
677 if [[ ${#} -eq 0 ]]; then
678 local f
679 while IFS= read -r -d '' f; do
680 # 1) accept only absolute paths
681 # (i.e. skip '', '.' or anything like that)
682 # 2) skip paths which do not exist
683 # (python2.6 complains about them verbosely)
684
685 if [[ ${f} == /* && -d ${D%/}${f} ]]; then
686 set -- "${D%/}${f}" "${@}"
687 fi
Craig Hesling34e58412020-01-20 20:34:27 -0800688 done < <("${PYTHON}" -c 'import sys; print("".join(x + "\0" for x in sys.path))' || die)
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800689
690 debug-print "${FUNCNAME}: using sys.path: ${*/%/;}"
691 fi
692
693 local d
694 for d; do
695 # make sure to get a nice path without //
696 local instpath=${d#${D%/}}
697 instpath=/${instpath##/}
698
699 case "${EPYTHON}" in
700 python2.7|python3.[34])
701 "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
702 "${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
703 ;;
704 python*|pypy3)
705 # both levels of optimization are separate since 3.5
706 "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
707 "${PYTHON}" -O -m compileall -q -f -d "${instpath}" "${d}"
708 "${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
709 ;;
710 *)
711 "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
712 ;;
713 esac
714 done
715}
716
717# @FUNCTION: python_scriptinto
718# @USAGE: <new-path>
719# @DESCRIPTION:
720# Set the directory to which files passed to python_doexe(),
721# python_doscript(), python_newexe() and python_newscript()
722# are going to be installed. The new value needs to be relative
723# to the installation root (${ED}).
724#
725# If not set explicitly, the directory defaults to /usr/bin.
726#
727# Example:
728# @CODE
729# src_install() {
730# python_scriptinto /usr/sbin
731# python_foreach_impl python_doscript foo
732# }
733# @CODE
734python_scriptinto() {
735 debug-print-function ${FUNCNAME} "${@}"
736
737 python_scriptroot=${1}
738}
739
740# @FUNCTION: python_doexe
741# @USAGE: <files>...
742# @DESCRIPTION:
743# Install the given executables into the executable install directory,
744# for the current Python implementation (${EPYTHON}).
745#
746# The executable will be wrapped properly for the Python implementation,
747# though no shebang mangling will be performed.
748python_doexe() {
749 debug-print-function ${FUNCNAME} "${@}"
750
751 local f
752 for f; do
753 python_newexe "${f}" "${f##*/}"
754 done
755}
756
757# @FUNCTION: python_newexe
758# @USAGE: <path> <new-name>
759# @DESCRIPTION:
760# Install the given executable into the executable install directory,
761# for the current Python implementation (${EPYTHON}).
762#
763# The executable will be wrapped properly for the Python implementation,
764# though no shebang mangling will be performed. It will be renamed
765# to <new-name>.
766python_newexe() {
767 debug-print-function ${FUNCNAME} "${@}"
768
769 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
770 [[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} <path> <new-name>"
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800771
772 local wrapd=${python_scriptroot:-/usr/bin}
773
774 local f=${1}
775 local newfn=${2}
776
777 local PYTHON_SCRIPTDIR d
778 python_export PYTHON_SCRIPTDIR
779 d=${PYTHON_SCRIPTDIR#${EPREFIX}}
780
781 (
782 dodir "${wrapd}"
783 exeopts -m 0755
784 exeinto "${d}"
785 newexe "${f}" "${newfn}" || return ${?}
786 )
787
788 # install the wrapper
789 _python_ln_rel "${ED%/}"/usr/lib/python-exec/python-exec2 \
790 "${ED%/}/${wrapd}/${newfn}" || die
791
792 # don't use this at home, just call python_doscript() instead
793 if [[ ${_PYTHON_REWRITE_SHEBANG} ]]; then
794 python_fix_shebang -q "${ED%/}/${d}/${newfn}"
795 fi
796}
797
798# @FUNCTION: python_doscript
799# @USAGE: <files>...
800# @DESCRIPTION:
801# Install the given scripts into the executable install directory,
802# for the current Python implementation (${EPYTHON}).
803#
804# All specified files must start with a 'python' shebang. The shebang
805# will be converted, and the files will be wrapped properly
806# for the Python implementation.
807#
808# Example:
809# @CODE
810# src_install() {
811# python_foreach_impl python_doscript ${PN}
812# }
813# @CODE
814python_doscript() {
815 debug-print-function ${FUNCNAME} "${@}"
816
817 local _PYTHON_REWRITE_SHEBANG=1
818 python_doexe "${@}"
819}
820
821# @FUNCTION: python_newscript
822# @USAGE: <path> <new-name>
823# @DESCRIPTION:
824# Install the given script into the executable install directory
825# for the current Python implementation (${EPYTHON}), and name it
826# <new-name>.
827#
828# The file must start with a 'python' shebang. The shebang will be
829# converted, and the file will be wrapped properly for the Python
830# implementation. It will be renamed to <new-name>.
831#
832# Example:
833# @CODE
834# src_install() {
835# python_foreach_impl python_newscript foo.py foo
836# }
837# @CODE
838python_newscript() {
839 debug-print-function ${FUNCNAME} "${@}"
840
841 local _PYTHON_REWRITE_SHEBANG=1
842 python_newexe "${@}"
843}
844
845# @FUNCTION: python_moduleinto
846# @USAGE: <new-path>
847# @DESCRIPTION:
848# Set the Python module install directory for python_domodule().
849# The <new-path> can either be an absolute target system path (in which
850# case it needs to start with a slash, and ${ED} will be prepended to
851# it) or relative to the implementation's site-packages directory
852# (then it must not start with a slash). The relative path can be
853# specified either using the Python package notation (separated by dots)
854# or the directory notation (using slashes).
855#
856# When not set explicitly, the modules are installed to the top
857# site-packages directory.
858#
859# In the relative case, the exact path is determined directly
860# by each python_doscript/python_newscript function. Therefore,
861# python_moduleinto can be safely called before establishing the Python
862# interpreter and/or a single call can be used to set the path correctly
863# for multiple implementations, as can be seen in the following example.
864#
865# Example:
866# @CODE
867# src_install() {
868# python_moduleinto bar
869# # installs ${PYTHON_SITEDIR}/bar/baz.py
870# python_foreach_impl python_domodule baz.py
871# }
872# @CODE
873python_moduleinto() {
874 debug-print-function ${FUNCNAME} "${@}"
875
876 python_moduleroot=${1}
877}
878
879# @FUNCTION: python_domodule
880# @USAGE: <files>...
881# @DESCRIPTION:
882# Install the given modules (or packages) into the current Python module
883# installation directory. The list can mention both modules (files)
884# and packages (directories). All listed files will be installed
885# for all enabled implementations, and compiled afterwards.
886#
887# Example:
888# @CODE
889# src_install() {
890# # (${PN} being a directory)
891# python_foreach_impl python_domodule ${PN}
892# }
893# @CODE
894python_domodule() {
895 debug-print-function ${FUNCNAME} "${@}"
896
897 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800898
899 local d
900 if [[ ${python_moduleroot} == /* ]]; then
901 # absolute path
902 d=${python_moduleroot}
903 else
904 # relative to site-packages
905 local PYTHON_SITEDIR=${PYTHON_SITEDIR}
906 [[ ${PYTHON_SITEDIR} ]] || python_export PYTHON_SITEDIR
907
Allen Webb6664ce22019-01-28 13:38:58 -0800908 d=${PYTHON_SITEDIR#${SYSROOT}}/${python_moduleroot//.//}
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800909 fi
910
911 (
912 insopts -m 0644
913 insinto "${d}"
914 doins -r "${@}" || return ${?}
915 )
916
917 python_optimize "${ED%/}/${d}"
918}
919
920# @FUNCTION: python_doheader
921# @USAGE: <files>...
922# @DESCRIPTION:
923# Install the given headers into the implementation-specific include
924# directory. This function is unconditionally recursive, i.e. you can
925# pass directories instead of files.
926#
927# Example:
928# @CODE
929# src_install() {
930# python_foreach_impl python_doheader foo.h bar.h
931# }
932# @CODE
933python_doheader() {
934 debug-print-function ${FUNCNAME} "${@}"
935
936 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800937
938 local d PYTHON_INCLUDEDIR=${PYTHON_INCLUDEDIR}
939 [[ ${PYTHON_INCLUDEDIR} ]] || python_export PYTHON_INCLUDEDIR
940
Allen Webb6664ce22019-01-28 13:38:58 -0800941 d=${PYTHON_INCLUDEDIR#${SYSROOT}}
Allen Webb7cfd3dc2019-01-28 13:27:13 -0800942
943 (
944 insopts -m 0644
945 insinto "${d}"
946 doins -r "${@}" || return ${?}
947 )
948}
949
950# @FUNCTION: python_wrapper_setup
951# @USAGE: [<path> [<impl>]]
952# @DESCRIPTION:
953# Create proper 'python' executable and pkg-config wrappers
954# (if available) in the directory named by <path>. Set up PATH
955# and PKG_CONFIG_PATH appropriately. <path> defaults to ${T}/${EPYTHON}.
956#
957# The wrappers will be created for implementation named by <impl>,
958# or for one named by ${EPYTHON} if no <impl> passed.
959#
960# If the named directory contains a python symlink already, it will
961# be assumed to contain proper wrappers already and only environment
962# setup will be done. If wrapper update is requested, the directory
963# shall be removed first.
964python_wrapper_setup() {
965 debug-print-function ${FUNCNAME} "${@}"
966
967 local workdir=${1:-${T}/${EPYTHON}}
968 local impl=${2:-${EPYTHON}}
969
970 [[ ${workdir} ]] || die "${FUNCNAME}: no workdir specified."
971 [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON specified."
972
973 if [[ ! -x ${workdir}/bin/python ]]; then
974 _python_check_dead_variables
975
976 mkdir -p "${workdir}"/{bin,pkgconfig} || die
977
978 # Clean up, in case we were supposed to do a cheap update.
979 rm -f "${workdir}"/bin/python{,2,3}{,-config} || die
980 rm -f "${workdir}"/bin/2to3 || die
981 rm -f "${workdir}"/pkgconfig/python{,2,3}.pc || die
982
983 local EPYTHON PYTHON
984 python_export "${impl}" EPYTHON PYTHON
985
986 local pyver pyother
987 if python_is_python3; then
988 pyver=3
989 pyother=2
990 else
991 pyver=2
992 pyother=3
993 fi
994
995 # Python interpreter
996 # note: we don't use symlinks because python likes to do some
997 # symlink reading magic that breaks stuff
998 # https://bugs.gentoo.org/show_bug.cgi?id=555752
999 cat > "${workdir}/bin/python" <<-_EOF_ || die
1000 #!/bin/sh
1001 exec "${PYTHON}" "\${@}"
1002 _EOF_
1003 cp "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
1004 chmod +x "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
1005
1006 local nonsupp=( "python${pyother}" "python${pyother}-config" )
1007
1008 # CPython-specific
1009 if [[ ${EPYTHON} == python* ]]; then
1010 cat > "${workdir}/bin/python-config" <<-_EOF_ || die
1011 #!/bin/sh
1012 exec "${PYTHON}-config" "\${@}"
1013 _EOF_
1014 cp "${workdir}/bin/python-config" \
1015 "${workdir}/bin/python${pyver}-config" || die
1016 chmod +x "${workdir}/bin/python-config" \
1017 "${workdir}/bin/python${pyver}-config" || die
1018
1019 # Python 2.6+.
1020 ln -s "${PYTHON/python/2to3-}" "${workdir}"/bin/2to3 || die
1021
1022 # Python 2.7+.
1023 ln -s "${EPREFIX}"/usr/$(get_libdir)/pkgconfig/${EPYTHON/n/n-}.pc \
1024 "${workdir}"/pkgconfig/python.pc || die
1025 ln -s python.pc "${workdir}"/pkgconfig/python${pyver}.pc || die
1026 else
1027 nonsupp+=( 2to3 python-config "python${pyver}-config" )
1028 fi
1029
1030 local x
1031 for x in "${nonsupp[@]}"; do
1032 cat >"${workdir}"/bin/${x} <<-_EOF_ || die
1033 #!/bin/sh
1034 echo "${ECLASS}: ${FUNCNAME}: ${x} is not supported by ${EPYTHON} (PYTHON_COMPAT)" >&2
1035 exit 127
1036 _EOF_
1037 chmod +x "${workdir}"/bin/${x} || die
1038 done
1039 fi
1040
1041 # Now, set the environment.
1042 # But note that ${workdir} may be shared with something else,
1043 # and thus already on top of PATH.
1044 if [[ ${PATH##:*} != ${workdir}/bin ]]; then
1045 PATH=${workdir}/bin${PATH:+:${PATH}}
1046 fi
1047 if [[ ${PKG_CONFIG_PATH##:*} != ${workdir}/pkgconfig ]]; then
1048 PKG_CONFIG_PATH=${workdir}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
1049 fi
1050 export PATH PKG_CONFIG_PATH
1051}
1052
1053# @FUNCTION: python_is_python3
1054# @USAGE: [<impl>]
1055# @DESCRIPTION:
1056# Check whether <impl> (or ${EPYTHON}) is a Python3k variant
1057# (i.e. uses syntax and stdlib of Python 3.*).
1058#
1059# Returns 0 (true) if it is, 1 (false) otherwise.
1060python_is_python3() {
1061 local impl=${1:-${EPYTHON}}
1062 [[ ${impl} ]] || die "python_is_python3: no impl nor EPYTHON"
1063
1064 [[ ${impl} == python3* || ${impl} == pypy3 ]]
1065}
1066
1067# @FUNCTION: python_is_installed
1068# @USAGE: [<impl>]
1069# @DESCRIPTION:
1070# Check whether the interpreter for <impl> (or ${EPYTHON}) is installed.
1071# Uses has_version with a proper dependency string.
1072#
1073# Returns 0 (true) if it is, 1 (false) otherwise.
1074python_is_installed() {
1075 local impl=${1:-${EPYTHON}}
1076 [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON"
1077 local hasv_args=()
1078
Craig Hesling34e58412020-01-20 20:34:27 -08001079 case ${EAPI} in
Allen Webb7cfd3dc2019-01-28 13:27:13 -08001080 5|6)
1081 hasv_args+=( --host-root )
1082 ;;
1083 *)
1084 hasv_args+=( -b )
1085 ;;
1086 esac
1087
1088 case "${impl}" in
1089 pypy|pypy3)
1090 local append=
1091 if [[ ${PYTHON_REQ_USE} ]]; then
1092 append=[${PYTHON_REQ_USE}]
1093 fi
1094
1095 # be happy with just the interpeter, no need for the virtual
1096 has_version "${hasv_args[@]}" "dev-python/${impl}${append}" \
1097 || has_version "${hasv_args[@]}" "dev-python/${impl}-bin${append}"
1098 ;;
1099 *)
1100 local PYTHON_PKG_DEP
1101 python_export "${impl}" PYTHON_PKG_DEP
1102 has_version "${hasv_args[@]}" "${PYTHON_PKG_DEP}"
1103 ;;
1104 esac
1105}
1106
1107# @FUNCTION: python_fix_shebang
1108# @USAGE: [-f|--force] [-q|--quiet] <path>...
1109# @DESCRIPTION:
1110# Replace the shebang in Python scripts with the current Python
1111# implementation (EPYTHON). If a directory is passed, works recursively
1112# on all Python scripts.
1113#
1114# Only files having a 'python*' shebang will be modified. Files with
1115# other shebang will either be skipped when working recursively
1116# on a directory or treated as error when specified explicitly.
1117#
1118# Shebangs matching explicitly current Python version will be left
1119# unmodified. Shebangs requesting another Python version will be treated
1120# as fatal error, unless --force is given.
1121#
1122# --force causes the function to replace even shebangs that require
1123# incompatible Python version. --quiet causes the function not to list
1124# modified files verbosely.
1125python_fix_shebang() {
1126 debug-print-function ${FUNCNAME} "${@}"
1127
1128 [[ ${EPYTHON} ]] || die "${FUNCNAME}: EPYTHON unset (pkg_setup not called?)"
1129
1130 local force quiet
1131 while [[ ${@} ]]; do
1132 case "${1}" in
1133 -f|--force) force=1; shift;;
1134 -q|--quiet) quiet=1; shift;;
1135 --) shift; break;;
1136 *) break;;
1137 esac
1138 done
1139
1140 [[ ${1} ]] || die "${FUNCNAME}: no paths given"
1141
1142 local path f
1143 for path; do
1144 local any_correct any_fixed is_recursive
1145
1146 [[ -d ${path} ]] && is_recursive=1
1147
1148 while IFS= read -r -d '' f; do
1149 local shebang i
1150 local error= from=
1151
1152 # note: we can't ||die here since read will fail if file
1153 # has no newline characters
1154 IFS= read -r shebang <"${f}"
1155
1156 # First, check if it's shebang at all...
1157 if [[ ${shebang} == '#!'* ]]; then
1158 local split_shebang=()
1159 read -r -a split_shebang <<<${shebang} || die
1160
1161 # Match left-to-right in a loop, to avoid matching random
1162 # repetitions like 'python2.7 python2'.
1163 for i in "${split_shebang[@]}"; do
1164 case "${i}" in
1165 *"${EPYTHON}")
1166 debug-print "${FUNCNAME}: in file ${f#${D%/}}"
1167 debug-print "${FUNCNAME}: shebang matches EPYTHON: ${shebang}"
1168
1169 # Nothing to do, move along.
1170 any_correct=1
1171 from=${EPYTHON}
1172 break
1173 ;;
1174 *python|*python[23])
1175 debug-print "${FUNCNAME}: in file ${f#${D%/}}"
1176 debug-print "${FUNCNAME}: rewriting shebang: ${shebang}"
1177
1178 if [[ ${i} == *python2 ]]; then
1179 from=python2
1180 if [[ ! ${force} ]]; then
1181 python_is_python3 "${EPYTHON}" && error=1
1182 fi
1183 elif [[ ${i} == *python3 ]]; then
1184 from=python3
1185 if [[ ! ${force} ]]; then
1186 python_is_python3 "${EPYTHON}" || error=1
1187 fi
1188 else
1189 from=python
1190 fi
1191 break
1192 ;;
1193 *python[23].[0123456789]|*pypy|*pypy3|*jython[23].[0123456789])
1194 # Explicit mismatch.
1195 if [[ ! ${force} ]]; then
1196 error=1
1197 else
1198 case "${i}" in
1199 *python[23].[0123456789])
1200 from="python[23].[0123456789]";;
1201 *pypy)
1202 from="pypy";;
1203 *pypy3)
1204 from="pypy3";;
1205 *jython[23].[0123456789])
1206 from="jython[23].[0123456789]";;
1207 *)
1208 die "${FUNCNAME}: internal error in 2nd pattern match";;
1209 esac
1210 fi
1211 break
1212 ;;
1213 esac
1214 done
1215 fi
1216
1217 if [[ ! ${error} && ! ${from} ]]; then
1218 # Non-Python shebang. Allowed in recursive mode,
1219 # disallowed when specifying file explicitly.
1220 [[ ${is_recursive} ]] && continue
1221 error=1
1222 fi
1223
1224 if [[ ! ${quiet} ]]; then
1225 einfo "Fixing shebang in ${f#${D%/}}."
1226 fi
1227
1228 if [[ ! ${error} ]]; then
1229 # We either want to match ${from} followed by space
1230 # or at end-of-string.
1231 if [[ ${shebang} == *${from}" "* ]]; then
1232 sed -i -e "1s:${from} :${EPYTHON} :" "${f}" || die
1233 else
1234 sed -i -e "1s:${from}$:${EPYTHON}:" "${f}" || die
1235 fi
1236 any_fixed=1
1237 else
1238 eerror "The file has incompatible shebang:"
1239 eerror " file: ${f#${D%/}}"
1240 eerror " current shebang: ${shebang}"
1241 eerror " requested impl: ${EPYTHON}"
1242 die "${FUNCNAME}: conversion of incompatible shebang requested"
1243 fi
1244 done < <(find -H "${path}" -type f -print0 || die)
1245
1246 if [[ ! ${any_fixed} ]]; then
1247 local cmd=eerror
Craig Hesling34e58412020-01-20 20:34:27 -08001248 [[ ${EAPI} == 5 ]] && cmd=eqawarn
Allen Webb7cfd3dc2019-01-28 13:27:13 -08001249
1250 "${cmd}" "QA warning: ${FUNCNAME}, ${path#${D%/}} did not match any fixable files."
1251 if [[ ${any_correct} ]]; then
1252 "${cmd}" "All files have ${EPYTHON} shebang already."
1253 else
1254 "${cmd}" "There are no Python files in specified directory."
1255 fi
1256
1257 [[ ${cmd} == eerror ]] && die "${FUNCNAME} did not match any fixable files (QA warning fatal in EAPI ${EAPI})"
1258 fi
1259 done
1260}
1261
1262# @FUNCTION: _python_check_locale_sanity
1263# @USAGE: <locale>
1264# @RETURN: 0 if sane, 1 otherwise
1265# @DESCRIPTION:
1266# Check whether the specified locale sanely maps between lowercase
1267# and uppercase ASCII characters.
1268_python_check_locale_sanity() {
1269 local -x LC_ALL=${1}
1270 local IFS=
1271
1272 local lc=( {a..z} )
1273 local uc=( {A..Z} )
1274 local input="${lc[*]}${uc[*]}"
1275
1276 local output=$(tr '[:lower:][:upper:]' '[:upper:][:lower:]' <<<"${input}")
1277 [[ ${output} == "${uc[*]}${lc[*]}" ]]
1278}
1279
1280# @FUNCTION: python_export_utf8_locale
1281# @RETURN: 0 on success, 1 on failure.
1282# @DESCRIPTION:
1283# Attempts to export a usable UTF-8 locale in the LC_CTYPE variable. Does
1284# nothing if LC_ALL is defined, or if the current locale uses a UTF-8 charmap.
1285# This may be used to work around the quirky open() behavior of python3.
1286python_export_utf8_locale() {
1287 debug-print-function ${FUNCNAME} "${@}"
1288
1289 # If the locale program isn't available, just return.
1290 type locale >/dev/null || return 0
1291
1292 if [[ $(locale charmap) != UTF-8 ]]; then
1293 # Try English first, then everything else.
1294 local lang locales="C.UTF-8 en_US.UTF-8 en_GB.UTF-8 $(locale -a)"
1295
1296 for lang in ${locales}; do
1297 if [[ $(LC_ALL=${lang} locale charmap 2>/dev/null) == UTF-8 ]]; then
1298 if _python_check_locale_sanity "${lang}"; then
1299 export LC_CTYPE=${lang}
1300 if [[ -n ${LC_ALL} ]]; then
1301 export LC_NUMERIC=${LC_ALL}
1302 export LC_TIME=${LC_ALL}
1303 export LC_COLLATE=${LC_ALL}
1304 export LC_MONETARY=${LC_ALL}
1305 export LC_MESSAGES=${LC_ALL}
1306 export LC_PAPER=${LC_ALL}
1307 export LC_NAME=${LC_ALL}
1308 export LC_ADDRESS=${LC_ALL}
1309 export LC_TELEPHONE=${LC_ALL}
1310 export LC_MEASUREMENT=${LC_ALL}
1311 export LC_IDENTIFICATION=${LC_ALL}
1312 export LC_ALL=
1313 fi
1314 return 0
1315 fi
1316 fi
1317 done
1318
1319 ewarn "Could not find a UTF-8 locale. This may trigger build failures in"
1320 ewarn "some python packages. Please ensure that a UTF-8 locale is listed in"
1321 ewarn "/etc/locale.gen and run locale-gen."
1322 return 1
1323 fi
1324
1325 return 0
1326}
1327
Craig Hesling34e58412020-01-20 20:34:27 -08001328# @FUNCTION: build_sphinx
1329# @USAGE: <directory>
1330# @DESCRIPTION:
1331# Build HTML documentation using dev-python/sphinx in the specified
1332# <directory>. Takes care of disabling Intersphinx and appending
1333# to HTML_DOCS.
1334#
1335# If <directory> is relative to the current directory, care needs
1336# to be taken to run einstalldocs from the same directory
1337# (usually ${S}).
1338build_sphinx() {
1339 debug-print-function ${FUNCNAME} "${@}"
1340 [[ ${#} -eq 1 ]] || die "${FUNCNAME} takes 1 arg: <directory>"
1341
1342 local dir=${1}
1343
1344 sed -i -e 's:^intersphinx_mapping:disabled_&:' \
1345 "${dir}"/conf.py || die
1346 # not all packages include the Makefile in pypi tarball
1347 sphinx-build -b html -d "${dir}"/_build/doctrees "${dir}" \
1348 "${dir}"/_build/html || die
1349
1350 HTML_DOCS+=( "${dir}/_build/html/." )
1351}
1352
Allen Webb7cfd3dc2019-01-28 13:27:13 -08001353# -- python.eclass functions --
1354
1355_python_check_dead_variables() {
1356 local v
1357
1358 for v in PYTHON_DEPEND PYTHON_USE_WITH{,_OR,_OPT} {RESTRICT,SUPPORT}_PYTHON_ABIS
1359 do
1360 if [[ ${!v} ]]; then
1361 die "${v} is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Ebuild_head"
1362 fi
1363 done
1364
1365 for v in PYTHON_{CPPFLAGS,CFLAGS,CXXFLAGS,LDFLAGS}
1366 do
1367 if [[ ${!v} ]]; then
1368 die "${v} is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#PYTHON_CFLAGS"
1369 fi
1370 done
1371
1372 for v in PYTHON_TESTS_RESTRICTED_ABIS PYTHON_EXPORT_PHASE_FUNCTIONS \
1373 PYTHON_VERSIONED_{SCRIPTS,EXECUTABLES} PYTHON_NONVERSIONED_EXECUTABLES
1374 do
1375 if [[ ${!v} ]]; then
1376 die "${v} is invalid for python-r1 suite"
1377 fi
1378 done
1379
1380 for v in DISTUTILS_USE_SEPARATE_SOURCE_DIRECTORIES DISTUTILS_SETUP_FILES \
1381 DISTUTILS_GLOBAL_OPTIONS DISTUTILS_SRC_TEST PYTHON_MODNAME
1382 do
1383 if [[ ${!v} ]]; then
1384 die "${v} is invalid for distutils-r1, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#${v}"
1385 fi
1386 done
1387
1388 if [[ ${DISTUTILS_DISABLE_TEST_DEPENDENCY} ]]; then
1389 die "${v} is invalid for distutils-r1, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#DISTUTILS_SRC_TEST"
1390 fi
1391
1392 # python.eclass::progress
1393 for v in PYTHON_BDEPEND PYTHON_MULTIPLE_ABIS PYTHON_ABI_TYPE \
1394 PYTHON_RESTRICTED_ABIS PYTHON_TESTS_FAILURES_TOLERANT_ABIS \
1395 PYTHON_CFFI_MODULES_GENERATION_COMMANDS
1396 do
1397 if [[ ${!v} ]]; then
1398 die "${v} is invalid for python-r1 suite"
1399 fi
1400 done
1401}
1402
1403python_pkg_setup() {
1404 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#pkg_setup"
1405}
1406
1407python_convert_shebangs() {
1408 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#python_convert_shebangs"
1409}
1410
1411python_clean_py-compile_files() {
1412 die "${FUNCNAME}() is invalid for python-r1 suite"
1413}
1414
1415python_clean_installation_image() {
1416 die "${FUNCNAME}() is invalid for python-r1 suite"
1417}
1418
1419python_execute_function() {
1420 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#python_execute_function"
1421}
1422
1423python_generate_wrapper_scripts() {
1424 die "${FUNCNAME}() is invalid for python-r1 suite"
1425}
1426
1427python_merge_intermediate_installation_images() {
1428 die "${FUNCNAME}() is invalid for python-r1 suite"
1429}
1430
1431python_set_active_version() {
1432 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#pkg_setup"
1433}
1434
1435python_need_rebuild() {
1436 die "${FUNCNAME}() is invalid for python-r1 suite"
1437}
1438
1439PYTHON() {
1440 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#.24.28PYTHON.29.2C_.24.7BEPYTHON.7D"
1441}
1442
1443python_get_implementation() {
1444 die "${FUNCNAME}() is invalid for python-r1 suite"
1445}
1446
1447python_get_implementational_package() {
1448 die "${FUNCNAME}() is invalid for python-r1 suite"
1449}
1450
1451python_get_libdir() {
1452 die "${FUNCNAME}() is invalid for python-r1 suite"
1453}
1454
1455python_get_library() {
1456 die "${FUNCNAME}() is invalid for python-r1 suite"
1457}
1458
1459python_get_version() {
1460 die "${FUNCNAME}() is invalid for python-r1 suite"
1461}
1462
1463python_get_implementation_and_version() {
1464 die "${FUNCNAME}() is invalid for python-r1 suite"
1465}
1466
1467python_execute_nosetests() {
1468 die "${FUNCNAME}() is invalid for python-r1 suite"
1469}
1470
1471python_execute_py.test() {
1472 die "${FUNCNAME}() is invalid for python-r1 suite"
1473}
1474
1475python_execute_trial() {
1476 die "${FUNCNAME}() is invalid for python-r1 suite"
1477}
1478
1479python_enable_pyc() {
1480 die "${FUNCNAME}() is invalid for python-r1 suite"
1481}
1482
1483python_disable_pyc() {
1484 die "${FUNCNAME}() is invalid for python-r1 suite"
1485}
1486
1487python_mod_optimize() {
1488 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Python_byte-code_compilation"
1489}
1490
1491python_mod_cleanup() {
1492 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Python_byte-code_compilation"
1493}
1494
1495# python.eclass::progress
1496
1497python_abi_depend() {
1498 die "${FUNCNAME}() is invalid for python-r1 suite"
1499}
1500
1501python_install_executables() {
1502 die "${FUNCNAME}() is invalid for python-r1 suite"
1503}
1504
1505python_get_extension_module_suffix() {
1506 die "${FUNCNAME}() is invalid for python-r1 suite"
1507}
1508
1509python_byte-compile_modules() {
1510 die "${FUNCNAME}() is invalid for python-r1 suite"
1511}
1512
1513python_clean_byte-compiled_modules() {
1514 die "${FUNCNAME}() is invalid for python-r1 suite"
1515}
1516
1517python_generate_cffi_modules() {
1518 die "${FUNCNAME}() is invalid for python-r1 suite"
1519}
1520
1521_PYTHON_UTILS_R1=1
1522fi