From 7ee49f6c892d6057b9a0d2f9eb84ff0f35d1d436 Mon Sep 17 00:00:00 2001
From: Russ Allbery <rra@debian.org>
Date: Tue, 20 Sep 2022 19:11:54 -0700
Subject: [PATCH] Improve alternative build dependency discussion

Alternatives in build dependencies are normally (except for
backports) handled specially by autobuilders to try to maintain
consistent builds.  This was documented in Policy, but in a
footnote that people often didn't see.

Move this text into the main body of the discussion of build
dependencies and reword it for additional clarity.  Add a pointer
to this discussion where alternative dependencies are introduced.
---
 policy/ch-relationships.rst | 61 +++++++++++++++++++++++++++----------
 1 file changed, 45 insertions(+), 16 deletions(-)

diff --git a/policy/ch-relationships.rst b/policy/ch-relationships.rst
index 5074428..ffafbf1 100644
--- a/policy/ch-relationships.rst
+++ b/policy/ch-relationships.rst
@@ -15,7 +15,10 @@ control fields of the package, which declare dependencies on other
 packages, the package names listed may also include lists of alternative
 package names, separated by vertical bar (pipe) symbols ``|``. In such a
 case, that part of the dependency can be satisfied by any one of the
-alternative packages.  [#]_
+alternative packages. (Alternative dependencies in ``Build-Depends``,
+``Build-Depends-Indep``, and ``Build-Depends-Arch`` are interpreted
+specially by Debian autobuilders. See :ref:`Relationships between source
+and binary packages <s-sourcebinarydeps>` for more details.)
 
 All of the fields may restrict their applicability to particular versions
 of each named package. This is done in parentheses after each individual
@@ -620,6 +623,47 @@ earlier for binary packages) in order to invoke the targets in
     ``Build-Conflicts-Arch`` fields must be satisfied when these targets
     are invoked.
 
+Alternative dependencies are allowed in the ``Build-Depends``,
+``Build-Depends-Indep``, and ``Build-Depends-Arch`` fields, but Debian's
+autobuilders normally discard the dependencies after the first. This is
+done to give alternative dependencies a consistent interpretation that
+reduces the risk of inconsistencies between repeated builds. If, for
+example, the first-listed dependency would normally be available but is
+temporarily not installable, the autobuilder fails rather than install a
+subsequent dependency that may significantly change the behavior of the
+package.
+
+More specifically, Debian autobuilders perform the following
+transformation on alternative dependencies in the ``Build-Depends``,
+``Build-Depends-Indep``, and ``Build-Depends-Arch`` fields:
+
+#. Discard any alternatives that are restricted to architectures that do
+   not match the host architecture.
+#. Discard any alternatives specifying different package names than the
+   now-first alternative. (Alternatives specifying the same package name
+   are kept to permit relationships such as ``foo (<= x) | foo (>= y)``.)
+
+For example, an autobuilder for the ``amd64`` architecture would treat the
+following dependency::
+
+    foo-special [armhf] | foo (<= 4) | foo (>= 4.2) | bar
+
+as if it were::
+
+    foo (<= 4) | foo (>= 4.2)
+
+The normal effect is to use only the first alternative that is valid on
+the relevant architecture and fail if that alternative is not installable.
+
+While this rule for build dependencies may limit the usefulness of
+alternatives, they can still be used to provide flexibility when building
+the package outside of Debian's autobuilders.
+
+The autobuilders for the Debian backports and experimental suites do not
+perform this transformation and instead use the same dependency resolution
+rules as normal package installations to choose which alternative
+dependency to install.
+
 .. _s-built-using:
 
 Additional source packages used to build the binary - ``Built-Using``
@@ -666,21 +710,6 @@ requirements to retain the referenced source packages.  It should not
 be added solely as a way to locate packages that need to be rebuilt
 against newer versions of their build dependencies.
 
-.. [#]
-   While ``Build-Depends``, ``Build-Depends-Indep`` and
-   ``Build-Depends-Arch`` permit the use of alternative dependencies,
-   those are only used for the backports suite on the Debian autobuilders.
-   On the other suites, after reducing any architecture-specific restrictions
-   for the build architecture in question, all but the first alternative are
-   discarded except if the alternative is the same package name as the first.
-   The latter exception is useful to specify version ranges like
-   ``foo (rel x) | foo (rel y)``. This is to reduce the risk of inconsistencies
-   between repeated rebuilds.  While this may limit the usefulness of
-   alternatives in a single release, they can still be used to provide
-   flexibility in building the same package across multiple
-   distributions or releases, where a particular dependency is met by
-   differently named packages.
-
 .. [#]
    The relations ``<`` and ``>`` were previously allowed, but they were
    confusingly defined to mean earlier/later or equal rather than
-- 
2.40.1

