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