libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

python-any-r1.eclass (10656B)


      1 # Copyright 1999-2022 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: 6 7 8
     11 # @PROVIDES: python-utils-r1
     12 # @BLURB: An eclass for packages having build-time dependency on Python.
     13 # @DESCRIPTION:
     14 # A minimal eclass for packages which need any Python interpreter
     15 # installed without a need for explicit choice and invariability.
     16 # This usually involves packages requiring Python at build-time
     17 # but having no other relevance to it.
     18 #
     19 # This eclass provides a minimal PYTHON_DEPS variable with a dependency
     20 # string on any of the supported Python implementations. It also exports
     21 # pkg_setup() which finds the best supported implementation and sets it
     22 # as the active one.
     23 #
     24 # Optionally, you can define a python_check_deps() function. It will
     25 # be called by the eclass with EPYTHON set to each matching Python
     26 # implementation and it is expected to check whether the implementation
     27 # fulfills the package requirements. You can use the locally exported
     28 # PYTHON_USEDEP or PYTHON_SINGLE_USEDEP to check USE-dependencies
     29 # of relevant packages. It should return a true value (0) if the Python
     30 # implementation fulfills the requirements, a false value (non-zero)
     31 # otherwise.
     32 #
     33 # Please note that python-any-r1 will always inherit python-utils-r1
     34 # as well. Thus, all the functions defined there can be used in the
     35 # packages using python-any-r1, and there is no need ever to inherit
     36 # both.
     37 #
     38 # For more information, please see the Python Guide:
     39 # https://projects.gentoo.org/python/guide/
     40 
     41 case "${EAPI:-0}" in
     42 	[0-5]) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
     43 	[6-8]) ;;
     44 	*)     die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;;
     45 esac
     46 
     47 if [[ ! ${_PYTHON_ANY_R1} ]]; then
     48 
     49 if [[ ${_PYTHON_R1} ]]; then
     50 	die 'python-any-r1.eclass can not be used with python-r1.eclass.'
     51 elif [[ ${_PYTHON_SINGLE_R1} ]]; then
     52 	die 'python-any-r1.eclass can not be used with python-single-r1.eclass.'
     53 fi
     54 
     55 inherit python-utils-r1
     56 
     57 fi
     58 
     59 EXPORT_FUNCTIONS pkg_setup
     60 
     61 # @ECLASS_VARIABLE: PYTHON_COMPAT
     62 # @REQUIRED
     63 # @DESCRIPTION:
     64 # This variable contains a list of Python implementations the package
     65 # supports. It must be set before the `inherit' call. It has to be
     66 # an array.
     67 #
     68 # Example:
     69 # @CODE
     70 # PYTHON_COMPAT=( python{2_5,2_6,2_7} )
     71 # @CODE
     72 
     73 # @ECLASS_VARIABLE: PYTHON_COMPAT_OVERRIDE
     74 # @USER_VARIABLE
     75 # @DEFAULT_UNSET
     76 # @DESCRIPTION:
     77 # This variable can be used when working with ebuilds to override
     78 # the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
     79 # which will be used to build the package. It needs to be specified
     80 # in the calling environment, and not in ebuilds.
     81 #
     82 # It should be noted that in order to preserve metadata immutability,
     83 # PYTHON_COMPAT_OVERRIDE does not affect dependencies. The value of
     84 # EPYTHON and eselect-python preferences are ignored. Dependencies need
     85 # to be satisfied manually.
     86 #
     87 # Example:
     88 # @CODE
     89 # PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
     90 # @CODE
     91 
     92 # @ECLASS_VARIABLE: PYTHON_REQ_USE
     93 # @DEFAULT_UNSET
     94 # @DESCRIPTION:
     95 # The list of USEflags required to be enabled on the Python
     96 # implementations, formed as a USE-dependency string. It should be valid
     97 # for all implementations in PYTHON_COMPAT, so it may be necessary to
     98 # use USE defaults.
     99 #
    100 # Example:
    101 # @CODE
    102 # PYTHON_REQ_USE="gdbm,ncurses(-)?"
    103 # @CODE
    104 #
    105 # It will cause the Python dependencies to look like:
    106 # @CODE
    107 # || ( dev-lang/python:X.Y[gdbm,ncurses(-)?] ... )
    108 # @CODE
    109 
    110 # @ECLASS_VARIABLE: PYTHON_DEPS
    111 # @OUTPUT_VARIABLE
    112 # @DESCRIPTION:
    113 # This is an eclass-generated Python dependency string for all
    114 # implementations listed in PYTHON_COMPAT.
    115 #
    116 # Any of the supported interpreters will satisfy the dependency.
    117 #
    118 # Example use:
    119 # @CODE
    120 # BDEPEND="${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 # 	python_has_version "dev-python/foo[${PYTHON_USEDEP}]"
    143 # }
    144 # @CODE
    145 #
    146 # Example value:
    147 # @CODE
    148 # python_targets_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 # 	python_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_ALLOW_PY27=1 \
    178 	_python_set_impls
    179 
    180 	for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
    181 		_python_export "${i}" PYTHON_PKG_DEP
    182 
    183 		# note: need to strip '=' slot operator for || deps
    184 		deps="${PYTHON_PKG_DEP/:0=/:0} ${deps}"
    185 	done
    186 	deps="|| ( ${deps})"
    187 
    188 	if [[ ${PYTHON_DEPS+1} ]]; then
    189 		if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
    190 			eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
    191 			eerror "Before: ${PYTHON_DEPS}"
    192 			eerror "Now   : ${deps}"
    193 			die "PYTHON_DEPS integrity check failed"
    194 		fi
    195 	else
    196 		PYTHON_DEPS=${deps}
    197 		readonly PYTHON_DEPS
    198 	fi
    199 
    200 	if [[ ! ${PYTHON_REQUIRED_USE+1} ]]; then
    201 		# fake var to catch mistaken usage
    202 		PYTHON_REQUIRED_USE='I-DO-NOT-EXIST-IN-PYTHON-ANY-R1'
    203 		readonly PYTHON_REQUIRED_USE
    204 	fi
    205 }
    206 _python_any_set_globals
    207 unset -f _python_any_set_globals
    208 
    209 if [[ ! ${_PYTHON_ANY_R1} ]]; then
    210 
    211 # @FUNCTION: python_gen_any_dep
    212 # @USAGE: <dependency-block>
    213 # @DESCRIPTION:
    214 # Generate an any-of dependency that enforces a version match between
    215 # the Python interpreter and Python packages. <dependency-block> needs
    216 # to list one or more dependencies with verbatim '${PYTHON_USEDEP}'
    217 # or '${PYTHON_SINGLE_USEDEP}' references (quoted!) that will get
    218 # expanded inside the function.
    219 #
    220 # This should be used along with an appropriate python_check_deps()
    221 # that checks which of the any-of blocks were matched.
    222 #
    223 # Example use:
    224 # @CODE
    225 # BDEPEND="$(python_gen_any_dep '
    226 #	dev-python/foo[${PYTHON_SINGLE_USEDEP}]
    227 #	|| ( dev-python/bar[${PYTHON_USEDEP}]
    228 #		dev-python/baz[${PYTHON_USEDEP}] )')"
    229 #
    230 # python_check_deps() {
    231 #	python_has_version "dev-python/foo[${PYTHON_SINGLE_USEDEP}]" \
    232 #		&& { python_has_version "dev-python/bar[${PYTHON_USEDEP}]" \
    233 #			|| python_has_version "dev-python/baz[${PYTHON_USEDEP}]"; }
    234 # }
    235 # @CODE
    236 #
    237 # Example value:
    238 # @CODE
    239 # || (
    240 #	(
    241 #		dev-lang/python:3.7
    242 #		dev-python/foo[python_single_target_python3_7(-)]
    243 #		|| ( dev-python/bar[python_targets_python3_7(-)
    244 #			dev-python/baz[python_targets_python3_7(-) )
    245 #	)
    246 #	(
    247 #		dev-lang/python:3.8
    248 #		dev-python/foo[python_single_target_python3_8(-)]
    249 #		|| ( dev-python/bar[python_targets_python3_8(-)]
    250 #			dev-python/baz[python_targets_python3_8(-)] )
    251 #	)
    252 # )
    253 # @CODE
    254 python_gen_any_dep() {
    255 	debug-print-function ${FUNCNAME} "${@}"
    256 
    257 	local depstr=${1}
    258 	[[ ${depstr} ]] || die "No dependency string provided"
    259 
    260 	local i PYTHON_PKG_DEP out=
    261 	for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
    262 		local PYTHON_USEDEP="python_targets_${i}(-)"
    263 		local PYTHON_SINGLE_USEDEP="python_single_target_${i}(-)"
    264 		_python_export "${i}" PYTHON_PKG_DEP
    265 
    266 		local i_depstr=${depstr//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
    267 		i_depstr=${i_depstr//\$\{PYTHON_SINGLE_USEDEP\}/${PYTHON_SINGLE_USEDEP}}
    268 		# note: need to strip '=' slot operator for || deps
    269 		out="( ${PYTHON_PKG_DEP%=} ${i_depstr} ) ${out}"
    270 	done
    271 	echo "|| ( ${out})"
    272 }
    273 
    274 # @FUNCTION: python_setup
    275 # @DESCRIPTION:
    276 # Determine what the best installed (and supported) Python
    277 # implementation is, and set the Python build environment up for it.
    278 #
    279 # This function will call python_check_deps() if defined.
    280 python_setup() {
    281 	debug-print-function ${FUNCNAME} "${@}"
    282 
    283 	# support developer override
    284 	if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
    285 		local impls=( ${PYTHON_COMPAT_OVERRIDE} )
    286 		[[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-any-r1"
    287 
    288 		ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
    289 		ewarn "implementation will be used:"
    290 		ewarn
    291 		ewarn "	${PYTHON_COMPAT_OVERRIDE}"
    292 		ewarn
    293 		ewarn "Dependencies won't be satisfied, and EPYTHON/eselect-python will be ignored."
    294 
    295 		_python_export "${impls[0]}" EPYTHON PYTHON
    296 		_python_wrapper_setup
    297 		einfo "Using ${EPYTHON} to build (via PYTHON_COMPAT_OVERRIDE)"
    298 		return
    299 	fi
    300 
    301 	# first, try ${EPYTHON}... maybe it's good enough for us.
    302 	local epython_impl=${EPYTHON/./_}
    303 	if [[ ${epython_impl} ]]; then
    304 		if ! has "${epython_impl}" "${_PYTHON_SUPPORTED_IMPLS[@]}"; then
    305 			if ! has "${epython_impl}" "${_PYTHON_ALL_IMPLS[@]}"; then
    306 				ewarn "Invalid EPYTHON: ${EPYTHON}"
    307 			else
    308 				einfo "EPYTHON (${EPYTHON}) not supported by the package"
    309 			fi
    310 		elif _python_run_check_deps "${epython_impl}"; then
    311 			_python_export EPYTHON PYTHON
    312 			_python_wrapper_setup
    313 			einfo "Using ${EPYTHON} to build (via EPYTHON)"
    314 			return
    315 		fi
    316 	fi
    317 
    318 	# fallback to the best installed impl.
    319 	# (reverse iteration over _PYTHON_SUPPORTED_IMPLS)
    320 	local i
    321 	for (( i = ${#_PYTHON_SUPPORTED_IMPLS[@]} - 1; i >= 0; i-- )); do
    322 		local impl=${_PYTHON_SUPPORTED_IMPLS[i]}
    323 		# avoid checking EPYTHON twice
    324 		[[ ${impl} == ${epython_impl} ]] && continue
    325 		_python_export "${impl}" EPYTHON PYTHON
    326 		if _python_run_check_deps "${impl}"; then
    327 			_python_wrapper_setup
    328 			einfo "Using ${EPYTHON} to build (via PYTHON_COMPAT iteration)"
    329 			return
    330 		fi
    331 	done
    332 
    333 	eerror "No Python implementation found for the build. This is usually"
    334 	eerror "a bug in the ebuild. Please report it to bugs.gentoo.org"
    335 	eerror "along with the build log."
    336 	echo
    337 	die "No supported Python implementation installed."
    338 }
    339 
    340 # @FUNCTION: python-any-r1_pkg_setup
    341 # @DESCRIPTION:
    342 # Runs python_setup during from-source installs.
    343 #
    344 # In a binary package installs is a no-op. If you need Python in pkg_*
    345 # phases of a binary package, call python_setup directly.
    346 python-any-r1_pkg_setup() {
    347 	debug-print-function ${FUNCNAME} "${@}"
    348 
    349 	[[ ${MERGE_TYPE} != binary ]] && python_setup
    350 }
    351 
    352 _PYTHON_ANY_R1=1
    353 fi