eclass: sync python eclasses

This commit is contained in:
Nick Owens 2016-01-25 11:48:21 -08:00
parent 193fd5dd8c
commit d7966f82ed
5 changed files with 546 additions and 483 deletions

View File

@ -1,8 +1,8 @@
# Copyright 1999-2014 Gentoo Foundation
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/python-any-r1.eclass,v 1.18 2014/11/09 22:27:58 mgorny Exp $
# $Id$
# @ECLASS: python-any-r1
# @ECLASS: python-any-r1.eclass
# @MAINTAINER:
# Python team <python@gentoo.org>
# @AUTHOR:
@ -33,12 +33,11 @@
# packages using python-any-r1, and there is no need ever to inherit
# both.
#
# For more information, please see the python-r1 Developer's Guide:
# http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml
# For more information, please see the wiki:
# https://wiki.gentoo.org/wiki/Project:Python/python-any-r1
case "${EAPI:-0}" in
0|1|2|3|4|5)
# EAPI=4 needed by python-r1
0|1|2|3|4|5|6)
;;
*)
die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
@ -72,9 +71,24 @@ if [[ ! ${_PYTHON_ANY_R1} ]]; then
# @CODE
# PYTHON_COMPAT=( python{2_5,2_6,2_7} )
# @CODE
if ! declare -p PYTHON_COMPAT &>/dev/null; then
die 'PYTHON_COMPAT not declared.'
fi
# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
# @INTERNAL
# @DESCRIPTION:
# This variable can be used when working with ebuilds to override
# the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
# which will be used to build the package. It needs to be specified
# in the calling environment, and not in ebuilds.
#
# It should be noted that in order to preserve metadata immutability,
# PYTHON_COMPAT_OVERRIDE does not affect dependencies. The value of
# EPYTHON and eselect-python preferences are ignored. Dependencies need
# to be satisfied manually.
#
# Example:
# @CODE
# PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
# @CODE
# @ECLASS-VARIABLE: PYTHON_REQ_USE
# @DEFAULT_UNSET
@ -113,27 +127,23 @@ fi
# dev-lang/python:2.6[gdbm] )
# @CODE
_python_build_set_globals() {
_python_any_set_globals() {
local usestr i PYTHON_PKG_DEP
[[ ${PYTHON_REQ_USE} ]] && usestr="[${PYTHON_REQ_USE}]"
# check for invalid PYTHON_COMPAT
for i in "${PYTHON_COMPAT[@]}"; do
# the function simply dies on invalid impl
_python_impl_supported "${i}"
done
_python_set_impls
PYTHON_DEPS=
for i in "${_PYTHON_ALL_IMPLS[@]}"; do
has "${i}" "${PYTHON_COMPAT[@]}" || continue
for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
python_export "${i}" PYTHON_PKG_DEP
PYTHON_DEPS="${PYTHON_PKG_DEP} ${PYTHON_DEPS}"
done
PYTHON_DEPS="|| ( ${PYTHON_DEPS})"
readonly PYTHON_DEPS
}
_python_build_set_globals
_python_any_set_globals
unset -f _python_any_set_globals
# @ECLASS-VARIABLE: PYTHON_USEDEP
# @DESCRIPTION:
@ -191,10 +201,10 @@ _python_build_set_globals
# dev-python/baz[python_targets_python2_7(-)?,python_single_target_python2_7(+)?] )
# )
# (
# dev-lang/python:2.6
# dev-python/foo[python_targets_python2_6(-)?,python_single_target_python2_6(+)?]
# || ( dev-python/bar[python_targets_python2_6(-)?,python_single_target_python2_6(+)?]
# dev-python/baz[python_targets_python2_6(-)?,python_single_target_python2_6(+)?] )
# dev-lang/python:3.3
# dev-python/foo[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
# || ( dev-python/bar[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
# dev-python/baz[python_targets_python3_3(-)?,python_single_target_python3_3(+)?] )
# )
# )
# @CODE
@ -205,9 +215,7 @@ python_gen_any_dep() {
[[ ${depstr} ]] || die "No dependency string provided"
local PYTHON_PKG_DEP out=
for i in "${_PYTHON_ALL_IMPLS[@]}"; do
has "${i}" "${PYTHON_COMPAT[@]}" || continue
for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
python_export "${i}" PYTHON_PKG_DEP
@ -238,7 +246,7 @@ _python_EPYTHON_supported() {
;;
esac
if has "${i}" "${PYTHON_COMPAT[@]}"; then
if has "${i}" "${_PYTHON_SUPPORTED_IMPLS[@]}"; then
if python_is_installed "${i}"; then
if declare -f python_check_deps >/dev/null; then
local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
@ -263,6 +271,23 @@ _python_EPYTHON_supported() {
python_setup() {
debug-print-function ${FUNCNAME} "${@}"
# support developer override
if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
local impls=( ${PYTHON_COMPAT_OVERRIDE} )
[[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-any-r1"
ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
ewarn "implementation will be used:"
ewarn
ewarn " ${PYTHON_COMPAT_OVERRIDE}"
ewarn
ewarn "Dependencies won't be satisfied, and EPYTHON/eselect-python will be ignored."
python_export "${impls[0]}" EPYTHON PYTHON
python_wrapper_setup
return
fi
# first, try ${EPYTHON}... maybe it's good enough for us.
if [[ ${EPYTHON} ]]; then
if _python_EPYTHON_supported "${EPYTHON}"; then
@ -288,15 +313,9 @@ python_setup() {
done
# fallback to best installed impl.
local rev_impls=()
for i in "${_PYTHON_ALL_IMPLS[@]}"; do
if has "${i}" "${PYTHON_COMPAT[@]}"; then
rev_impls=( "${i}" "${rev_impls[@]}" )
fi
done
for i in "${rev_impls[@]}"; do
python_export "${i}" EPYTHON PYTHON
# (reverse iteration over _PYTHON_SUPPORTED_IMPLS)
for (( i = ${#_PYTHON_SUPPORTED_IMPLS[@]} - 1; i >= 0; i-- )); do
python_export "${_PYTHON_SUPPORTED_IMPLS[i]}" EPYTHON PYTHON
if _python_EPYTHON_supported "${EPYTHON}"; then
python_wrapper_setup
return

View File

@ -1,8 +1,8 @@
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/python-r1.eclass,v 1.90 2015/03/21 14:55:33 mgorny Exp $
# $Id$
# @ECLASS: python-r1
# @ECLASS: python-r1.eclass
# @MAINTAINER:
# Python team <python@gentoo.org>
# @AUTHOR:
@ -26,8 +26,8 @@
# in the packages using python-r1, and there is no need ever to inherit
# both.
#
# For more information, please see the python-r1 Developer's Guide:
# http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml
# For more information, please see the wiki:
# https://wiki.gentoo.org/wiki/Project:Python/python-r1
case "${EAPI:-0}" in
0|1|2|3)
@ -47,7 +47,7 @@ case "${EAPI:-0}" in
die "Unsupported EAPI=${EAPI:-4} (too old, allowed only on restricted set of packages) for ${ECLASS}"
fi
;;
5)
5|6)
# EAPI=5 is required for sane USE_EXPAND dependencies
;;
*)
@ -63,6 +63,7 @@ elif [[ ${_PYTHON_ANY_R1} ]]; then
die 'python-r1.eclass can not be used with python-any-r1.eclass.'
fi
[[ ${EAPI} == [45] ]] && inherit eutils
inherit multibuild python-utils-r1
# @ECLASS-VARIABLE: PYTHON_COMPAT
@ -74,16 +75,13 @@ inherit multibuild python-utils-r1
#
# Example:
# @CODE
# PYTHON_COMPAT=( python2_5 python2_6 python2_7 )
# PYTHON_COMPAT=( python2_7 python3_3 python3_4} )
# @CODE
#
# Please note that you can also use bash brace expansion if you like:
# @CODE
# PYTHON_COMPAT=( python{2_5,2_6,2_7} )
# PYTHON_COMPAT=( python2_7 python3_{3,4} )
# @CODE
if ! declare -p PYTHON_COMPAT &>/dev/null; then
die 'PYTHON_COMPAT not declared.'
fi
# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
# @INTERNAL
@ -139,8 +137,8 @@ fi
# Example value:
# @CODE
# dev-lang/python-exec:=
# python_targets_python2_6? ( dev-lang/python:2.6[gdbm] )
# python_targets_python2_7? ( dev-lang/python:2.7[gdbm] )
# python_targets_pypy? ( virtual/pypy[gdbm] )
# @CODE
# @ECLASS-VARIABLE: PYTHON_USEDEP
@ -160,7 +158,7 @@ fi
#
# Example value:
# @CODE
# python_targets_python2_6(-)?,python_targets_python2_7(-)?
# python_targets_python2_7(-)?,python_targets_python3_4(-)?
# @CODE
# @ECLASS-VARIABLE: PYTHON_REQUIRED_USE
@ -178,28 +176,21 @@ fi
#
# Example value:
# @CODE
# || ( python_targets_python2_6 python_targets_python2_7 )
# || ( python_targets_python2_7 python_targets_python3_4 )
# @CODE
_python_set_globals() {
local impls=()
PYTHON_DEPS=
local i PYTHON_PKG_DEP
for i in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${i}" || continue
_python_set_impls
for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
python_export "${i}" PYTHON_PKG_DEP
PYTHON_DEPS+="python_targets_${i}? ( ${PYTHON_PKG_DEP} ) "
impls+=( "${i}" )
done
if [[ ${#impls[@]} -eq 0 ]]; then
die "No supported implementation in PYTHON_COMPAT."
fi
local flags=( "${impls[@]/#/python_targets_}" )
local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" )
local optflags=${flags[@]/%/(-)?}
# A nice QA trick here. Since a python-single-r1 package has to have
@ -208,7 +199,7 @@ _python_set_globals() {
# it should prevent developers from mistakenly depending on packages
# not supporting multiple Python implementations.
local flags_st=( "${impls[@]/#/-python_single_target_}" )
local flags_st=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/-python_single_target_}" )
optflags+=,${flags_st[@]/%/(-)}
IUSE=${flags[*]}
@ -228,8 +219,10 @@ _python_set_globals() {
else
PYTHON_DEPS+="dev-lang/python-exec:2[${PYTHON_USEDEP}]"
fi
readonly PYTHON_DEPS PYTHON_REQUIRED_USE PYTHON_USEDEP
}
_python_set_globals
unset -f _python_set_globals
# @FUNCTION: _python_validate_useflags
# @INTERNAL
@ -240,9 +233,7 @@ _python_validate_useflags() {
local i
for i in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${i}" || continue
for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
use "python_targets_${i}" && return 0
done
@ -284,9 +275,7 @@ python_gen_usedep() {
local impl pattern
local matches=()
for impl in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${impl}" || continue
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
for pattern; do
if [[ ${impl} == ${pattern} ]]; then
matches+=(
@ -327,9 +316,7 @@ python_gen_useflags() {
local impl pattern
local matches=()
for impl in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${impl}" || continue
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
for pattern; do
if [[ ${impl} == ${pattern} ]]; then
matches+=( "python_targets_${impl}" )
@ -355,17 +342,17 @@ python_gen_useflags() {
#
# Example:
# @CODE
# PYTHON_COMPAT=( python{2_5,2_6,2_7} )
# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
# RDEPEND="$(python_gen_cond_dep \
# 'dev-python/unittest2[${PYTHON_USEDEP}]' python{2_5,2_6})"
# 'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )"
# @CODE
#
# It will cause the variable to look like:
# @CODE
# RDEPEND="python_targets_python2_5? (
# dev-python/unittest2[python_targets_python2_5?] )
# python_targets_python2_6? (
# dev-python/unittest2[python_targets_python2_6?] )"
# RDEPEND="python_targets_python2_7? (
# dev-python/unittest2[python_targets_python2_7?] )
# python_targets_pypy? (
# dev-python/unittest2[python_targets_pypy?] )"
# @CODE
python_gen_cond_dep() {
debug-print-function ${FUNCNAME} "${@}"
@ -376,17 +363,15 @@ python_gen_cond_dep() {
local dep=${1}
shift
for impl in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${impl}" || continue
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
for pattern; do
if [[ ${impl} == ${pattern} ]]; then
# substitute ${PYTHON_USEDEP} if used
# (since python_gen_usedep() will not return ${PYTHON_USEDEP}
# the code is run at most once)
if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then
local PYTHON_USEDEP=$(python_gen_usedep "${@}")
dep=${dep//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
local usedep=$(python_gen_usedep "${@}")
dep=${dep//\$\{PYTHON_USEDEP\}/${usedep}}
fi
matches+=( "python_targets_${impl}? ( ${dep} )" )
@ -398,6 +383,58 @@ python_gen_cond_dep() {
echo "${matches[@]}"
}
# @FUNCTION: python_gen_impl_dep
# @USAGE: [<requested-use-flags> [<impl-pattern>...]]
# @DESCRIPTION:
# Output a dependency on Python implementations with the specified USE
# dependency string appended, or no USE dependency string if called
# without the argument (or with empty argument). If any implementation
# patterns are passed, the output dependencies will be generated only
# for the implementations matching them.
#
# Use this function when you need to request different USE flags
# on the Python interpreter depending on package's USE flags. If you
# only need a single set of interpreter USE flags, just set
# PYTHON_REQ_USE and use ${PYTHON_DEPS} globally.
#
# Example:
# @CODE
# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
# RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )"
# @CODE
#
# It will cause the variable to look like:
# @CODE
# RDEPEND="foo? (
# python_targets_python2_7? (
# dev-lang/python:2.7[xml(+)] )
# python_targets_pypy? (
# dev-python/pypy[xml(+)] ) )"
# @CODE
python_gen_impl_dep() {
debug-print-function ${FUNCNAME} "${@}"
local impl pattern
local matches=()
local PYTHON_REQ_USE=${1}
shift
local patterns=( "${@-*}" )
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
for pattern in "${patterns[@]}"; do
if [[ ${impl} == ${pattern} ]]; then
local PYTHON_PKG_DEP
python_export "${impl}" PYTHON_PKG_DEP
matches+=( "python_targets_${impl}? ( ${PYTHON_PKG_DEP} )" )
break
fi
done
done
echo "${matches[@]}"
}
# @ECLASS-VARIABLE: BUILD_DIR
# @DESCRIPTION:
# The current build directory. In global scope, it is supposed to
@ -410,7 +447,7 @@ python_gen_cond_dep() {
#
# Example value:
# @CODE
# ${WORKDIR}/foo-1.3-python2_6
# ${WORKDIR}/foo-1.3-python2_7
# @CODE
# @FUNCTION: python_copy_sources
@ -430,220 +467,6 @@ python_copy_sources() {
multibuild_copy_sources
}
# @FUNCTION: _python_check_USE_PYTHON
# @INTERNAL
# @DESCRIPTION:
# Check whether USE_PYTHON and PYTHON_TARGETS are in sync. Output
# warnings if they are not.
_python_check_USE_PYTHON() {
debug-print-function ${FUNCNAME} "${@}"
if [[ ! ${_PYTHON_USE_PYTHON_CHECKED} ]]; then
_PYTHON_USE_PYTHON_CHECKED=1
# python-exec has profile-forced flags.
if [[ ${CATEGORY}/${PN} == dev-lang/python-exec ]]; then
return
fi
_try_eselect() {
# The eselect solution will work only with one py2 & py3.
local impl py2 py3 dis_py2 dis_py3
for impl in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${impl}" || continue
if use "python_targets_${impl}"; then
case "${impl}" in
python2_*)
if [[ ${py2+1} ]]; then
debug-print "${FUNCNAME}: -> more than one py2: ${py2} ${impl}"
return 1
fi
py2=${impl/_/.}
;;
python3_4)
debug-print "${FUNCNAME}: python3.4 found, not using eselect"
return 1
;;
python3_*)
if [[ ${py3+1} ]]; then
debug-print "${FUNCNAME}: -> more than one py3: ${py3} ${impl}"
return 1
fi
py3=${impl/_/.}
;;
*)
return 1
;;
esac
else
case "${impl}" in
python2_*)
dis_py2=1
;;
python3_*)
dis_py3=1
;;
esac
fi
done
# The eselect solution won't work if the disabled Python version
# is installed.
if [[ ! ${py2+1} && ${dis_py2} ]]; then
debug-print "${FUNCNAME}: -> all py2 versions disabled"
if ! has python2_7 "${PYTHON_COMPAT[@]}"; then
debug-print "${FUNCNAME}: ---> package does not support 2.7"
return 0
fi
if has_version '=dev-lang/python-2*'; then
debug-print "${FUNCNAME}: ---> but =python-2* installed!"
return 1
fi
fi
if [[ ! ${py3+1} && ${dis_py3} ]]; then
debug-print "${FUNCNAME}: -> all py3 versions disabled"
if ! has python3_2 "${PYTHON_COMPAT[@]}"; then
debug-print "${FUNCNAME}: ---> package does not support 3.2"
return 0
fi
if has_version '=dev-lang/python-3*'; then
debug-print "${FUNCNAME}: ---> but =python-3* installed!"
return 1
fi
fi
local warned
# Now check whether the correct implementations are active.
if [[ ${py2+1} ]]; then
local sel_py2=$(eselect python show --python2)
debug-print "${FUNCNAME}: -> py2 built: ${py2}, active: ${sel_py2}"
if [[ ${py2} != ${sel_py2} ]]; then
ewarn "Building package for ${py2} only while ${sel_py2} is active."
ewarn "Please consider switching the active Python 2 interpreter:"
ewarn
ewarn " eselect python set --python2 ${py2}"
warned=1
fi
fi
if [[ ${py3+1} ]]; then
local sel_py3=$(eselect python show --python3)
debug-print "${FUNCNAME}: -> py3 built: ${py3}, active: ${sel_py3}"
if [[ ${py3} != ${sel_py3} ]]; then
[[ ${warned} ]] && ewarn
ewarn "Building package for ${py3} only while ${sel_py3} is active."
ewarn "Please consider switching the active Python 3 interpreter:"
ewarn
ewarn " eselect python set --python3 ${py3}"
warned=1
fi
fi
if [[ ${warned} ]]; then
ewarn
ewarn "Please note that after switching the active Python interpreter,"
ewarn "you may need to run 'python-updater' to rebuild affected packages."
ewarn
ewarn "For more information on PYTHON_TARGETS and python.eclass"
ewarn "compatibility, please see the relevant Wiki article [1]."
ewarn
ewarn "[1] https://wiki.gentoo.org/wiki/Project:Python/PYTHON_TARGETS"
fi
}
# If user has no USE_PYTHON, try to avoid it.
if [[ ! ${USE_PYTHON} ]]; then
debug-print "${FUNCNAME}: trying eselect solution ..."
_try_eselect && return
fi
debug-print "${FUNCNAME}: trying USE_PYTHON solution ..."
debug-print "${FUNCNAME}: -> USE_PYTHON=${USE_PYTHON}"
local impl old=${USE_PYTHON} new=() removed=()
for impl in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${impl}" || continue
local abi
case "${impl}" in
pypy|pypy3|python3_4)
# unsupported in python.eclass
continue
;;
python*)
abi=${impl#python}
;;
jython*)
abi=${impl#jython}-jython
;;
*)
die "Unexpected Python implementation: ${impl}"
;;
esac
abi=${abi/_/.}
has "${abi}" ${USE_PYTHON}
local has_abi=${?}
use "python_targets_${impl}"
local has_impl=${?}
# 0 = has, 1 = does not have
if [[ ${has_abi} == 0 && ${has_impl} == 1 ]]; then
debug-print "${FUNCNAME}: ---> remove ${abi}"
# remove from USE_PYTHON
old=${old/${abi}/}
removed+=( ${abi} )
elif [[ ${has_abi} == 1 && ${has_impl} == 0 ]]; then
debug-print "${FUNCNAME}: ---> add ${abi}"
# add to USE_PYTHON
new+=( ${abi} )
fi
done
if [[ ${removed[@]} || ${new[@]} ]]; then
old=( ${old} )
debug-print "${FUNCNAME}: -> old: ${old[@]}"
debug-print "${FUNCNAME}: -> new: ${new[@]}"
debug-print "${FUNCNAME}: -> removed: ${removed[@]}"
if [[ ${USE_PYTHON} ]]; then
ewarn "It seems that your USE_PYTHON setting lists different Python"
ewarn "implementations than your PYTHON_TARGETS variable. Please consider"
ewarn "using the following value instead:"
ewarn
ewarn " USE_PYTHON='\033[35m${old[@]}${new[@]+ \033[1m${new[@]}}\033[0m'"
if [[ ${removed[@]} ]]; then
ewarn
ewarn "(removed \033[31m${removed[@]}\033[0m)"
fi
else
ewarn "It seems that you need to set USE_PYTHON to make sure that legacy"
ewarn "packages will be built with respect to PYTHON_TARGETS correctly:"
ewarn
ewarn " USE_PYTHON='\033[35;1m${new[@]}\033[0m'"
fi
ewarn
ewarn "Please note that after changing the USE_PYTHON variable, you may need"
ewarn "to run 'python-updater' to rebuild affected packages."
ewarn
ewarn "For more information on PYTHON_TARGETS and python.eclass"
ewarn "compatibility, please see the relevant Wiki article [1]."
ewarn
ewarn "[1] https://wiki.gentoo.org/wiki/Project:Python/PYTHON_TARGETS"
fi
fi
}
# @FUNCTION: _python_obtain_impls
# @INTERNAL
# @DESCRIPTION:
@ -665,16 +488,12 @@ _python_obtain_impls() {
fi
_python_validate_useflags
_python_check_USE_PYTHON
MULTIBUILD_VARIANTS=()
for impl in "${_PYTHON_ALL_IMPLS[@]}"; do
if has "${impl}" "${PYTHON_COMPAT[@]}" \
&& use "python_targets_${impl}"
then
MULTIBUILD_VARIANTS+=( "${impl}" )
fi
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
has "${impl}" "${PYTHON_COMPAT[@]}" && \
use "python_targets_${impl}" && MULTIBUILD_VARIANTS+=( "${impl}" )
done
}
@ -738,6 +557,8 @@ python_foreach_impl() {
python_parallel_foreach_impl() {
debug-print-function ${FUNCNAME} "${@}"
[[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI ${EAPI}"
if [[ ! ${_PYTHON_PARALLEL_WARNED} ]]; then
eqawarn "python_parallel_foreach_impl() is no longer meaningful. All runs"
eqawarn "are non-parallel now. Please replace the call with python_foreach_impl."
@ -790,6 +611,7 @@ python_setup() {
done
}
python_foreach_impl _python_try_impl
unset -f _python_try_impl
if [[ ! ${best_impl} ]]; then
eerror "${FUNCNAME}: none of the enabled implementation matched the patterns."
@ -813,6 +635,8 @@ python_setup() {
python_export_best() {
debug-print-function ${FUNCNAME} "${@}"
[[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI ${EAPI}"
eqawarn "python_export_best() is deprecated. Please use python_setup instead,"
eqawarn "combined with python_export if necessary."
@ -825,6 +649,7 @@ python_export_best() {
best=${MULTIBUILD_VARIANT}
}
multibuild_for_best_variant _python_set_best
unset -f _python_set_best
debug-print "${FUNCNAME}: Best implementation is: ${best}"
python_export "${best}" "${@}"
@ -859,6 +684,7 @@ python_replicate_script() {
local files=( "${@}" )
python_foreach_impl _python_replicate_script
unset -f _python_replicate_script
# install the wrappers
local f

View File

@ -1,8 +1,8 @@
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/python-single-r1.eclass,v 1.38 2015/03/22 13:41:16 mgorny Exp $
# $Id$
# @ECLASS: python-single-r1
# @ECLASS: python-single-r1.eclass
# @MAINTAINER:
# Python team <python@gentoo.org>
# @AUTHOR:
@ -28,8 +28,8 @@
# in the packages using python-single-r1, and there is no need ever
# to inherit both.
#
# For more information, please see the python-r1 Developer's Guide:
# http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml
# For more information, please see the wiki:
# https://wiki.gentoo.org/wiki/Project:Python/python-single-r1
case "${EAPI:-0}" in
0|1|2|3)
@ -55,7 +55,7 @@ case "${EAPI:-0}" in
die "Unsupported EAPI=${EAPI:-4} (too old, allowed only on restricted set of packages) for ${ECLASS}"
fi
;;
5)
5|6)
# EAPI=5 is required for sane USE_EXPAND dependencies
;;
*)
@ -88,11 +88,32 @@ if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
#
# Example:
# @CODE
# PYTHON_COMPAT=( python{2_5,2_6,2_7} )
# PYTHON_COMPAT=( python2_7 python3_3 python3_4} )
# @CODE
#
# Please note that you can also use bash brace expansion if you like:
# @CODE
# PYTHON_COMPAT=( python2_7 python3_{3,4} )
# @CODE
# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
# @INTERNAL
# @DESCRIPTION:
# This variable can be used when working with ebuilds to override
# the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
# which package will be built for. It needs to be specified
# in the calling environment, and not in ebuilds.
#
# It should be noted that in order to preserve metadata immutability,
# PYTHON_COMPAT_OVERRIDE does not affect IUSE nor dependencies.
# The state of PYTHON_TARGETS and PYTHON_SINGLE_TARGET is ignored,
# and the implementation in PYTHON_COMPAT_OVERRIDE is built instead.
# Dependencies need to be satisfied manually.
#
# Example:
# @CODE
# PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
# @CODE
if ! declare -p PYTHON_COMPAT &>/dev/null; then
die 'PYTHON_COMPAT not declared.'
fi
# @ECLASS-VARIABLE: PYTHON_REQ_USE
# @DEFAULT_UNSET
@ -131,8 +152,8 @@ fi
# Example value:
# @CODE
# dev-lang/python-exec:=
# python_single_target_python2_6? ( dev-lang/python:2.6[gdbm] )
# python_single_target_python2_7? ( dev-lang/python:2.7[gdbm] )
# python_single_target_pypy? ( virtual/pypy[gdbm] )
# @CODE
# @ECLASS-VARIABLE: PYTHON_USEDEP
@ -152,7 +173,7 @@ fi
#
# Example value:
# @CODE
# python_targets_python2_7(-)?,python_single_target_python2_7(+)?
# python_targets_python2_7(-)?,python_single_target_python3_4(+)?
# @CODE
# @ECLASS-VARIABLE: PYTHON_REQUIRED_USE
@ -172,40 +193,30 @@ fi
#
# Example value:
# @CODE
# python_single_target_python2_6? ( python_targets_python2_6 )
# python_single_target_python2_7? ( python_targets_python2_7 )
# ^^ ( python_single_target_python2_6 python_single_target_python2_7 )
# python_single_target_python3_3? ( python_targets_python3_3 )
# ^^ ( python_single_target_python2_7 python_single_target_python3_3 )
# @CODE
_python_single_set_globals() {
local impls=()
local unimpls=()
_python_set_impls
PYTHON_DEPS=
local i PYTHON_PKG_DEP
for i in "${_PYTHON_ALL_IMPLS[@]}"; do
has "${i}" "${PYTHON_COMPAT[@]}" \
&& impls+=( "${i}" ) \
|| unimpls+=( "${i}" )
done
if [[ ${#impls[@]} -eq 0 ]]; then
die "No supported implementation in PYTHON_COMPAT."
fi
local flags_mt=( "${impls[@]/#/python_targets_}" )
local flags=( "${impls[@]/#/python_single_target_}" )
local unflags=( "${unimpls[@]/#/-python_single_target_}" )
local flags_mt=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" )
local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_single_target_}" )
local unflags=( "${_PYTHON_UNSUPPORTED_IMPLS[@]/#/-python_single_target_}" )
local optflags=${flags_mt[@]/%/(-)?},${unflags[@]/%/(-)}
IUSE="${flags_mt[*]}"
if [[ ${#impls[@]} -eq 1 ]]; then
if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
# There is only one supported implementation; set IUSE and other
# variables without PYTHON_SINGLE_TARGET.
PYTHON_REQUIRED_USE="${flags_mt[*]}"
python_export "${impls[0]}" PYTHON_PKG_DEP
python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" PYTHON_PKG_DEP
PYTHON_DEPS="${PYTHON_PKG_DEP} "
# Force on the python_single_target_* flag for this impl, so
# that any dependencies that inherit python-single-r1 and
@ -220,7 +231,7 @@ _python_single_set_globals() {
# on this package.
optflags+=,${flags[@]/%/(+)?}
for i in "${impls[@]}"; do
for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
# The chosen targets need to be in PYTHON_TARGETS as well.
# This is in order to enforce correct dependencies on packages
# supporting multiple implementations.
@ -245,8 +256,10 @@ _python_single_set_globals() {
else
PYTHON_DEPS+="dev-lang/python-exec:2[${PYTHON_USEDEP}]"
fi
readonly PYTHON_DEPS PYTHON_REQUIRED_USE PYTHON_USEDEP
}
_python_single_set_globals
unset -f _python_single_set_globals
# @FUNCTION: python_gen_usedep
# @USAGE: <pattern> [...]
@ -278,9 +291,7 @@ python_gen_usedep() {
local impl pattern
local matches=()
for impl in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${impl}" || continue
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
for pattern; do
if [[ ${impl} == ${pattern} ]]; then
matches+=(
@ -318,15 +329,19 @@ python_gen_usedep() {
python_gen_useflags() {
debug-print-function ${FUNCNAME} "${@}"
local impl pattern
local flag_prefix impl pattern
local matches=()
for impl in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${impl}" || continue
if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
flag_prefix=python_targets
else
flag_prefix=python_single_target
fi
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
for pattern; do
if [[ ${impl} == ${pattern} ]]; then
matches+=( "python_single_target_${impl}" )
matches+=( "${flag_prefix}_${impl}" )
break
fi
done
@ -349,41 +364,103 @@ python_gen_useflags() {
#
# Example:
# @CODE
# PYTHON_COMPAT=( python{2_5,2_6,2_7} )
# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
# RDEPEND="$(python_gen_cond_dep \
# 'dev-python/unittest2[${PYTHON_USEDEP}]' python{2_5,2_6})"
# 'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )"
# @CODE
#
# It will cause the variable to look like:
# @CODE
# RDEPEND="python_single_target_python2_5? (
# dev-python/unittest2[python_targets_python2_5(-)?,...] )
# python_single_target_python2_6? (
# dev-python/unittest2[python_targets_python2_6(-)?,...] )"
# RDEPEND="python_single_target_python2_7? (
# dev-python/unittest2[python_targets_python2_7(-)?,...] )
# python_single_target_pypy? (
# dev-python/unittest2[python_targets_pypy(-)?,...] )"
# @CODE
python_gen_cond_dep() {
debug-print-function ${FUNCNAME} "${@}"
local impl pattern
local flag_prefix impl pattern
local matches=()
if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
flag_prefix=python_targets
else
flag_prefix=python_single_target
fi
local dep=${1}
shift
for impl in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${impl}" || continue
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
for pattern; do
if [[ ${impl} == ${pattern} ]]; then
# substitute ${PYTHON_USEDEP} if used
# (since python_gen_usedep() will not return ${PYTHON_USEDEP}
# the code is run at most once)
if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then
local PYTHON_USEDEP=$(python_gen_usedep "${@}")
dep=${dep//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
local usedep=$(python_gen_usedep "${@}")
dep=${dep//\$\{PYTHON_USEDEP\}/${usedep}}
fi
matches+=( "python_single_target_${impl}? ( ${dep} )" )
matches+=( "${flag_prefix}_${impl}? ( ${dep} )" )
break
fi
done
done
echo "${matches[@]}"
}
# @FUNCTION: python_gen_impl_dep
# @USAGE: [<requested-use-flags> [<impl-pattern>...]]
# @DESCRIPTION:
# Output a dependency on Python implementations with the specified USE
# dependency string appended, or no USE dependency string if called
# without the argument (or with empty argument). If any implementation
# patterns are passed, the output dependencies will be generated only
# for the implementations matching them.
#
# Use this function when you need to request different USE flags
# on the Python interpreter depending on package's USE flags. If you
# only need a single set of interpreter USE flags, just set
# PYTHON_REQ_USE and use ${PYTHON_DEPS} globally.
#
# Example:
# @CODE
# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
# RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )"
# @CODE
#
# It will cause the variable to look like:
# @CODE
# RDEPEND="foo? (
# python_single_target_python2_7? (
# dev-lang/python:2.7[xml(+)] )
# python_single_target_pypy? (
# dev-python/pypy[xml(+)] ) )"
# @CODE
python_gen_impl_dep() {
debug-print-function ${FUNCNAME} "${@}"
local impl pattern
local matches=()
if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
flag_prefix=python_targets
else
flag_prefix=python_single_target
fi
local PYTHON_REQ_USE=${1}
shift
local patterns=( "${@-*}" )
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
for pattern in "${patterns[@]}"; do
if [[ ${impl} == ${pattern} ]]; then
local PYTHON_PKG_DEP
python_export "${impl}" PYTHON_PKG_DEP
matches+=( "${flag_prefix}_${impl}? ( ${PYTHON_PKG_DEP} )" )
break
fi
done
@ -401,20 +478,32 @@ python_setup() {
unset EPYTHON
local impl impls=()
for impl in "${PYTHON_COMPAT[@]}"; do
_python_impl_supported "${impl}" || continue
impls+=( "${impl}" )
done
# support developer override
if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
local impls=( ${PYTHON_COMPAT_OVERRIDE} )
[[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-single-r1"
if [[ ${#impls[@]} -eq 1 ]]; then
if use "python_targets_${impls[0]}"; then
ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
ewarn "implementation will be used:"
ewarn
ewarn " ${PYTHON_COMPAT_OVERRIDE}"
ewarn
ewarn "Dependencies won't be satisfied, and PYTHON_SINGLE_TARGET flags will be ignored."
python_export "${impls[0]}" EPYTHON PYTHON
python_wrapper_setup
return
fi
if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
if use "python_targets_${_PYTHON_SUPPORTED_IMPLS[0]}"; then
# Only one supported implementation, enable it explicitly
python_export "${impls[0]}" EPYTHON PYTHON
python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" EPYTHON PYTHON
python_wrapper_setup
fi
else
for impl in "${impls[@]}"; do
local impl
for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
if use "python_single_target_${impl}"; then
if [[ ${EPYTHON} ]]; then
eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python"
@ -442,14 +531,14 @@ python_setup() {
if [[ ! ${EPYTHON} ]]; then
eerror "No Python implementation selected for the build. Please set"
if [[ ${#impls[@]} -eq 1 ]]; then
if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
eerror "the PYTHON_TARGETS variable in your make.conf to include one"
else
eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one"
fi
eerror "of the following values:"
eerror
eerror "${impls[@]}"
eerror "${_PYTHON_SUPPORTED_IMPLS[@]}"
echo
die "No supported Python implementation in PYTHON_SINGLE_TARGET/PYTHON_TARGETS."
fi

View File

@ -1,8 +1,8 @@
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/python-utils-r1.eclass,v 1.82 2015/03/21 14:55:33 mgorny Exp $
# $Id$
# @ECLASS: python-utils-r1
# @ECLASS: python-utils-r1.eclass
# @MAINTAINER:
# Python team <python@gentoo.org>
# @AUTHOR:
@ -16,11 +16,11 @@
# This eclass does not set any metadata variables nor export any phase
# functions. It can be inherited safely.
#
# For more information, please see the python-r1 Developer's Guide:
# http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml
# For more information, please see the wiki:
# https://wiki.gentoo.org/wiki/Project:Python/python-utils-r1
case "${EAPI:-0}" in
0|1|2|3|4|5)
0|1|2|3|4|5|6)
;;
*)
die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
@ -33,18 +33,20 @@ fi
if [[ ! ${_PYTHON_UTILS_R1} ]]; then
inherit eutils multilib toolchain-funcs
[[ ${EAPI:-0} == [012345] ]] && inherit eutils multilib
inherit toolchain-funcs
# @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS
# @INTERNAL
# @DESCRIPTION:
# All supported Python implementations, most preferred last.
_PYTHON_ALL_IMPLS=(
jython2_5 jython2_7
pypy pypy3
python3_3 python3_4 python3_5
python2_7
python3_3 python3_4 python3_5
pypy pypy3
jython2_7
)
readonly _PYTHON_ALL_IMPLS
# @FUNCTION: _python_impl_supported
# @USAGE: <impl>
@ -66,7 +68,7 @@ _python_impl_supported() {
# keep in sync with _PYTHON_ALL_IMPLS!
# (not using that list because inline patterns shall be faster)
case "${impl}" in
python2_7|python3_[345]|jython2_[57])
python2_7|python3_[345]|jython2_7)
return 0
;;
pypy1_[89]|pypy2_0|python2_[56]|python3_[12])
@ -82,6 +84,55 @@ _python_impl_supported() {
esac
}
# @FUNCTION: _python_set_impls
# @INTERNAL
# @DESCRIPTION:
# Check PYTHON_COMPAT for well-formedness and validity, then set
# two global variables:
#
# - _PYTHON_SUPPORTED_IMPLS containing valid implementations supported
# by the ebuild (PYTHON_COMPAT - dead implementations),
#
# - and _PYTHON_UNSUPPORTED_IMPLS containing valid implementations that
# are not supported by the ebuild.
#
# Implementations in both variables are ordered using the pre-defined
# eclass implementation ordering.
#
# This function must be called once in global scope by an eclass
# utilizing PYTHON_COMPAT.
_python_set_impls() {
local i
if ! declare -p PYTHON_COMPAT &>/dev/null; then
die 'PYTHON_COMPAT not declared.'
fi
if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
die 'PYTHON_COMPAT must be an array.'
fi
for i in "${PYTHON_COMPAT[@]}"; do
# trigger validity checks
_python_impl_supported "${i}"
done
_PYTHON_SUPPORTED_IMPLS=()
_PYTHON_UNSUPPORTED_IMPLS=()
for i in "${_PYTHON_ALL_IMPLS[@]}"; do
if has "${i}" "${PYTHON_COMPAT[@]}"; then
_PYTHON_SUPPORTED_IMPLS+=( "${i}" )
else
_PYTHON_UNSUPPORTED_IMPLS+=( "${i}" )
fi
done
if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 0 ]]; then
die "No supported implementation in PYTHON_COMPAT."
fi
readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS
}
# @ECLASS-VARIABLE: PYTHON
# @DEFAULT_UNSET
# @DESCRIPTION:
@ -126,6 +177,7 @@ _python_impl_supported() {
# The path to Python site-packages directory.
#
# Set and exported on request using python_export().
# Requires a proper build-time dependency on the Python implementation.
#
# Example value:
# @CODE
@ -138,6 +190,7 @@ _python_impl_supported() {
# The path to Python include directory.
#
# Set and exported on request using python_export().
# Requires a proper build-time dependency on the Python implementation.
#
# Example value:
# @CODE
@ -150,7 +203,8 @@ _python_impl_supported() {
# The path to Python library.
#
# Set and exported on request using python_export().
# Valid only for CPython.
# Valid only for CPython. Requires a proper build-time dependency
# on the Python implementation.
#
# Example value:
# @CODE
@ -187,6 +241,20 @@ _python_impl_supported() {
# -lpython2.7
# @CODE
# @ECLASS-VARIABLE: PYTHON_CONFIG
# @DEFAULT_UNSET
# @DESCRIPTION:
# Path to the python-config executable.
#
# Set and exported on request using python_export().
# Valid only for CPython. Requires a proper build-time dependency
# on the Python implementation and on pkg-config.
#
# Example value:
# @CODE
# /usr/bin/python2.7-config
# @CODE
# @ECLASS-VARIABLE: PYTHON_PKG_DEP
# @DEFAULT_UNSET
# @DESCRIPTION:
@ -259,51 +327,34 @@ python_export() {
debug-print "${FUNCNAME}: PYTHON = ${PYTHON}"
;;
PYTHON_SITEDIR)
local dir
case "${impl}" in
python*|pypy|pypy3)
dir=/usr/$(get_libdir)/${impl}
;;
jython*)
dir=/usr/share/${impl/n/n-}/Lib
;;
esac
export PYTHON_SITEDIR=${EPREFIX}${dir}/site-packages
[[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
# sysconfig can't be used because:
# 1) pypy doesn't give site-packages but stdlib
# 2) jython gives paths with wrong case
PYTHON_SITEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())') || die
export PYTHON_SITEDIR
debug-print "${FUNCNAME}: PYTHON_SITEDIR = ${PYTHON_SITEDIR}"
;;
PYTHON_INCLUDEDIR)
local dir
case "${impl}" in
python*)
dir=/usr/include/${impl}
;;
pypy|pypy3)
dir=/usr/$(get_libdir)/${impl}/include
;;
*)
die "${impl} lacks header files"
;;
esac
export PYTHON_INCLUDEDIR=${EPREFIX}${dir}
[[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
PYTHON_INCLUDEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_inc())') || die
export PYTHON_INCLUDEDIR
debug-print "${FUNCNAME}: PYTHON_INCLUDEDIR = ${PYTHON_INCLUDEDIR}"
# Jython gives a non-existing directory
if [[ ! -d ${PYTHON_INCLUDEDIR} ]]; then
die "${impl} does not install any header files!"
fi
;;
PYTHON_LIBPATH)
local libname
case "${impl}" in
python*)
libname=lib${impl}
;;
*)
die "${impl} lacks a dynamic library"
;;
esac
local path=${EPREFIX}/usr/$(get_libdir)
export PYTHON_LIBPATH=${path}/${libname}$(get_libname)
[[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
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
export PYTHON_LIBPATH
debug-print "${FUNCNAME}: PYTHON_LIBPATH = ${PYTHON_LIBPATH}"
if [[ ! ${PYTHON_LIBPATH} ]]; then
die "${impl} lacks a (usable) dynamic library"
fi
;;
PYTHON_CFLAGS)
local val
@ -311,7 +362,7 @@ python_export() {
case "${impl}" in
python*)
# python-2.7, python-3.2, etc.
val=$($(tc-getPKG_CONFIG) --cflags ${impl/n/n-})
val=$($(tc-getPKG_CONFIG) --cflags ${impl/n/n-}) || die
;;
*)
die "${impl}: obtaining ${var} not supported"
@ -327,7 +378,7 @@ python_export() {
case "${impl}" in
python*)
# python-2.7, python-3.2, etc.
val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-})
val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-}) || die
;;
*)
die "${impl}: obtaining ${var} not supported"
@ -337,6 +388,23 @@ python_export() {
export PYTHON_LIBS=${val}
debug-print "${FUNCNAME}: PYTHON_LIBS = ${PYTHON_LIBS}"
;;
PYTHON_CONFIG)
local flags val
case "${impl}" in
python*)
[[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
flags=$("${PYTHON}" -c 'import sysconfig; print(sysconfig.get_config_var("ABIFLAGS") or "")') || die
val=${PYTHON}${flags}-config
;;
*)
die "${impl}: obtaining ${var} not supported"
;;
esac
export PYTHON_CONFIG=${val}
debug-print "${FUNCNAME}: PYTHON_CONFIG = ${PYTHON_CONFIG}"
;;
PYTHON_PKG_DEP)
local d
case ${impl} in
@ -350,8 +418,6 @@ python_export() {
PYTHON_PKG_DEP='virtual/pypy:0=';;
pypy3)
PYTHON_PKG_DEP='virtual/pypy3:0=';;
jython2.5)
PYTHON_PKG_DEP='>=dev-java/jython-2.5.3-r2:2.5';;
jython2.7)
PYTHON_PKG_DEP='dev-java/jython:2.7';;
*)
@ -457,6 +523,23 @@ python_get_LIBS() {
echo "${PYTHON_LIBS}"
}
# @FUNCTION: python_get_PYTHON_CONFIG
# @USAGE: [<impl>]
# @DESCRIPTION:
# Obtain and print the PYTHON_CONFIG location for the given
# implementation. If no implementation is provided, ${EPYTHON} will be
# used.
#
# Please note that this function can be used with CPython only.
# It requires Python installed, and therefore proper build-time
# dependencies need be added to the ebuild.
python_get_PYTHON_CONFIG() {
debug-print-function ${FUNCNAME} "${@}"
python_export "${@}" PYTHON_CONFIG
echo "${PYTHON_CONFIG}"
}
# @FUNCTION: python_get_scriptdir
# @USAGE: [<impl>]
# @DESCRIPTION:
@ -533,9 +616,6 @@ python_optimize() {
local PYTHON=${PYTHON}
[[ ${PYTHON} ]] || python_export PYTHON
# Note: python2.6 can't handle passing files to compileall...
# TODO: we do not support 2.6 any longer
# default to sys.path
if [[ ${#} -eq 0 ]]; then
local f
@ -548,7 +628,7 @@ python_optimize() {
if [[ ${f} == /* && -d ${D}${f} ]]; then
set -- "${D}${f}" "${@}"
fi
done < <("${PYTHON}" -c 'import sys; print("\0".join(sys.path))')
done < <("${PYTHON}" -c 'import sys; print("\0".join(sys.path))' || die)
debug-print "${FUNCNAME}: using sys.path: ${*/%/;}"
fi
@ -634,6 +714,9 @@ python_newexe() {
[[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
[[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} <path> <new-name>"
if [[ ${EAPI:-0} == [0123] ]]; then
die "python_do* and python_new* helpers are banned in EAPIs older than 4."
fi
local wrapd=${python_scriptroot:-${DESTTREE}/bin}
@ -647,7 +730,7 @@ python_newexe() {
(
dodir "${wrapd}"
exeinto "${d}"
newexe "${f}" "${newfn}" || die
newexe "${f}" "${newfn}" || return ${?}
)
# install the wrapper
@ -761,6 +844,9 @@ python_domodule() {
debug-print-function ${FUNCNAME} "${@}"
[[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
if [[ ${EAPI:-0} == [0123] ]]; then
die "python_do* and python_new* helpers are banned in EAPIs older than 4."
fi
local d
if [[ ${python_moduleroot} == /* ]]; then
@ -774,10 +860,10 @@ python_domodule() {
d=${PYTHON_SITEDIR#${EPREFIX}}/${python_moduleroot}
fi
local INSDESTTREE
insinto "${d}"
doins -r "${@}" || die
(
insinto "${d}"
doins -r "${@}" || return ${?}
)
python_optimize "${ED}/${d}"
}
@ -799,16 +885,19 @@ python_doheader() {
debug-print-function ${FUNCNAME} "${@}"
[[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
if [[ ${EAPI:-0} == [0123] ]]; then
die "python_do* and python_new* helpers are banned in EAPIs older than 4."
fi
local d PYTHON_INCLUDEDIR=${PYTHON_INCLUDEDIR}
[[ ${PYTHON_INCLUDEDIR} ]] || python_export PYTHON_INCLUDEDIR
d=${PYTHON_INCLUDEDIR#${EPREFIX}}
local INSDESTTREE
insinto "${d}"
doins -r "${@}" || die
(
insinto "${d}"
doins -r "${@}" || return ${?}
)
}
# @FUNCTION: python_wrapper_setup
@ -840,29 +929,47 @@ python_wrapper_setup() {
mkdir -p "${workdir}"/{bin,pkgconfig} || die
# Clean up, in case we were supposed to do a cheap update.
rm -f "${workdir}"/bin/python{,2,3,-config}
rm -f "${workdir}"/bin/2to3
rm -f "${workdir}"/pkgconfig/python{,2,3}.pc
rm -f "${workdir}"/bin/python{,2,3,-config} || die
rm -f "${workdir}"/bin/2to3 || die
rm -f "${workdir}"/pkgconfig/python{,2,3}.pc || die
local EPYTHON PYTHON
local EPYTHON PYTHON PYTHON_CONFIG
python_export "${impl}" EPYTHON PYTHON
local pyver
local pyver pyother
if python_is_python3; then
pyver=3
pyother=2
else
pyver=2
pyother=3
fi
# Python interpreter
ln -s "${PYTHON}" "${workdir}"/bin/python || die
ln -s python "${workdir}"/bin/python${pyver} || die
# note: we don't use symlinks because python likes to do some
# symlink reading magic that breaks stuff
# https://bugs.gentoo.org/show_bug.cgi?id=555752
cat > "${workdir}/bin/python" <<-_EOF_ || die
#!/bin/sh
exec "${PYTHON}" "\${@}"
_EOF_
cp "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
chmod +x "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
local nonsupp=()
local nonsupp=( "python${pyother}" "python${pyother}-config" )
# CPython-specific
if [[ ${EPYTHON} == python* ]]; then
ln -s "${PYTHON}-config" "${workdir}"/bin/python-config || die
python_export "${impl}" PYTHON_CONFIG
cat > "${workdir}/bin/python-config" <<-_EOF_ || die
#!/bin/sh
exec "${PYTHON_CONFIG}" "\${@}"
_EOF_
cp "${workdir}/bin/python-config" \
"${workdir}/bin/python${pyver}-config" || die
chmod +x "${workdir}/bin/python-config" \
"${workdir}/bin/python${pyver}-config" || die
# Python 2.6+.
ln -s "${PYTHON/python/2to3-}" "${workdir}"/bin/2to3 || die
@ -872,16 +979,16 @@ python_wrapper_setup() {
"${workdir}"/pkgconfig/python.pc || die
ln -s python.pc "${workdir}"/pkgconfig/python${pyver}.pc || die
else
nonsupp+=( 2to3 python-config )
nonsupp+=( 2to3 python-config "python${pyver}-config" )
fi
local x
for x in "${nonsupp[@]}"; do
cat >"${workdir}"/bin/${x} <<__EOF__
#!/bin/sh
echo "${x} is not supported by ${EPYTHON}" >&2
exit 1
__EOF__
cat >"${workdir}"/bin/${x} <<-_EOF_ || die
#!/bin/sh
echo "${x} is not supported by ${EPYTHON}" >&2
exit 127
_EOF_
chmod +x "${workdir}"/bin/${x} || die
done
@ -989,12 +1096,14 @@ python_fix_shebang() {
local shebang i
local error= from=
IFS= read -r shebang <${f}
# note: we can't ||die here since read will fail if file
# has no newline characters
IFS= read -r shebang <"${f}"
# First, check if it's shebang at all...
if [[ ${shebang} == '#!'* ]]; then
local split_shebang=()
read -r -a split_shebang <<<${shebang}
read -r -a split_shebang <<<${shebang} || die
# Match left-to-right in a loop, to avoid matching random
# repetitions like 'python2.7 python2'.
@ -1079,19 +1188,42 @@ python_fix_shebang() {
eerror " requested impl: ${EPYTHON}"
die "${FUNCNAME}: conversion of incompatible shebang requested"
fi
done < <(find "${path}" -type f -print0)
done < <(find -H "${path}" -type f -print0 || die)
if [[ ! ${any_fixed} ]]; then
eqawarn "QA warning: ${FUNCNAME}, ${path#${D}} did not match any fixable files."
local cmd=eerror
[[ ${EAPI:-0} == [012345] ]] && cmd=eqawarn
"${cmd}" "QA warning: ${FUNCNAME}, ${path#${D}} did not match any fixable files."
if [[ ${any_correct} ]]; then
eqawarn "All files have ${EPYTHON} shebang already."
"${cmd}" "All files have ${EPYTHON} shebang already."
else
eqawarn "There are no Python files in specified directory."
"${cmd}" "There are no Python files in specified directory."
fi
[[ ${cmd} == eerror ]] && die "${FUNCNAME} did not match any fixable files (QA warning fatal in EAPI ${EAPI})"
fi
done
}
# @FUNCTION: _python_check_locale_sanity
# @USAGE: <locale>
# @RETURN: 0 if sane, 1 otherwise
# @DESCRIPTION:
# Check whether the specified locale sanely maps between lowercase
# and uppercase ASCII characters.
_python_check_locale_sanity() {
local -x LC_CTYPE=${1}
local IFS=
local lc=( {a..z} )
local uc=( {A..Z} )
local input="${lc[*]}${uc[*]}"
local output=$(tr '[:lower:][:upper:]' '[:upper:][:lower:]' <<<"${input}")
[[ ${output} == "${uc[*]}${lc[*]}" ]]
}
# @FUNCTION: python_export_utf8_locale
# @RETURN: 0 on success, 1 on failure.
# @DESCRIPTION:
@ -1101,20 +1233,33 @@ python_fix_shebang() {
python_export_utf8_locale() {
debug-print-function ${FUNCNAME} "${@}"
if [[ $(locale charmap) != UTF-8 ]]; then
if [[ -n ${LC_ALL} ]]; then
ewarn "LC_ALL is set to a locale with a charmap other than UTF-8."
ewarn "This may trigger build failures in some python packages."
return 1
fi
# If the locale program isn't available, just return.
type locale >/dev/null || return 0
if [[ $(locale charmap) != UTF-8 ]]; then
# Try English first, then everything else.
local lang locales="en_US.UTF-8 $(locale -a)"
for lang in ${locales}; do
if [[ $(LC_CTYPE=${lang} locale charmap 2>/dev/null) == UTF-8 ]]; then
export LC_CTYPE=${lang}
return 0
if [[ $(LC_ALL=${lang} locale charmap 2>/dev/null) == UTF-8 ]]; then
if _python_check_locale_sanity "${lang}"; then
export LC_CTYPE=${lang}
if [[ -n ${LC_ALL} ]]; then
export LC_NUMERIC=${LC_ALL}
export LC_TIME=${LC_ALL}
export LC_COLLATE=${LC_ALL}
export LC_MONETARY=${LC_ALL}
export LC_MESSAGES=${LC_ALL}
export LC_PAPER=${LC_ALL}
export LC_NAME=${LC_ALL}
export LC_ADDRESS=${LC_ALL}
export LC_TELEPHONE=${LC_ALL}
export LC_MEASUREMENT=${LC_ALL}
export LC_IDENTIFICATION=${LC_ALL}
export LC_ALL=
fi
return 0
fi
fi
done

View File

@ -1,6 +1,6 @@
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.171 2015/03/31 18:43:33 ulm Exp $
# $Id$
# @ECLASS: python.eclass
# @MAINTAINER:
@ -12,6 +12,10 @@
# This eclass is DEPRECATED. Please use python-r1, python-single-r1
# or python-any-r1 instead.
if [[ ${EAPI} == 6 ]]; then
die "${ECLASS}.eclass is banned in EAPI ${EAPI}"
fi
if [[ ${_PYTHON_UTILS_R1} ]]; then
die 'python.eclass can not be used with python-r1 suite eclasses.'
fi
@ -341,19 +345,7 @@ _python_initialize_prefix_variables() {
unset PYTHON_SANITY_CHECKS_EXECUTED PYTHON_SKIP_SANITY_CHECKS
_python_initial_sanity_checks() {
if [[ "$(declare -p PYTHON_SANITY_CHECKS_EXECUTED 2> /dev/null)" != "declare -- PYTHON_SANITY_CHECKS_EXECUTED="* || " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " && -z "${PYTHON_SKIP_SANITY_CHECKS}" ]]; then
# Ensure that /usr/bin/python and /usr/bin/python-config are valid.
if [[ "$(readlink "${EPREFIX}/usr/bin/python")" != "python-wrapper" ]]; then
eerror "'${EPREFIX}/usr/bin/python' is not a valid symlink."
eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
die "'${EPREFIX}/usr/bin/python' is not a valid symlink"
fi
if [[ "$(<"${EPREFIX}/usr/bin/python-config")" != *"Gentoo python-config wrapper script"* ]]; then
eerror "'${EPREFIX}/usr/bin/python-config' is not a valid script"
eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
die "'${EPREFIX}/usr/bin/python-config' is not a valid script"
fi
fi
:
}
_python_final_sanity_checks() {
@ -804,10 +796,6 @@ _python_calculate_PYTHON_ABIS() {
python_version="$("${EPREFIX}/usr/bin/python" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
if has_version "=dev-lang/python-2*"; then
if [[ "$(readlink "${EPREFIX}/usr/bin/python2")" != "python2."* ]]; then
die "'${EPREFIX}/usr/bin/python2' is not a valid symlink"
fi
python2_version="$("${EPREFIX}/usr/bin/python2" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
support_python_major_version="0"
@ -827,10 +815,6 @@ _python_calculate_PYTHON_ABIS() {
fi
if has_version "=dev-lang/python-3*"; then
if [[ "$(readlink "${EPREFIX}/usr/bin/python3")" != "python3."* ]]; then
die "'${EPREFIX}/usr/bin/python3' is not a valid symlink"
fi
python3_version="$("${EPREFIX}/usr/bin/python3" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
support_python_major_version="0"