public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Ulrich Müller" <ulm@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/devmanual:master commit in: eclass-writing/
Date: Sun, 24 Apr 2022 12:52:28 +0000 (UTC)	[thread overview]
Message-ID: <1650804713.be55691ed16c2ab4dd7c3d635fc2bd67ecd6b563.ulm@gentoo> (raw)

commit:     be55691ed16c2ab4dd7c3d635fc2bd67ecd6b563
Author:     Thomas Bracht Laumann Jespersen <t <AT> laumann <DOT> xyz>
AuthorDate: Fri Apr 15 21:42:03 2022 +0000
Commit:     Ulrich Müller <ulm <AT> gentoo <DOT> org>
CommitDate: Sun Apr 24 12:51:53 2022 +0000
URL:        https://gitweb.gentoo.org/proj/devmanual.git/commit/?id=be55691e

eclass-writing: doc inherit guards, EXPORT_FUNCTIONS warning

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 <t <AT> laumann.xyz>
Signed-off-by: Ulrich Müller <ulm <AT> gentoo.org>

 eclass-writing/text.xml | 156 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 122 insertions(+), 34 deletions(-)

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 <d/> for example, say we had <c>fnord.eclass</c>:
 </p>
 
 <codesample lang="ebuild">
-EXPORT_FUNCTIONS src_compile
-
 fnord_src_compile() {
 	do_stuff || die
 }
+
+EXPORT_FUNCTIONS src_compile
 </codesample>
 
 <p>
@@ -659,6 +659,115 @@ src_compile() {
 }
 </codesample>
 
+<p>
+Eclasses may inherit other eclasses to make use of their functionality, and
+historically there have been instances of eclasses calling
+<c>EXPORT_FUNCTIONS</c> and then inheriting another eclass. As inherited
+eclasses may also execute <c>EXPORT_FUNCTIONS</c>, it was not fully defined
+which defaults should take effect. The general recommendation is now that
+eclasses should not inherit other eclasses <e>after</e> calling
+<c>EXPORT_FUNCTIONS</c>.
+</p>
+
+</body>
+</section>
+
+<section>
+<title>Inherit guards</title>
+<body>
+
+<p>
+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.
+</p>
+
+<p>
+A typical inherit guard looks as follows (for a hypothetical <c>foo.eclass</c>):
+</p>
+
+<codesample lang="ebuild">
+if [[ -z ${_FOO_ECLASS} ]]; then
+_FOO_ECLASS=1
+
+# Variables and functions go here
+
+fi
+</codesample>
+
+<p>
+When it comes to <c>EXPORT_FUNCTIONS</c> and inherit guards, the call to
+<c>EXPORT_FUNCTIONS</c> must be placed at the very end of the eclass
+<e>outside</e> any inherit guards, like this:
+</p>
+
+<codesample lang="ebuild">
+if [[ -z ${_FOO_ECLASS} ]]; then
+_FOO_ECLASS=1
+
+foo_src_compile() {
+	...
+}
+fi
+
+EXPORT_FUNCTIONS src_compile
+</codesample>
+
+<p>
+This helps to ensure that the last inherited eclass gets to define the default
+phase functions. Consider two eclasses <c>foo.eclass</c> and <c>bar.eclass</c>
+that define the same default phase function via <c>EXPORT_FUNCTIONS</c>. If an
+ebuild inherits both as <c>inherit foo bar</c>, then the default phases are
+defined by <c>bar.eclass</c>. If <c>foo.eclass</c> is then modified to inherit
+<c>bar</c> as well, then the ebuild's default functions could suddenly become
+those from <c>foo</c> if <c>EXPORT_FUNCTIONS</c> was placed inside the inherit
+guard.
+</p>
+
+<note>
+The rule of thumb here is: put the call (if any) to <c>EXPORT_FUNCTIONS</c> in
+the last line of an eclass, outside of any inherit guards.
+</note>
+
+<warning>
+Old eclasses may put <c>EXPORT_FUNCTIONS</c> in other places, even before
+<c>inherit</c>. They should <e>not</e> blindly be updated to follow the
+recommended pattern here, as it could result in significant breakage.
+</warning>
+
+</body>
+</section>
+
+<section>
+<title>Handling incorrect usage of an eclass</title>
+<body>
+
+<p>
+Sometimes an eclass is used incorrectly by an ebuild and the eclass
+knows it is being used incorrectly <d/> 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:
+</p>
+
+<codesample lang="ebuild">
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: eapi-die.eclass
+# @MAINTAINER:
+# Gentoo Devmanual Project &lt;devmanual@gentoo.org&gt;
+# @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
+</codesample>
 </body>
 </section>
 
@@ -674,7 +783,7 @@ functions.
 </p>
 
 <codesample lang="ebuild">
-# 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="&gt;=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
 </codesample>
 
 </body>
 </section>
 
-<section>
-<title>Handling incorrect usage of an eclass</title>
-<body>
-
-<p>
-Sometimes an eclass is used incorrectly by an ebuild and the eclass
-knows it is being used incorrectly <d/> 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:
-</p>
-
-<codesample lang="ebuild">
-# Copyright 1999-2021 Gentoo Authors
-# Distributed under the terms of the GNU General Public License v2
-
-# @ECLASS: eapi-die.eclass
-# @MAINTAINER:
-# Gentoo Devmanual Project &lt;devmanual@gentoo.org&gt;
-# @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
-</codesample>
-</body>
-</section>
 </chapter>
 </guide>


             reply	other threads:[~2022-04-24 12:52 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-24 12:52 Ulrich Müller [this message]
  -- strict thread matches above, loose matches on Subject: below --
2024-04-29  6:31 [gentoo-commits] proj/devmanual:master commit in: eclass-writing/ Ulrich Müller
2024-04-29  6:31 Ulrich Müller
2024-04-29  6:31 Ulrich Müller
2024-04-29  6:31 Ulrich Müller
2024-01-19 21:06 Ulrich Müller
2023-08-26  5:30 Ulrich Müller
2023-05-27 18:49 Ulrich Müller
2022-04-30 17:01 Ulrich Müller
2022-04-28  8:12 Ulrich Müller
2022-03-26 16:16 Ulrich Müller
2022-03-23 14:10 Ulrich Müller
2022-03-20 13:48 Ulrich Müller
2022-03-18 18:10 Sam James
2022-03-18 18:10 Sam James
2022-03-16 14:47 Sam James
2022-03-16 14:47 Sam James
2021-12-09  5:01 Sam James
2021-10-13 13:44 Ulrich Müller
2021-09-04 10:38 Ulrich Müller
2021-09-04 10:36 Ulrich Müller
2021-09-04 10:36 Ulrich Müller
2021-09-04 10:33 Ulrich Müller
2021-09-04 10:33 Ulrich Müller
2021-04-07 17:35 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2021-03-30  6:55 Ulrich Müller
2020-12-29 22:08 Göktürk Yüksek
2020-09-18  7:01 Ulrich Müller
2019-09-20 22:52 Göktürk Yüksek
2019-08-30 15:51 Göktürk Yüksek
2019-08-30 15:51 Göktürk Yüksek
2016-10-31  1:21 Göktürk Yüksek
2016-10-31  1:21 Göktürk Yüksek
2016-10-31  1:21 Göktürk Yüksek
2016-10-31  1:21 Göktürk Yüksek
2016-10-31  1:21 Göktürk Yüksek
2011-12-13 20:17 Petteri Räty

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1650804713.be55691ed16c2ab4dd7c3d635fc2bd67ecd6b563.ulm@gentoo \
    --to=ulm@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox