Bug#757760: debian-policy: please document build profiles

Johannes Schauer Marin Rodrigues <[email protected]> Thu, 26 Mar 2026 17:25:00 +0100
Newsgroups gmane.linux.debian.devel.policy
Message-ID <177454230016.3821.6634664205660061631__39252.4498792895$1774542451$gmane$org@localhost>
Hi Sean,

Quoting Sean Whitton (2026-03-26 14:20:38)
> Thanks.  I think this means we need one more seconder of the combination of
> your patch plus these changes.  It might be helpful if you were to reroll
> your patch to include these changes.

yes, good idea. I took Helmut's last patch and change the things which I added
as a diff to the bottom of this mail to directly see the difference between
that version from Helmut and the new one. I attached the full final patch as
well and added you as another co-author.

Thanks!

cheers, josch

diff --git a/policy/ch-controlfields.rst b/policy/ch-controlfields.rst
index 738698c..508f6d3 100644
--- a/policy/ch-controlfields.rst
+++ b/policy/ch-controlfields.rst
@@ -1252,7 +1252,15 @@ This field occurs in the binary package sections of a source template
 control file. It expresses whether the binary package is being
 produced, given a set of enabled build profiles.  The condition uses
 the same `restriction formula syntax <s-restrictions>` from the
-``Build-Depends`` field.
+``Build-Depends`` field. In the following example, ``libglib2.0-tests``
+is only built if both ``noinsttest`` and ``nogir`` are not enabled:
+
+::
+
+    # Build if (!noinsttest) && (!nogir)
+    Package: libglib2.0-tests
+    Build-Profiles: <!noinsttest !nogir>
+
 
 If a binary package stanza in a source package template control file
 does not contain a ``Build-Profiles`` field, then it implicitly means
diff --git a/policy/ch-relationships.rst b/policy/ch-relationships.rst
index 89a8277..685d9df 100644
--- a/policy/ch-relationships.rst
+++ b/policy/ch-relationships.rst
@@ -76,6 +76,10 @@ build profile restriction formula in the field value. The non-empty sets
 of terms enclosed in either square or angle brackets must be separated
 by whitespace.
 
+A term can be prefixed with an optional exclamation mark and must
+consist only of lower case letters (``a-z``), digits (``0-9``), plus
+(``+``) and minus (``-``) signs, slashes (``/``) and periods (``.``).
+
 Architecture restriction lists and build profile restriction formulas
 are evaluated differently. Both can be evaluated to booleans, given a
 host architecture and a set of enabled build profiles. Their results
diff --git a/policy/ch-source.rst b/policy/ch-source.rst
index fed0468..f0286f0 100644
--- a/policy/ch-source.rst
+++ b/policy/ch-source.rst
@@ -629,8 +629,8 @@ order to make it work for your package.
 If the ``DEB_BUILD_PROFILES`` environment variable is defined during the
 build of a source package, it specifies which build profiles are
 enabled. Its value is a space-separated, unordered list of enabled build
-profile names. By default, no build profiles are enabled. The meaning of
-the following build profiles has been standardized:
+profile names. By default, no build profiles are enabled.
+The following build profiles are standard:
 
 ``nocheck``
     This profile extends the meaning of the ``nocheck`` tag in
@@ -640,7 +640,7 @@ the following build profiles has been standardized:
     during the build. Note that enabling the profile or the tag must not
     functionally change the emitted binary packages and also must not
     change the set of binary packages being produced. If tests happen to
-    be installed into a binary package, consider supporting the
+    be installed into a binary package, it is recommended to add the
     ``noinsttest`` build profile.
 
 ``noinsttest``
@@ -653,8 +653,8 @@ the following build profiles has been standardized:
     concurrently.  Therefore such dependencies tend to be conditional to
     ``<!nocheck> <!noinsttest>``.
 
-A larger list of commonly used build profiles can be found in the `Build
-Profile Spec
+Commonly used but non-standard build profiles can be found in
+the `Build Profile Spec
 <https://wiki.debian.org/BuildProfileSpec#Registered_profile_names>`_.
 
 The following makefile snippet is an example of how to enable python for
0001-document-build-profiles.patch (application/mbox, 12 KB)
From 3a517dbd7e698ed2c690d76334055a4311232487 Mon Sep 17 00:00:00 2001
From: Johannes Schauer Marin Rodrigues <[email protected]>
Date: Sat, 29 Mar 2025 23:04:56 +0100
Subject: [PATCH] document build profiles

Closes: #757760

Co-Authored-by: Helmut Grohne <[email protected]>
Co-Authored-by: Jochen Sprickerhof <[email protected]>
Co-Authored-by: Nattie Mayer-Hutchings <[email protected]>
Co-Authored-by: Sean Whitton <[email protected]>
Reviewed-by: Colin Watson <[email protected]>
---
 policy/ch-controlfields.rst |  19 ++++++
 policy/ch-relationships.rst | 131 +++++++++++++++++++++++++++++++-----
 policy/ch-source.rst        |  60 +++++++++++++++++
 3 files changed, 195 insertions(+), 15 deletions(-)

diff --git a/policy/ch-controlfields.rst b/policy/ch-controlfields.rst
index 3151816..738698c 100644
--- a/policy/ch-controlfields.rst
+++ b/policy/ch-controlfields.rst
@@ -152,6 +152,8 @@ The fields in the binary package stanzas are:
 
 -  :ref:`Package-Type <s-f-Package-Type>`
 
+-  :ref:`Build-Profiles <s-f-Build-Profiles>`
+
 The syntax and semantics of the fields are described below.
 
 These fields are used by ``dpkg-gencontrol`` to generate control files
@@ -1243,6 +1245,23 @@ or set it to ``binary-targets`` if it has been requested to test
 whether the package it builds correctly implements the fall-back for
 legacy builders.
 
+``Build-Profiles``
+~~~~~~~~~~~~~~~~~~
+
+This field occurs in the binary package sections of a source template
+control file. It expresses whether the binary package is being
+produced, given a set of enabled build profiles.  The condition uses
+the same `restriction formula syntax <s-restrictions>` from the
+``Build-Depends`` field.
+
+If a binary package stanza in a source package template control file
+does not contain a ``Build-Profiles`` field, then it implicitly means
+that it builds unconditionally with respect to build profiles.  If a
+binary package stanza in a source package template control file is
+annotated with a ``Build-Profiles`` field, then that binary package is
+generated if and only if the condition expressed by field's value
+evaluates to true.
+
 Remarks
 ^^^^^^^
 
diff --git a/policy/ch-relationships.rst b/policy/ch-relationships.rst
index fb9dae8..89a8277 100644
--- a/policy/ch-relationships.rst
+++ b/policy/ch-relationships.rst
@@ -51,22 +51,73 @@ For example, a list of dependencies might appear as:
     Version: 1.3.17-1
     Depends: libc6 (>= 2.2.1), default-mta | mail-transport-agent
 
-Relationships may be restricted to a certain set of architectures. This
-is indicated in brackets after each individual package name and the
-optional version specification. The brackets enclose a non-empty list of
-Debian architecture names in the format described in
-:ref:`s-arch-spec`, separated by whitespace. Exclamation
-marks may be prepended to each of the names. (It is not permitted for
-some names to be prepended with exclamation marks while others aren't.)
+.. _s-restrictions
+
+Restrictions
+~~~~~~~~~~~~
+
+Relationships may be restricted to a certain set of architectures or
+build profiles. This is indicated in brackets after each individual
+package name and the optional version specification. There are two types
+of restrictions.  Architecture restriction lists are enclosed in a pair
+of opening and closing square brackets, the specifics of which are
+`described below <s-architecture-restrictions>`. Build profile
+restriction lists are enclosed by pairs of opening and closing angle
+brackets and are also `described in detail below
+<s-profile-restrictions>`.
+
+There can be at most one architecture restriction list per dependency
+alternative, but there can be more than one build profile restriction
+list. One or more build profile restriction lists form a build profile
+restriction formula. If both an architecture restriction list and a
+build profile restriction formula are to be applied to a dependency
+alternative, then the architecture restriction list must come before the
+build profile restriction formula in the field value. The non-empty sets
+of terms enclosed in either square or angle brackets must be separated
+by whitespace.
+
+Architecture restriction lists and build profile restriction formulas
+are evaluated differently. Both can be evaluated to booleans, given a
+host architecture and a set of enabled build profiles. Their results
+indicate whether the dependency alternative should be considered or
+ignored. For a dependency alternative to be considered, the architecture
+restriction list (if any) and the build profile restriction formula (if
+any) must evaluate to true. A dependency is ignored if none of its
+alternatives apply.
+
+The sense in which a dependency is ignored depends on the field in which
+the restriction appears.  A restriction in one of the build relationship
+fields (``Build-Depends``...) that does not match means that the
+build-dependency is not required to be satisfied for the package to be
+built.  For example, a restriction might specify that building a package
+on a certain architecture requires an additional dependency; such a
+restriction does not match on other architectures, meaning the package
+can be built there without first installing that additional dependency.
+
+A restriction appearing in a field describing relationships between
+binary packages (such as ``Depends``) must only appear in the source
+package template control file ``debian/control``.  The dependency is
+ignored, in the sense that it will not appear in the corresponding
+binary package control file, if the restriction does not match.
+
+.. _s-architecture-restrictions
+
+Architecture restrictions
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Architecture restriction lists consist of Debian :ref:`architecture
+specification strings <s-arch-spec>`.  Exclamation marks may be
+prepended to each of the names. (It is not permitted for some names to
+be prepended with exclamation marks while others aren't.)
 
 For build relationship fields (``Build-Depends``,
 ``Build-Depends-Indep``, ``Build-Depends-Arch``, ``Build-Conflicts``,
 ``Build-Conflicts-Indep`` and ``Build-Conflicts-Arch``), if the current
 Debian host architecture is not in this list and there are no
 exclamation marks in the list, or it is in the list with a prepended
-exclamation mark, the package name and the associated version
-specification are ignored completely for the purposes of defining the
-relationships.
+exclamation mark, the restriction list evaluates to false.  This means
+that the package name and the associated version specification are
+ignored completely for the purposes of defining the relationships.
 
 For example:
 
@@ -134,11 +185,61 @@ is equivalent to ``foo`` on architectures using the Linux kernel and any
 cpu, ``bar`` on architectures using any kernel and an i386 cpu, and
 ``baz`` on any architecture using a kernel other than Linux.
 
-Note that the binary package relationship fields such as ``Depends``
-appear in one of the binary package stanzas of the template control file,
-whereas the build-time relationships such as ``Build-Depends`` appear in
-the source package stanza of the template control file (which is the first
-section).
+.. _s-profile-restrictions
+
+Build profile restriction formulas
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A build profile restriction formula is a sequence of build profile
+restriction lists. In contrast, there must not be more than one
+architecture restriction list per dependency alternative.  Each list
+is enclosed in angle brackets (less than sign and greater than
+sign). Each of the space-separated terms of a restriction list is the
+possibly-negated name of a build profile. Negation happens by
+prefixing the name with an exclamation mark. Unlike architecture
+restriction lists, positive and negative terms may be mixed.
+
+A restriction formula may be evaluated as a disjunctive normal form
+expression, given a set of :ref:`enabled build profiles
+<s-rules-build-profiles>`. In other words, each term within a
+restriction list is AND-ed together while the restriction lists in a
+restriction formula are OR-ed together. Therefore, the order of terms
+within restriction lists and the order of restriction lists within a
+restriction formula does not matter. A profile name in a term
+evaluates to "true" if the profile with its name is enabled for the
+build and to "false" otherwise. The result may be negated by
+prefixing the profile name with an exclamation mark.
+
+In the following example, the package would depend on ``foo`` when built
+for ``i386`` or 32-bit ARM architectures and if one of the ``nocheck``
+and ``cross`` profiles is not enabled by the builder:
+
+::
+
+    Build-Depends: foo (>= 1.0) [i386 any-arm] <!nocheck> <!cross>, bar
+
+In the following example, the source package would build-depend on
+``foo`` only if both the ``nocheck`` profile and the ``cross`` profile
+are enabled at the same time.
+
+::
+
+    Build-Depends: foo <nocheck cross>
+
+In the next example, the source package would build-depend on ``foo`` if
+``nopython`` is disabled and at least one of ``nocheck`` and
+``noinsttest`` is disabled.
+
+::
+
+    Build-Depends: foo <!nopython !nocheck> <!nopython !noinsttest>
+
+The last example can also be rewritten to this alternative form which is
+equal in meaning:
+
+::
+
+    Build-Depends: foo <!nopython !nocheck>, foo <!nopython !noinsttest>
 
 .. _s-binarydeps:
 
diff --git a/policy/ch-source.rst b/policy/ch-source.rst
index a2aa4cc..fed0468 100644
--- a/policy/ch-source.rst
+++ b/policy/ch-source.rst
@@ -621,6 +621,66 @@ order to make it work for your package.
             # Code to run the package test suite.
     endif
 
+.. _s-rules-build-profiles
+
+``debian/rules`` and ``DEB_BUILD_PROFILES``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the ``DEB_BUILD_PROFILES`` environment variable is defined during the
+build of a source package, it specifies which build profiles are
+enabled. Its value is a space-separated, unordered list of enabled build
+profile names. By default, no build profiles are enabled. The meaning of
+the following build profiles has been standardized:
+
+``nocheck``
+    This profile extends the meaning of the ``nocheck`` tag in
+    ``DEB_BUILD_OPTIONS`` and must not be enabled unless combined with
+    that tag. In addition to disabling build-time testing, it allows
+    skipping the installation of dependencies required for those tests
+    during the build. Note that enabling the profile or the tag must not
+    functionally change the emitted binary packages and also must not
+    change the set of binary packages being produced. If tests happen to
+    be installed into a binary package, consider supporting the
+    ``noinsttest`` build profile.
+
+``noinsttest``
+    This profile disables the emission of binary packages consisting
+    entirely of automated tests, manual tests, example/demo programs,
+    and test tools. Other packages must not functionally change when
+    this profile is enabled. Note that in many cases, it is only
+    possible to drop such dependencies used for building when enabling
+    both the ``noinsttest`` and the ``nocheck`` build profile
+    concurrently.  Therefore such dependencies tend to be conditional to
+    ``<!nocheck> <!noinsttest>``.
+
+A larger list of commonly used build profiles can be found in the `Build
+Profile Spec
+<https://wiki.debian.org/BuildProfileSpec#Registered_profile_names>`_.
+
+The following makefile snippet is an example of how to enable python for
+all builds except when the package is built with the ``nopython`` build
+profile active.
+
+.. code-block:: Makefile
+
+    ifneq ($(filter nopython,$(DEB_BUILD_PROFILES)),)
+        # nopython build profile was activated -- disable python
+        CONFIGURE_SWITCHES += --disable-python
+    else
+        CONFIGURE_SWITCHES += --enable-python
+    endif
+
+Alternatively, one may defer the evaluation of restriction formulas in
+general (including architecture restrictions) to ``debhelper``.
+
+.. code-block:: Makefile
+
+    ifneq ($(filter foo,$(shell dh_listpackages)),)
+        # foo is being built
+        CONFIGURE_SWITCHES += --enable-foo
+    else
+        CONFIGURE_SWITCHES += --disable-foo
+    endif
 
 .. _s-debianrules-gainrootapi:
 
-- 
2.47.3
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEElFhU6KL81LF4wVq58sulx4+9g+EFAmnFXdsACgkQ8sulx4+9
g+GtkBAAjmM1LvDQ5LtTTl4Qy0o2ix/E+tVuvi6lW+i2IEoZvr5g/fpMot4XXCIM
NzlxsSojp4l5rBwfWjBFKd8/ReRGW12hskZHV2At01z7NRGDm38y1XRubqOapGnB
ri0/teTddp/f0k51QxHAyqtA8nXdEo7uJRVOuLYiB64w12u1fe+IAJBuzzKJsgkn
WDd2dwUlNH9z8W538N8SFVTA3ug2Qb2XKVwCeMyGVF4fbPU0nW+d3Gfa1Nsvg5KA
X2RPXrP6qBf7Uh1ljGWoc71g266doP5aArslxZGOMq1eatP6GLcGBUbv156b6hjn
CtGlJ0+liK1LGqthzfpU3B8kRfj4DZ9Y/dK2lTjFBSC2MYJllPgGWeUPMtDYkcte
+zWOsiWp16+oew2CsKlzr0ldyPI2o3vE+y63jtUUIMkqusDUnrulEDDIxaZ0x2Ap
PcKAGalLlQ2OJayvzgZoOJ5OSlA19aT5KODffhtoiNb7k+Idig0rsmKlWz/YVDg0
p0XaCKOX2eo6sgxqmY/Br4hvZoOMd4PTzmekdrXJ5APLI6Tjaiq8kRNBa3pVYiBX
pNTpuo/j2gbUHVFr+tZ5IJWIIb2uf90ZpusYsnAdRjSKEVaXZTHh/QqVDKYX8E/I
UL+om+SY9BOTTexUH6DD8U7HQZqCn1psygW+CJlTxRz7BgEyyr4=
=Qz8n
-----END PGP SIGNATURE-----