summaryrefslogtreecommitdiff
path: root/eclass
diff options
context:
space:
mode:
authorArfrever Frehtes Taifersar Arahesis <arfrever@gentoo.org>2009-08-01 22:36:20 +0000
committerArfrever Frehtes Taifersar Arahesis <arfrever@gentoo.org>2009-08-01 22:36:20 +0000
commit3698f286d79f4234312a74c730ddb27efca1a220 (patch)
tree380ea33e9195ef293df4758c4cc4e9f6035f0512 /eclass
parentVersion bump; experimental ebuild, since the code does not look extremely use... (diff)
downloadhistorical-3698f286d79f4234312a74c730ddb27efca1a220.tar.gz
historical-3698f286d79f4234312a74c730ddb27efca1a220.tar.bz2
historical-3698f286d79f4234312a74c730ddb27efca1a220.zip
Add initial support for installation of Python modules for multiple Python versions.
Diffstat (limited to 'eclass')
-rw-r--r--eclass/distutils.eclass101
-rw-r--r--eclass/python.eclass531
2 files changed, 503 insertions, 129 deletions
diff --git a/eclass/distutils.eclass b/eclass/distutils.eclass
index 8d9848574ba7..66e78d3d2414 100644
--- a/eclass/distutils.eclass
+++ b/eclass/distutils.eclass
@@ -1,6 +1,6 @@
-# Copyright 1999-2008 Gentoo Foundation
+# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/distutils.eclass,v 1.55 2009/02/18 14:43:31 pva Exp $
+# $Header: /var/cvsroot/gentoo-x86/eclass/distutils.eclass,v 1.56 2009/08/01 22:36:20 arfrever Exp $
# @ECLASS: distutils.eclass
# @MAINTAINER:
@@ -52,7 +52,7 @@ distutils_src_unpack() {
unpack ${A}
cd "${S}"
- has ${EAPI:-0} 0 1 && distutils_src_prepare
+ has "${EAPI:-0}" 0 1 && distutils_src_prepare
}
# @FUNCTION: distutils_src_prepare
@@ -69,7 +69,14 @@ distutils_src_prepare() {
# @DESCRIPTION:
# The distutils src_compile function, this function is exported
distutils_src_compile() {
- ${python} setup.py build "$@" || die "compilation failed"
+ if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
+ build_modules() {
+ ${python} setup.py build -b "build-${PYTHON_ABI}" "$@"
+ }
+ python_execute_function build_modules "$@"
+ else
+ ${python} setup.py build "$@" || die "compilation failed"
+ fi
}
# @FUNCTION: distutils_src_install
@@ -82,80 +89,95 @@ distutils_src_install() {
# Mark the package to be rebuilt after a python upgrade.
python_need_rebuild
- # need this for python-2.5 + setuptools in cases where
- # a package uses distutils but does not install anything
- # in site-packages. (eg. dev-java/java-config-2.x)
- # - liquidx (14/08/2006)
- pylibdir="$(${python} -c 'from distutils.sysconfig import get_python_lib; print get_python_lib()')"
- [ -n "${pylibdir}" ] && dodir "${pylibdir}"
-
- if has_version ">=dev-lang/python-2.3"; then
- ${python} setup.py install --root="${D}" --no-compile "$@" ||\
- die "python setup.py install failed"
+ if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
+ install_modules() {
+ # need this for python-2.5 + setuptools in cases where
+ # a package uses distutils but does not install anything
+ # in site-packages. (eg. dev-java/java-config-2.x)
+ # - liquidx (14/08/2006)
+ pylibdir="$(${python} -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())')"
+ [[ -n "${pylibdir}" ]] && dodir "${pylibdir}"
+
+ echo ${python} setup.py build -b "build-${PYTHON_ABI}" install --root="${D}" --no-compile "$@"
+ ${python} setup.py build -b "build-${PYTHON_ABI}" install --root="${D}" --no-compile "$@"
+ }
+ python_execute_function install_modules "$@"
else
- ${python} setup.py install --root="${D}" "$@" ||\
- die "python setup.py install failed"
+ # need this for python-2.5 + setuptools in cases where
+ # a package uses distutils but does not install anything
+ # in site-packages. (eg. dev-java/java-config-2.x)
+ # - liquidx (14/08/2006)
+ pylibdir="$(${python} -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())')"
+ [[ -n "${pylibdir}" ]] && dodir "${pylibdir}"
+
+ ${python} setup.py install --root="${D}" --no-compile "$@" || die "python setup.py install failed"
fi
DDOCS="CHANGELOG KNOWN_BUGS MAINTAINERS PKG-INFO CONTRIBUTORS TODO NEWS"
DDOCS="${DDOCS} Change* MANIFEST* README* AUTHORS"
+ local doc
for doc in ${DDOCS}; do
- [ -s "$doc" ] && dodoc $doc
+ [[ -s "$doc" ]] && dodoc $doc
done
- [ -n "${DOCS}" ] && dodoc ${DOCS}
+ [[ -n "${DOCS}" ]] && dodoc ${DOCS}
}
# @FUNCTION: distutils_pkg_postrm
# @DESCRIPTION:
# Generic pyc/pyo cleanup script. This function is exported.
distutils_pkg_postrm() {
- local moddir pylibdir pymod
+ local pylibdir pymod
if [[ -z "${PYTHON_MODNAME}" ]]; then
for pylibdir in "${ROOT}"/usr/$(get_libdir)/python*; do
- if [[ -d "${pylibdir}"/site-packages/${PN} ]]; then
- PYTHON_MODNAME=${PN}
+ if [[ -d "${pylibdir}/site-packages/${PN}" ]]; then
+ PYTHON_MODNAME="${PN}"
fi
done
fi
- if has_version ">=dev-lang/python-2.3"; then
- ebegin "Performing Python Module Cleanup .."
- if [[ -n "${PYTHON_MODNAME}" ]]; then
- for pymod in ${PYTHON_MODNAME}; do
- for pylibdir in "${ROOT}"/usr/$(get_libdir)/python*; do
- if [[ -d "${pylibdir}"/site-packages/${pymod} ]]; then
- python_mod_cleanup "${pylibdir#${ROOT}}"/site-packages/${pymod}
+ ebegin "Performing cleanup of Python modules..."
+ if [[ -n "${PYTHON_MODNAME}" ]]; then
+ for pymod in ${PYTHON_MODNAME}; do
+ for pylibdir in "${ROOT}"/usr/$(get_libdir)/python*; do
+ if [[ -d "${pylibdir}/site-packages/${pymod}" ]]; then
+ if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
+ python_mod_cleanup "${pymod}"
+ else
+ python_mod_cleanup "${pylibdir#${ROOT}}/site-packages/${pymod}"
fi
- done
+ fi
done
- else
- python_mod_cleanup
- fi
- eend 0
+ done
+ else
+ python_mod_cleanup
fi
+ eend 0
}
# @FUNCTION: distutils_pkg_postinst
# @DESCRIPTION:
# This is a generic optimization, you should override it if your package
-# installs things in another directory. This function is exported
+# installs modules in another directory. This function is exported.
distutils_pkg_postinst() {
local pylibdir pymod
if [[ -z "${PYTHON_MODNAME}" ]]; then
for pylibdir in "${ROOT}"/usr/$(get_libdir)/python*; do
- if [[ -d "${pylibdir}"/site-packages/${PN} ]]; then
- PYTHON_MODNAME=${PN}
+ if [[ -d "${pylibdir}/site-packages/${PN}" ]]; then
+ PYTHON_MODNAME="${PN}"
fi
done
fi
- if has_version ">=dev-lang/python-2.3"; then
+ if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
+ for pymod in ${PYTHON_MODNAME}; do
+ python_mod_optimize "${pymod}"
+ done
+ else
python_version
for pymod in ${PYTHON_MODNAME}; do
- python_mod_optimize \
- /usr/$(get_libdir)/python${PYVER}/site-packages/${pymod}
+ python_mod_optimize "/usr/$(get_libdir)/python${PYVER}/site-packages/${pymod}"
done
fi
}
@@ -174,4 +196,3 @@ distutils_python_version() {
distutils_python_tkinter() {
python_tkinter_exists
}
-
diff --git a/eclass/python.eclass b/eclass/python.eclass
index 20e59e851565..14320185c7f4 100644
--- a/eclass/python.eclass
+++ b/eclass/python.eclass
@@ -1,6 +1,6 @@
-# Copyright 1999-2008 Gentoo Foundation
+# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.55 2009/05/27 22:49:32 betelgeuse Exp $
+# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.56 2009/08/01 22:36:20 arfrever Exp $
# @ECLASS: python.eclass
# @MAINTAINER:
@@ -21,6 +21,10 @@ else
PYTHON_ATOM="dev-lang/python"
fi
+if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
+ DEPEND="${DEPEND} >=app-admin/eselect-python-20090801"
+fi
+
__python_eclass_test() {
__python_version_extract 2.3
echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR"
@@ -62,6 +66,227 @@ python_version() {
__python_version_extract $PYVER_ALL
}
+# @FUNCTION: get_python
+# @USAGE: [-a|--absolute-path] <Python_ABI="${PYTHON_ABI}">
+# @DESCRIPTION:
+# Get Python interpreter filename for specified Python ABI. If Python_ABI argument
+# is ommitted, then PYTHON_ABI environment variable must be set and is used.
+get_python() {
+ local absolute_path="0" slot=
+
+ while (($#)); do
+ case "$1" in
+ -a|--absolute-path)
+ absolute_path="1"
+ ;;
+ -*)
+ die "${FUNCNAME}(): Unrecognized option $1"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+ done
+
+ if [[ "$#" -eq "0" ]]; then
+ if [[ -n "${PYTHON_ABI}" ]]; then
+ slot="${PYTHON_ABI}"
+ else
+ die "${FUNCNAME}(): Invalid usage"
+ fi
+ elif [[ "$#" -eq "1" ]]; then
+ slot="$1"
+ else
+ die "${FUNCNAME}(): Invalid usage"
+ fi
+
+ if [[ "${absolute_path}" == "1" ]]; then
+ echo -n "/usr/bin/python${slot}"
+ else
+ echo -n "python${slot}"
+ fi
+}
+
+# @FUNCTION: validate_PYTHON_ABIS
+# @DESCRIPTION:
+# Make sure PYTHON_ABIS variable has valid value.
+validate_PYTHON_ABIS() {
+ # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 4.
+ if [[ -z "${PYTHON_ABIS}" ]] && has "${EAPI:-0}" 0 1 2 3; then
+ local ABI support_ABI supported_PYTHON_ABIS= restricted_ABI
+ PYTHON_ABI_SUPPORTED_VALUES="2.4 2.5 2.6 2.7 3.0 3.1 3.2"
+ for ABI in ${USE_PYTHON}; do
+ if ! has "${ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then
+ ewarn "Ignoring unsupported Python ABI '${ABI}'"
+ continue
+ fi
+ support_ABI="1"
+ for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
+ if python -c "from fnmatch import fnmatch; exit(not fnmatch('${ABI}', '${restricted_ABI}'))"; then
+ support_ABI="0"
+ break
+ fi
+ done
+ [[ "${support_ABI}" == "1" ]] && supported_PYTHON_ABIS+=" ${ABI}"
+ done
+ export PYTHON_ABIS="${supported_PYTHON_ABIS# }"
+ fi
+
+ if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
+ python_version
+ export PYTHON_ABIS="${PYVER}"
+ fi
+}
+
+# @FUNCTION: python_copy_sources
+# @USAGE: [directory]
+# @DESCRIPTION:
+# Copy unpacked sources of given package for each Python ABI.
+python_copy_sources() {
+ local dir dirs=() PYTHON_ABI
+
+ if [[ "$#" -eq "0" ]]; then
+ if [[ "${WORKDIR}" == "${S}" ]]; then
+ die "${FUNCNAME}() cannot be used"
+ fi
+ dirs="${S}"
+ else
+ dirs="$@"
+ fi
+
+ validate_PYTHON_ABIS
+ for PYTHON_ABI in ${PYTHON_ABIS}; do
+ for dir in "${dirs[@]}"; do
+ cp -lpr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
+ done
+ done
+}
+
+# @FUNCTION: python_set_build_dir_symlink
+# @USAGE: [directory="build"]
+# @DESCRIPTION:
+# Create build directory symlink.
+python_set_build_dir_symlink() {
+ local dir="$1"
+
+ [[ -z "${PYTHON_ABIS}" ]] && die "PYTHON_ABIS variable not set"
+ [[ -z "${dir}" ]] && dir="build"
+
+ # Don't delete preexistent directories.
+ rm -f "${dir}" || die "Deletion of '${dir}' failed"
+ ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed"
+}
+
+# @FUNCTION: python_execute_function
+# @USAGE: [--action-message message] [--failure-message message] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] <function> [arguments]
+# @DESCRIPTION:
+# Execute specified function for each value of PYTHON_ABIS, optionally passing
+# additional arguments. The specified function can use PYTHON_ABI variable.
+python_execute_function() {
+ local action action_message action_message_template= failure_message failure_message_template= function nonfatal="0" PYTHON_ABI quiet="0" separate_build_dirs="0"
+
+ while (($#)); do
+ case "$1" in
+ --action-message)
+ action_message_template="$2"
+ shift
+ ;;
+ --failure-message)
+ failure_message_template="$2"
+ shift
+ ;;
+ --nonfatal)
+ nonfatal="1"
+ ;;
+ -q|--quiet)
+ quiet="1"
+ ;;
+ -s|--separate-build-dirs)
+ separate_build_dirs="1"
+ ;;
+ -*)
+ die "${FUNCNAME}(): Unrecognized option $1"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+ done
+
+ if [[ "$#" -eq "0" ]]; then
+ die "${FUNCNAME}(): Missing function name"
+ fi
+ function="$1"
+ shift
+
+ if [[ "${quiet}" == "0" ]]; then
+ [[ "${EBUILD_PHASE}" == "setup" ]] && action="Setting up"
+ [[ "${EBUILD_PHASE}" == "unpack" ]] && action="Unpacking"
+ [[ "${EBUILD_PHASE}" == "prepare" ]] && action="Preparation"
+ [[ "${EBUILD_PHASE}" == "configure" ]] && action="Configuration"
+ [[ "${EBUILD_PHASE}" == "compile" ]] && action="Building"
+ [[ "${EBUILD_PHASE}" == "test" ]] && action="Testing"
+ [[ "${EBUILD_PHASE}" == "install" ]] && action="Installation"
+ [[ "${EBUILD_PHASE}" == "preinst" ]] && action="Preinstallation"
+ [[ "${EBUILD_PHASE}" == "postinst" ]] && action="Postinstallation"
+ [[ "${EBUILD_PHASE}" == "prerm" ]] && action="Preuninstallation"
+ [[ "${EBUILD_PHASE}" == "postrm" ]] && action="Postuninstallation"
+ fi
+
+ local RED GREEN BLUE NORMAL
+ if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
+ RED=$'\e[1;31m'
+ GREEN=$'\e[1;32m'
+ BLUE=$'\e[1;34m'
+ NORMAL=$'\e[0m'
+ else
+ RED=
+ GREEN=
+ BLUE=
+ NORMAL=
+ fi
+
+ validate_PYTHON_ABIS
+ for PYTHON_ABI in ${PYTHON_ABIS}; do
+ if [[ "${quiet}" == "0" ]]; then
+ if [[ -n "${action_message_template}" ]]; then
+ action_message="$(eval echo -n "${action_message_template}")"
+ else
+ action_message="${action} of ${CATEGORY}/${PF} with Python ${PYTHON_ABI}..."
+ fi
+ echo " ${GREEN}*${NORMAL} ${BLUE}${action_message}${NORMAL}"
+ fi
+ if [[ "${separate_build_dirs}" == "1" ]]; then
+ pushd "${S}-${PYTHON_ABI}" > /dev/null || die "pushd failed"
+ fi
+ if ! EPYTHON="$(get_python)" "${function}" "$@"; then
+ if [[ -n "${failure_message_template}" ]]; then
+ failure_message="$(eval echo -n "${failure_message_template}")"
+ else
+ failure_message="${action} failed with Python ${PYTHON_ABI} in ${function}() function"
+ fi
+ if [[ "${nonfatal}" == "1" ]] || has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
+ local ABI enabled_PYTHON_ABIS
+ for ABI in ${PYTHON_ABIS}; do
+ [[ "${ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+=" ${ABI}"
+ done
+ export PYTHON_ABIS="${enabled_PYTHON_ABIS# }"
+ if [[ "${quiet}" == "0" ]]; then
+ ewarn "${RED}${failure_message}${NORMAL}"
+ fi
+ else
+ die "${failure_message}"
+ fi
+ fi
+ if [[ "${separate_build_dirs}" == "1" ]]; then
+ popd > /dev/null || die "popd failed"
+ fi
+ done
+}
+
+
# @ECLASS-VARIABLE: PYTHON_USE_WITH
# @DESCRIPTION:
# Set this to a space separated list of use flags
@@ -166,17 +391,33 @@ python_need_rebuild() {
export PYTHON_NEED_REBUILD=${PYVER}
}
+# @FUNCTION: python_get_includedir
+# @DESCRIPTION:
+# Run without arguments, returns the Python include directory.
+python_get_includedir() {
+ if [[ -n "${PYTHON_ABI}" ]]; then
+ echo "/usr/include/python${PYTHON_ABI}"
+ else
+ python_version
+ echo "/usr/include/python${PYVER}"
+ fi
+}
+
# @FUNCTION: python_get_libdir
# @DESCRIPTION:
-# Run without arguments, returns the python library dir
+# Run without arguments, returns the Python library directory.
python_get_libdir() {
- python_version
- echo "/usr/$(get_libdir)/python${PYVER}"
+ if [[ -n "${PYTHON_ABI}" ]]; then
+ echo "/usr/$(get_libdir)/python${PYTHON_ABI}"
+ else
+ python_version
+ echo "/usr/$(get_libdir)/python${PYVER}"
+ fi
}
# @FUNCTION: python_get_sitedir
# @DESCRIPTION:
-# Run without arguments, returns the python site-packages dir
+# Run without arguments, returns the Python site-packages directory.
python_get_sitedir() {
echo "$(python_get_libdir)/site-packages"
}
@@ -205,7 +446,7 @@ python_tkinter_exists() {
}
# @FUNCTION: python_mod_exists
-# @USAGE: < module >
+# @USAGE: <module>
# @DESCRIPTION:
# Run with the module name as an argument. it will check if a
# python module is installed and loadable. it will return
@@ -218,11 +459,11 @@ python_tkinter_exists() {
# fi
python_mod_exists() {
[[ "$1" ]] || die "${FUNCNAME} requires an argument!"
- python -c "import $1" >/dev/null 2>&1
+ python -c "import $1" &>/dev/null
}
# @FUNCTION: python_mod_compile
-# @USAGE: < file > [more files ...]
+# @USAGE: <file> [more files ...]
# @DESCRIPTION:
# Given filenames, it will pre-compile the module's .pyc and .pyo.
# This function should only be run in pkg_postinst()
@@ -231,6 +472,10 @@ python_mod_exists() {
# python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py
#
python_mod_compile() {
+ if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
+ die "${FUNCNAME}() cannot be used in this EAPI"
+ fi
+
local f myroot myfiles=()
# Check if phase is pkg_postinst()
@@ -261,112 +506,220 @@ python_mod_compile() {
}
# @FUNCTION: python_mod_optimize
-# @USAGE: [ path ]
+# @USAGE: [options] [directory|file]
# @DESCRIPTION:
-# If no arguments supplied, it will recompile all modules under
-# sys.path (eg. /usr/lib/python2.3, /usr/lib/python2.3/site-packages/ ..)
-# no recursively
+# If no arguments supplied, it will recompile not recursively all modules
+# under sys.path (eg. /usr/lib/python2.6, /usr/lib/python2.6/site-packages).
#
# If supplied with arguments, it will recompile all modules recursively
-# in the supplied directory
-# This function should only be run in pkg_postinst()
+# in the supplied directory.
+# This function should only be run in pkg_postinst().
#
-# Options passed to this function are passed to compileall.py
+# Options passed to this function are passed to compileall.py.
#
# Example:
-# python_mod_optimize /usr/share/codegen
+# python_mod_optimize ctypesgencore
python_mod_optimize() {
- local myroot mydirs=() myfiles=() myopts=()
-
- # Check if phase is pkg_postinst()
- [[ ${EBUILD_PHASE} != postinst ]] &&\
- die "${FUNCNAME} should only be run in pkg_postinst()"
-
- # strip trailing slash
- myroot="${ROOT%/}"
+ # Check if phase is pkg_postinst().
+ [[ ${EBUILD_PHASE} != "postinst" ]] && die "${FUNCNAME} should only be run in pkg_postinst()"
+
+ if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
+ local dir file options=() other_dirs=() other_files=() PYTHON_ABI return_code root site_packages_absolute_dirs=() site_packages_dirs=() site_packages_absolute_files=() site_packages_files=()
+
+ # Strip trailing slash from ROOT.
+ root="${ROOT%/}"
+
+ # Respect ROOT and options passed to compileall.py.
+ while (($#)); do
+ case "$1" in
+ -l|-f|-q)
+ options+=("$1")
+ ;;
+ -d|-x)
+ options+=("$1" "$2")
+ shift
+ ;;
+ -*)
+ ewarn "${FUNCNAME}: Ignoring compile option $1"
+ ;;
+ *)
+ if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
+ die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
+ elif [[ "$1" =~ ^/ ]]; then
+ if [[ -d "${root}/$1" ]]; then
+ other_dirs+=("${root}/$1")
+ elif [[ -f "${root}/$1" ]]; then
+ other_files+=("${root}/$1")
+ elif [[ -e "${root}/$1" ]]; then
+ ewarn "'${root}/$1' is not a file or a directory!"
+ else
+ ewarn "'${root}/$1' doesn't exist!"
+ fi
+ else
+ for PYTHON_ABI in ${PYTHON_ABIS}; do
+ if [[ -d "${root}/$(python_get_sitedir)/$1" ]]; then
+ site_packages_dirs+=("$1")
+ break
+ elif [[ -f "${root}/$(python_get_sitedir)/$1" ]]; then
+ site_packages_files+=("$1")
+ break
+ elif [[ -e "${root}/$(python_get_sitedir)/$1" ]]; then
+ ewarn "'$1' is not a file or a directory!"
+ else
+ ewarn "'$1' doesn't exist!"
+ fi
+ done
+ fi
+ ;;
+ esac
+ shift
+ done
- # respect ROOT and options passed to compileall.py
- while (($#)); do
- case $1 in
- -l|-f|-q)
- myopts+=("$1")
- ;;
- -d|-x)
- myopts+=("$1" "$2")
- shift
- ;;
- -*)
- ewarn "${FUNCNAME}: Ignoring compile option $1"
- ;;
- *)
- if [[ -d "${myroot}"/$1 ]]; then
- mydirs+=("${myroot}/$1")
- elif [[ -f "${myroot}"/$1 ]]; then
- # Files are passed to python_mod_compile which is ROOT-aware
- myfiles+=("$1")
- elif [[ -e "${myroot}/$1" ]]; then
- ewarn "${myroot}/$1 is not a file or directory!"
- else
- ewarn "${myroot}/$1 doesn't exist!"
+ # Set additional options.
+ options+=("-q")
+
+ for PYTHON_ABI in ${PYTHON_ABIS}; do
+ if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then
+ return_code="0"
+ ebegin "Compilation and optimization of Python modules for Python ${PYTHON_ABI}"
+ if ((${#site_packages_dirs[@]})); then
+ for dir in "${site_packages_dirs[@]}"; do
+ site_packages_absolute_dirs+=("${root}/$(python_get_sitedir)/${dir}")
+ done
+ "$(get_python)" "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1"
+ "$(get_python)" -O "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1"
fi
- ;;
- esac
- shift
- done
+ if ((${#site_packages_files[@]})); then
+ for file in "${site_packages_files[@]}"; do
+ site_packages_absolute_files+=("${root}/$(python_get_sitedir)/${file}")
+ done
+ "$(get_python)" "${root}/$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1"
+ "$(get_python)" -O "${root}/$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1"
+ fi
+ eend "${return_code}"
+ fi
+ unset site_packages_absolute_dirs site_packages_absolute_files
+ done
- # allow compiling for older python versions
- if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then
- PYVER=${PYTHON_OVERRIDE_PYVER}
+ # Don't use PYTHON_ABI in next calls to python_get_libdir().
+ unset PYTHON_ABI
+
+ if ((${#other_dirs[@]})) || ((${#other_files[@]})); then
+ return_code="0"
+ ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for Python ${PYVER}..."
+ if ((${#other_dirs[@]})); then
+ python${PYVER} "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
+ python${PYVER} -O "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
+ fi
+ if ((${#other_files[@]})); then
+ python${PYVER} "${root}/$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
+ python${PYVER} -O "${root}/$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
+ fi
+ eend "${return_code}"
+ fi
else
- python_version
- fi
+ local myroot mydirs=() myfiles=() myopts=()
+
+ # strip trailing slash
+ myroot="${ROOT%/}"
+
+ # respect ROOT and options passed to compileall.py
+ while (($#)); do
+ case "$1" in
+ -l|-f|-q)
+ myopts+=("$1")
+ ;;
+ -d|-x)
+ myopts+=("$1" "$2")
+ shift
+ ;;
+ -*)
+ ewarn "${FUNCNAME}: Ignoring compile option $1"
+ ;;
+ *)
+ if [[ -d "${myroot}"/$1 ]]; then
+ mydirs+=("${myroot}/$1")
+ elif [[ -f "${myroot}"/$1 ]]; then
+ # Files are passed to python_mod_compile which is ROOT-aware
+ myfiles+=("$1")
+ elif [[ -e "${myroot}/$1" ]]; then
+ ewarn "${myroot}/$1 is not a file or directory!"
+ else
+ ewarn "${myroot}/$1 doesn't exist!"
+ fi
+ ;;
+ esac
+ shift
+ done
- # set additional opts
- myopts+=(-q)
-
- ebegin "Byte compiling python modules for python-${PYVER} .."
- if ((${#mydirs[@]})); then
- python${PYVER} \
- "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
- "${myopts[@]}" "${mydirs[@]}"
- python${PYVER} -O \
- "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
- "${myopts[@]}" "${mydirs[@]}"
- fi
+ # allow compiling for older python versions
+ if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then
+ PYVER=${PYTHON_OVERRIDE_PYVER}
+ else
+ python_version
+ fi
- if ((${#myfiles[@]})); then
- python_mod_compile "${myfiles[@]}"
- fi
+ # set additional opts
+ myopts+=(-q)
+
+ ebegin "Byte compiling python modules for python-${PYVER} .."
+ if ((${#mydirs[@]})); then
+ python${PYVER} \
+ "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
+ "${myopts[@]}" "${mydirs[@]}"
+ python${PYVER} -O \
+ "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
+ "${myopts[@]}" "${mydirs[@]}"
+ fi
- eend $?
+ if ((${#myfiles[@]})); then
+ python_mod_compile "${myfiles[@]}"
+ fi
+
+ eend $?
+ fi
}
# @FUNCTION: python_mod_cleanup
-# @USAGE: [ dir ]
+# @USAGE: [directory]
# @DESCRIPTION:
# Run with optional arguments, where arguments are directories of
-# python modules. if none given, it will look in /usr/lib/python[0-9].[0-9]
+# python modules. If none given, it will look in /usr/lib/python[0-9].[0-9].
#
-# It will recursively scan all compiled python modules in the directories
-# and determine if they are orphaned (eg. their corresponding .py is missing.)
-# if they are, then it will remove their corresponding .pyc and .pyo
+# It will recursively scan all compiled Python modules in the directories and
+# determine if they are orphaned (i.e. their corresponding .py files are missing.)
+# If they are, then it will remove their corresponding .pyc and .pyo files.
#
-# This function should only be run in pkg_postrm()
+# This function should only be run in pkg_postrm().
python_mod_cleanup() {
- local SEARCH_PATH=() myroot src_py
+ local PYTHON_ABI SEARCH_PATH=() root src_py
- # Check if phase is pkg_postrm()
- [[ ${EBUILD_PHASE} != postrm ]] &&\
- die "${FUNCNAME} should only be run in pkg_postrm()"
+ # Check if phase is pkg_postrm().
+ [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME} should only be run in pkg_postrm()"
- # strip trailing slash
- myroot="${ROOT%/}"
+ # Strip trailing slash from ROOT.
+ root="${ROOT%/}"
if (($#)); then
- SEARCH_PATH=("${@#/}")
- SEARCH_PATH=("${SEARCH_PATH[@]/#/$myroot/}")
+ if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
+ while (($#)); do
+ if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
+ die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
+ elif [[ "$1" =~ ^/ ]]; then
+ SEARCH_PATH+=("${root}/${1#/}")
+ else
+ for PYTHON_ABI in ${PYTHON_ABIS}; do
+ SEARCH_PATH+=("${root}/$(python_get_sitedir)/$1")
+ done
+ fi
+ shift
+ done
+ else
+ SEARCH_PATH=("${@#/}")
+ SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}")
+ fi
else
- SEARCH_PATH=("${myroot}"/usr/lib*/python*/site-packages)
+ SEARCH_PATH=("${root}"/usr/lib*/python*/site-packages)
fi
for path in "${SEARCH_PATH[@]}"; do
@@ -378,7 +731,7 @@ python_mod_cleanup() {
rm -f "${src_py}"[co]
done
- # attempt to remove directories that maybe empty
+ # Attempt to remove directories that may be empty.
find "${path}" -type d | sort -r | while read -r dir; do
rmdir "${dir}" 2>/dev/null
done