From be55691ed16c2ab4dd7c3d635fc2bd67ecd6b563 Mon Sep 17 00:00:00 2001 From: Thomas Bracht Laumann Jespersen Date: Fri, 15 Apr 2022 23:42:03 +0200 Subject: eclass-writing: doc inherit guards, EXPORT_FUNCTIONS warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a section to explain what inherit guards are and their usage, and add a "rule of thumb" to put EXPORT_FUNCTIONS at the end of eclasses for max portability. This turned into a larger re-ordering of the sections so the full jmake example can showcase all the features discussed in the preceding sections, like EAPI guard, inherit guard, and EXPORT_FUNCTIONS at the very end. Signed-off-by: Thomas Bracht Laumann Jespersen Signed-off-by: Ulrich Müller --- eclass-writing/text.xml | 156 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 122 insertions(+), 34 deletions(-) (limited to 'eclass-writing') diff --git a/eclass-writing/text.xml b/eclass-writing/text.xml index f0f03c0..22b973f 100644 --- a/eclass-writing/text.xml +++ b/eclass-writing/text.xml @@ -638,11 +638,11 @@ eclass-defined defaults for example, say we had fnord.eclass:

-EXPORT_FUNCTIONS src_compile - fnord_src_compile() { do_stuff || die } + +EXPORT_FUNCTIONS src_compile

@@ -659,6 +659,115 @@ src_compile() { } +

+Eclasses may inherit other eclasses to make use of their functionality, and +historically there have been instances of eclasses calling +EXPORT_FUNCTIONS and then inheriting another eclass. As inherited +eclasses may also execute EXPORT_FUNCTIONS, it was not fully defined +which defaults should take effect. The general recommendation is now that +eclasses should not inherit other eclasses after calling +EXPORT_FUNCTIONS. +

+ + + + +
+Inherit guards + + +

+It is common practice to surround the main contents of an eclass with an +"inherit guard". Much like header guards known from C, inherit guards help +ensure that an eclass can be inherited multiple times and have its functions and +variables defined only once. An inherit guard is only needed for an eclass that +can be inherited more than once. +

+ +

+A typical inherit guard looks as follows (for a hypothetical foo.eclass): +

+ + +if [[ -z ${_FOO_ECLASS} ]]; then +_FOO_ECLASS=1 + +# Variables and functions go here + +fi + + +

+When it comes to EXPORT_FUNCTIONS and inherit guards, the call to +EXPORT_FUNCTIONS must be placed at the very end of the eclass +outside any inherit guards, like this: +

+ + +if [[ -z ${_FOO_ECLASS} ]]; then +_FOO_ECLASS=1 + +foo_src_compile() { + ... +} +fi + +EXPORT_FUNCTIONS src_compile + + +

+This helps to ensure that the last inherited eclass gets to define the default +phase functions. Consider two eclasses foo.eclass and bar.eclass +that define the same default phase function via EXPORT_FUNCTIONS. If an +ebuild inherits both as inherit foo bar, then the default phases are +defined by bar.eclass. If foo.eclass is then modified to inherit +bar as well, then the ebuild's default functions could suddenly become +those from foo if EXPORT_FUNCTIONS was placed inside the inherit +guard. +

+ + +The rule of thumb here is: put the call (if any) to EXPORT_FUNCTIONS in +the last line of an eclass, outside of any inherit guards. + + + +Old eclasses may put EXPORT_FUNCTIONS in other places, even before +inherit. They should not blindly be updated to follow the +recommended pattern here, as it could result in significant breakage. + + + +
+ +
+Handling incorrect usage of an eclass + + +

+Sometimes an eclass is used incorrectly by an ebuild and the eclass +knows it is being used incorrectly the common example is an +eclass that only works with a specific set of EAPIs, but is being +accessed (inherited) by an ebuild with a different EAPI. +In those cases, used sparingly as a last resort, it is allowed +for an eclass to invoke die from the global scope. For example: +

+ + +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: eapi-die.eclass +# @MAINTAINER: +# Gentoo Devmanual Project <devmanual@gentoo.org> +# @SUPPORTED_EAPIS: 7 8 +# @BLURB: Calls die when used with an invalid EAPI. + +case ${EAPI} in + 7|8) ;; + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; +esac +
@@ -674,7 +783,7 @@ functions.

-# Copyright 1999-2021 Gentoo Authors +# Copyright 1999-2022 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: jmake.eclass @@ -688,7 +797,13 @@ functions. # (hypothetical) jmake build system along with default src_configure and # src_compile phase functions -EXPORT_FUNCTIONS src_configure src_compile +case ${EAPI} in + 7|8) ;; + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; +esac + +if [[ -z ${_JMAKE_ECLASS} ]]; then +_JMAKE_ECLASS=1 BDEPEND=">=sys-devel/jmake-2" @@ -725,40 +840,13 @@ jmake-build() { jmake_src_compile() { jmake-build || die "build failed" } +fi + +EXPORT_FUNCTIONS src_configure src_compile -
-Handling incorrect usage of an eclass - - -

-Sometimes an eclass is used incorrectly by an ebuild and the eclass -knows it is being used incorrectly the common example is an -eclass that only works with a specific set of EAPIs, but is being -accessed (inherited) by an ebuild with a different EAPI. -In those cases, used sparingly as a last resort, it is allowed -for an eclass to invoke die from the global scope. For example: -

- - -# Copyright 1999-2021 Gentoo Authors -# Distributed under the terms of the GNU General Public License v2 - -# @ECLASS: eapi-die.eclass -# @MAINTAINER: -# Gentoo Devmanual Project <devmanual@gentoo.org> -# @SUPPORTED_EAPIS: 7 8 -# @BLURB: Calls die when used with an invalid EAPI. - -case ${EAPI} in - 7|8) ;; - *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; -esac - - -
-- cgit v1.2.3-65-gdbad