libshit

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

python-single-r1.eclass (13652B)


      1 # Copyright 1999-2022 Gentoo Authors
      2 # Distributed under the terms of the GNU General Public License v2
      3 
      4 # @ECLASS: python-single-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 Python packages not installed for multiple implementations.
     13 # @DESCRIPTION:
     14 # An extension of the python-r1 eclass suite for packages which
     15 # don't support being installed for multiple Python implementations.
     16 # This mostly includes tools embedding Python and packages using foreign
     17 # build systems.
     18 #
     19 # This eclass sets correct IUSE.  It also provides PYTHON_DEPS
     20 # and PYTHON_REQUIRED_USE that need to be added to appropriate ebuild
     21 # metadata variables.
     22 #
     23 # The eclass exports PYTHON_SINGLE_USEDEP that is suitable for depending
     24 # on other packages using the eclass.  Dependencies on packages using
     25 # python-r1 should be created via python_gen_cond_dep() function,
     26 # using PYTHON_USEDEP placeholder.
     27 #
     28 # Please note that packages support multiple Python implementations
     29 # (using python-r1 eclass) can not depend on packages not supporting
     30 # them (using this eclass).
     31 #
     32 # Please note that python-single-r1 will always inherit python-utils-r1
     33 # as well. Thus, all the functions defined there can be used
     34 # in the packages using python-single-r1, and there is no need ever
     35 # to inherit both.
     36 #
     37 # For more information, please see the Python Guide:
     38 # https://projects.gentoo.org/python/guide/
     39 
     40 case "${EAPI:-0}" in
     41 	[0-5])
     42 		die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
     43 		;;
     44 	[6-8])
     45 		;;
     46 	*)
     47 		die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
     48 		;;
     49 esac
     50 
     51 if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
     52 
     53 if [[ ${_PYTHON_R1_ECLASS} ]]; then
     54 	die 'python-single-r1.eclass can not be used with python-r1.eclass.'
     55 elif [[ ${_PYTHON_ANY_R1_ECLASS} ]]; then
     56 	die 'python-single-r1.eclass can not be used with python-any-r1.eclass.'
     57 fi
     58 
     59 inherit python-utils-r1
     60 
     61 fi
     62 
     63 EXPORT_FUNCTIONS pkg_setup
     64 
     65 # @ECLASS_VARIABLE: PYTHON_COMPAT
     66 # @REQUIRED
     67 # @DESCRIPTION:
     68 # This variable contains a list of Python implementations the package
     69 # supports. It must be set before the `inherit' call. It has to be
     70 # an array.
     71 #
     72 # Example:
     73 # @CODE
     74 # PYTHON_COMPAT=( python2_7 python3_3 python3_4 )
     75 # @CODE
     76 #
     77 # Please note that you can also use bash brace expansion if you like:
     78 # @CODE
     79 # PYTHON_COMPAT=( python2_7 python3_{3,4} )
     80 # @CODE
     81 
     82 # @ECLASS_VARIABLE: PYTHON_COMPAT_OVERRIDE
     83 # @USER_VARIABLE
     84 # @DEFAULT_UNSET
     85 # @DESCRIPTION:
     86 # This variable can be used when working with ebuilds to override
     87 # the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
     88 # which package will be built for. It needs to be specified
     89 # in the calling environment, and not in ebuilds.
     90 #
     91 # It should be noted that in order to preserve metadata immutability,
     92 # PYTHON_COMPAT_OVERRIDE does not affect IUSE nor dependencies.
     93 # The state of PYTHON_SINGLE_TARGET is ignored, and the implementation
     94 # in PYTHON_COMPAT_OVERRIDE is built instead.  Dependencies need to be
     95 # satisfied manually.
     96 #
     97 # Example:
     98 # @CODE
     99 # PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
    100 # @CODE
    101 
    102 # @ECLASS_VARIABLE: PYTHON_REQ_USE
    103 # @DEFAULT_UNSET
    104 # @DESCRIPTION:
    105 # The list of USEflags required to be enabled on the chosen Python
    106 # implementations, formed as a USE-dependency string. It should be valid
    107 # for all implementations in PYTHON_COMPAT, so it may be necessary to
    108 # use USE defaults.
    109 #
    110 # This should be set before calling `inherit'.
    111 #
    112 # Example:
    113 # @CODE
    114 # PYTHON_REQ_USE="gdbm,ncurses(-)?"
    115 # @CODE
    116 #
    117 # It will cause the Python dependencies to look like:
    118 # @CODE
    119 # python_single_target_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?] )
    120 # @CODE
    121 
    122 # @ECLASS_VARIABLE: PYTHON_DEPS
    123 # @OUTPUT_VARIABLE
    124 # @DESCRIPTION:
    125 # This is an eclass-generated Python dependency string for all
    126 # implementations listed in PYTHON_COMPAT.
    127 #
    128 # The dependency string is conditional on PYTHON_SINGLE_TARGET.
    129 #
    130 # Example use:
    131 # @CODE
    132 # RDEPEND="${PYTHON_DEPS}
    133 #	dev-foo/mydep"
    134 # BDEPEND="${PYTHON_DEPS}"
    135 # @CODE
    136 #
    137 # Example value:
    138 # @CODE
    139 # python_single_target_python2_7? ( dev-lang/python:2.7[gdbm] )
    140 # python_single_target_pypy? ( dev-python/pypy[gdbm] )
    141 # @CODE
    142 
    143 # @ECLASS_VARIABLE: PYTHON_SINGLE_USEDEP
    144 # @OUTPUT_VARIABLE
    145 # @DESCRIPTION:
    146 # This is an eclass-generated USE-dependency string which can be used to
    147 # depend on another python-single-r1 package being built for the same
    148 # Python implementations.
    149 #
    150 # If you need to depend on a multi-impl (python-r1) package, use
    151 # python_gen_cond_dep with PYTHON_USEDEP placeholder instead.
    152 #
    153 # Example use:
    154 # @CODE
    155 # RDEPEND="dev-python/foo[${PYTHON_SINGLE_USEDEP}]"
    156 # @CODE
    157 #
    158 # Example value:
    159 # @CODE
    160 # python_single_target_python3_4(-)?
    161 # @CODE
    162 
    163 # @ECLASS_VARIABLE: PYTHON_USEDEP
    164 # @OUTPUT_VARIABLE
    165 # @DESCRIPTION:
    166 # This is a placeholder variable supported by python_gen_cond_dep,
    167 # in order to depend on python-r1 packages built for the same Python
    168 # implementations.
    169 #
    170 # Example use:
    171 # @CODE
    172 # RDEPEND="$(python_gen_cond_dep '
    173 #     dev-python/foo[${PYTHON_USEDEP}]
    174 #   ')"
    175 # @CODE
    176 #
    177 # Example value:
    178 # @CODE
    179 # python_targets_python3_4(-)
    180 # @CODE
    181 
    182 # @ECLASS_VARIABLE: PYTHON_REQUIRED_USE
    183 # @OUTPUT_VARIABLE
    184 # @DESCRIPTION:
    185 # This is an eclass-generated required-use expression which ensures
    186 # that exactly one PYTHON_SINGLE_TARGET value has been enabled.
    187 #
    188 # This expression should be utilized in an ebuild by including it in
    189 # REQUIRED_USE, optionally behind a use flag.
    190 #
    191 # Example use:
    192 # @CODE
    193 # REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"
    194 # @CODE
    195 #
    196 # Example value:
    197 # @CODE
    198 # ^^ ( python_single_target_python2_7 python_single_target_python3_3 )
    199 # @CODE
    200 
    201 _python_single_set_globals() {
    202 	_python_set_impls
    203 
    204 	local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_single_target_}" )
    205 
    206 	if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
    207 		# if only one implementation is supported, use IUSE defaults
    208 		# to avoid requesting the user to enable it
    209 		IUSE="+${flags[0]}"
    210 	else
    211 		IUSE="${flags[*]}"
    212 	fi
    213 
    214 	local requse="^^ ( ${flags[*]} )"
    215 	local single_flags="${flags[@]/%/(-)?}"
    216 	local single_usedep=${single_flags// /,}
    217 
    218 	local deps= i PYTHON_PKG_DEP
    219 	for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
    220 		_python_export "${i}" PYTHON_PKG_DEP
    221 		deps+="python_single_target_${i}? (
    222 			${PYTHON_PKG_DEP}
    223 		) "
    224 	done
    225 
    226 	if [[ ${PYTHON_DEPS+1} ]]; then
    227 		if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
    228 			eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
    229 			eerror "Before: ${PYTHON_DEPS}"
    230 			eerror "Now   : ${deps}"
    231 			die "PYTHON_DEPS integrity check failed"
    232 		fi
    233 
    234 		# these two are formality -- they depend on PYTHON_COMPAT only
    235 		if [[ ${PYTHON_REQUIRED_USE} != ${requse} ]]; then
    236 			eerror "PYTHON_REQUIRED_USE have changed between inherits!"
    237 			eerror "Before: ${PYTHON_REQUIRED_USE}"
    238 			eerror "Now   : ${requse}"
    239 			die "PYTHON_REQUIRED_USE integrity check failed"
    240 		fi
    241 
    242 		if [[ ${PYTHON_SINGLE_USEDEP} != "${single_usedep}" ]]; then
    243 			eerror "PYTHON_SINGLE_USEDEP have changed between inherits!"
    244 			eerror "Before: ${PYTHON_SINGLE_USEDEP}"
    245 			eerror "Now   : ${single_usedep}"
    246 			die "PYTHON_SINGLE_USEDEP integrity check failed"
    247 		fi
    248 	else
    249 		PYTHON_DEPS=${deps}
    250 		PYTHON_REQUIRED_USE=${requse}
    251 		PYTHON_USEDEP='%PYTHON_USEDEP-NEEDS-TO-BE-USED-IN-PYTHON_GEN_COND_DEP%'
    252 		PYTHON_SINGLE_USEDEP=${single_usedep}
    253 		readonly PYTHON_DEPS PYTHON_REQUIRED_USE PYTHON_SINGLE_USEDEP \
    254 			PYTHON_USEDEP
    255 	fi
    256 }
    257 _python_single_set_globals
    258 unset -f _python_single_set_globals
    259 
    260 if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
    261 
    262 # @FUNCTION: python_gen_useflags
    263 # @USAGE: [<pattern>...]
    264 # @DESCRIPTION:
    265 # Output a list of USE flags for Python implementations which
    266 # are both in PYTHON_COMPAT and match any of the patterns passed
    267 # as parameters to the function.
    268 #
    269 # For the pattern syntax, please see _python_impl_matches
    270 # in python-utils-r1.eclass.
    271 #
    272 # Example:
    273 # @CODE
    274 # PYTHON_COMPAT=( python{2_7,3_4} )
    275 # REQUIRED_USE="doc? ( ^^ ( $(python_gen_useflags 'python2*') ) )"
    276 # @CODE
    277 #
    278 # It will cause the variable to look like:
    279 # @CODE
    280 # REQUIRED_USE="doc? ( ^^ ( python_single_target_python2_7 ) )"
    281 # @CODE
    282 python_gen_useflags() {
    283 	debug-print-function ${FUNCNAME} "${@}"
    284 
    285 	local impl matches=()
    286 
    287 	_python_verify_patterns "${@}"
    288 	for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
    289 		if _python_impl_matches "${impl}" "${@}"; then
    290 			matches+=( "python_single_target_${impl}" )
    291 		fi
    292 	done
    293 
    294 	echo "${matches[@]}"
    295 }
    296 
    297 # @FUNCTION: python_gen_cond_dep
    298 # @USAGE: <dependency> [<pattern>...]
    299 # @DESCRIPTION:
    300 # Output a list of <dependency>-ies made conditional to USE flags
    301 # of Python implementations which are both in PYTHON_COMPAT and match
    302 # any of the patterns passed as the remaining parameters.
    303 #
    304 # For the pattern syntax, please see _python_impl_matches
    305 # in python-utils-r1.eclass.
    306 #
    307 # In order to enforce USE constraints on the packages, verbatim
    308 # '${PYTHON_SINGLE_USEDEP}' and '${PYTHON_USEDEP}' (quoted!) may
    309 # be placed in the dependency specification. It will get expanded within
    310 # the function into a proper USE dependency string.
    311 #
    312 # Example:
    313 # @CODE
    314 # PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
    315 # RDEPEND="$(python_gen_cond_dep \
    316 #   'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )"
    317 # @CODE
    318 #
    319 # It will cause the variable to look like:
    320 # @CODE
    321 # RDEPEND="python_single_target_python2_7? (
    322 #     dev-python/unittest2[python_targets_python2_7(-)?,...] )
    323 #	python_single_target_pypy? (
    324 #     dev-python/unittest2[python_targets_pypy(-)?,...] )"
    325 # @CODE
    326 python_gen_cond_dep() {
    327 	debug-print-function ${FUNCNAME} "${@}"
    328 
    329 	local impl matches=()
    330 
    331 	local dep=${1}
    332 	shift
    333 
    334 	_python_verify_patterns "${@}"
    335 	for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
    336 		if _python_impl_matches "${impl}" "${@}"; then
    337 			local single_usedep="python_single_target_${impl}(-)"
    338 			local multi_usedep="python_targets_${impl}(-)"
    339 
    340 			local subdep=${dep//\$\{PYTHON_SINGLE_USEDEP\}/${single_usedep}}
    341 			matches+=( "python_single_target_${impl}? (
    342 				${subdep//\$\{PYTHON_USEDEP\}/${multi_usedep}} )" )
    343 		fi
    344 	done
    345 
    346 	echo "${matches[@]}"
    347 }
    348 
    349 # @FUNCTION: python_gen_impl_dep
    350 # @USAGE: [<requested-use-flags> [<impl-pattern>...]]
    351 # @DESCRIPTION:
    352 # Output a dependency on Python implementations with the specified USE
    353 # dependency string appended, or no USE dependency string if called
    354 # without the argument (or with empty argument). If any implementation
    355 # patterns are passed, the output dependencies will be generated only
    356 # for the implementations matching them.
    357 #
    358 # For the pattern syntax, please see _python_impl_matches
    359 # in python-utils-r1.eclass.
    360 #
    361 # Use this function when you need to request different USE flags
    362 # on the Python interpreter depending on package's USE flags. If you
    363 # only need a single set of interpreter USE flags, just set
    364 # PYTHON_REQ_USE and use ${PYTHON_DEPS} globally.
    365 #
    366 # Example:
    367 # @CODE
    368 # PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
    369 # RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )"
    370 # @CODE
    371 #
    372 # It will cause the variable to look like:
    373 # @CODE
    374 # RDEPEND="foo? (
    375 #   python_single_target_python2_7? (
    376 #     dev-lang/python:2.7[xml(+)] )
    377 #	python_single_target_pypy? (
    378 #     dev-python/pypy[xml(+)] ) )"
    379 # @CODE
    380 python_gen_impl_dep() {
    381 	debug-print-function ${FUNCNAME} "${@}"
    382 
    383 	local impl
    384 	local matches=()
    385 
    386 	local PYTHON_REQ_USE=${1}
    387 	shift
    388 
    389 	_python_verify_patterns "${@}"
    390 	for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
    391 		if _python_impl_matches "${impl}" "${@}"; then
    392 			local PYTHON_PKG_DEP
    393 			_python_export "${impl}" PYTHON_PKG_DEP
    394 			matches+=( "python_single_target_${impl}? ( ${PYTHON_PKG_DEP} )" )
    395 		fi
    396 	done
    397 
    398 	echo "${matches[@]}"
    399 }
    400 
    401 # @FUNCTION: python_setup
    402 # @DESCRIPTION:
    403 # Determine what the selected Python implementation is and set
    404 # the Python build environment up for it.
    405 python_setup() {
    406 	debug-print-function ${FUNCNAME} "${@}"
    407 
    408 	unset EPYTHON
    409 
    410 	# support developer override
    411 	if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
    412 		local impls=( ${PYTHON_COMPAT_OVERRIDE} )
    413 		[[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-single-r1"
    414 
    415 		ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
    416 		ewarn "implementation will be used:"
    417 		ewarn
    418 		ewarn "	${PYTHON_COMPAT_OVERRIDE}"
    419 		ewarn
    420 		ewarn "Dependencies won't be satisfied, and PYTHON_SINGLE_TARGET flags will be ignored."
    421 
    422 		_python_export "${impls[0]}" EPYTHON PYTHON
    423 		_python_wrapper_setup
    424 		einfo "Using ${EPYTHON} to build"
    425 		return
    426 	fi
    427 
    428 	local impl
    429 	for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
    430 		if use "python_single_target_${impl}"; then
    431 			if [[ ${EPYTHON} ]]; then
    432 				eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python"
    433 				eerror "implementation. Please set it to just one value. If you need"
    434 				eerror "to override the value for a single package, please use package.env"
    435 				eerror "or an equivalent solution (man 5 portage)."
    436 				echo
    437 				die "More than one implementation in PYTHON_SINGLE_TARGET."
    438 			fi
    439 
    440 			_python_export "${impl}" EPYTHON PYTHON
    441 			_python_wrapper_setup
    442 			einfo "Using ${EPYTHON} to build"
    443 		fi
    444 	done
    445 
    446 	if [[ ! ${EPYTHON} ]]; then
    447 		eerror "No Python implementation selected for the build. Please set"
    448 		eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one"
    449 		eerror "of the following values:"
    450 		eerror
    451 		eerror "${_PYTHON_SUPPORTED_IMPLS[@]}"
    452 		echo
    453 		die "No supported Python implementation in PYTHON_SINGLE_TARGET."
    454 	fi
    455 }
    456 
    457 # @FUNCTION: python-single-r1_pkg_setup
    458 # @DESCRIPTION:
    459 # Runs python_setup.
    460 python-single-r1_pkg_setup() {
    461 	debug-print-function ${FUNCNAME} "${@}"
    462 
    463 	[[ ${MERGE_TYPE} != binary ]] && python_setup
    464 }
    465 
    466 _PYTHON_SINGLE_R1=1
    467 fi