Hi Sean, thank you for your review. Please excuse the delay of our response. I happened to run into Nattie again and she helped me a lot in improving the text in combination with your remarks. Also Colin reviewed it and Stefano Rivera helped on a few paragraphs.
On Sun, Jun 01, 2025 at 11:12:31AM +0100, Sean Whitton wrote: > > +``Build-Profiles`` > > +~~~~~~~~~~~~~~~~~~ > > + > > +Specifies the condition for which that binary package does or does not > > +build. > > ... when it doesn't have any FTBFS bugs? :) > > How about > > Build profiles are <succinct description>. This field expresses > just when the binary package builds, with respect to active and > inactive build profiles. This condition is expressed using the > `restriction formula syntax <s-restrictions>` ... We found the paragraph hard to read, agreed with your criticism and significantly rephrased it. > > + 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 the > > + disjunctive normal form expression evaluates to true. > > I know what disjunctive normal form means but I don't think Policy > defines it and I'm not sure it is necessary to mention it here. > Why not just say > > If a binary package stanza in a source package template control file > has a ``Build-Profiles`` field, then that binary package is > generated if and only if the condition expressed by the field's > value holds. We do explain disjuntive normal form later. Indeed there is little value in mentioning it here. > > + > > --- a/policy/ch-relationships.rst > > +++ b/policy/ch-relationships.rst > > @@ -51,22 +51,76 @@ 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 rectangular brackets, specifics of which are > > +`described below <s-architecture-restrictions>`. > > "*the* specifics of which" Yes, thanks > > +Build profile > > +restriction lists are enclosed by pairs of opening and closing angular > > +brackets and are further `described below as well > > +<s-profile-restrictions>`. > > s/further described below as well/also described in detail below/ > > Also, I'd suggest a paragraph break after this sentence. Yes, both, thanks. > > +There can only be at most one architecture > > +restriction list per package > > Per binary package, right? I found that ambiguous as well and went for "dependency alternative" instead. Hope that also makes sense to you and others. > > 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 as well as a build profile restriction formula are to > > +be applied to a dependency, then the architecture restriction list must > > +come before the build profile restriction formula. > > "... must come before the build profile restriction formula *in the field > value*." Yes, thanks. > > The non-empty set of > > +terms enclosed in either rectangular or angular brackets are separated > > +by whitespace. > > This doesn't make sense -- the singular non-empty set has a plural "are > separated". What do you mean? It's the set that should have been plural and the sets that should be separated. Thank you. > > +Architecture restriction lists and build profile restriction formulas > > +are evaluated differently but they both evaluate to a boolean decision > > +as to whether the dependency that the restriction was applied to is > > +being kept or should be ignored. > > "as to whether the dependency to which the restriction is applied should > be kept or ignored." Rewritten instead. > > For a dependency to be ignored, it is > > +enough for either the architecture restriction list or the build profile > > +restriction formula to evaluate to false. If the dependency with a > > +restriction is part of a set of alternatives, the alternative for which > > +either restriction does not apply is ignored and the other alternatives > > +remain for evaluation. > > "remain for evaluation" seems vague. > > I think you are trying to capture how a system consuming these files is > allowed to consider only the first alternative? > > Could you just say that each restriction applies separately to each > alternative? You are not the only one being confused. Rewritten. Thanks. > > +A dependency with an architecture restriction list or build profile > > +restriction formula in one of the build relationship fields > > +(``Build-Depends``, ``Build-Depends-Indep``, ``Build-Depends-Arch``, > > +``Build-Conflicts``, ``Build-Conflicts-Indep`` and > > +``Build-Conflicts-Arch``) which does not not match will result in that > > +build dependency to be ignored. If the dependency is used for binary > > +relationship fields and the ``Built-Using`` field, the architecture and > > +build profile restriction syntax is only supported in the source package > > +template control file ``debian/control``. When the corresponding binary > > +package control file is generated, the relationship will either be > > +omitted or included with neither the architecture restriction nor the > > +build profile restriction formula. > > This is very dense, let me suggest something like > > 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 specifying that > building a package on a certain architecture requires an additional > dependency doesn't 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 appear in only 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 [right?]. Thank you. Accepted with minor changes. > > +Build profile restriction formulas > > +^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > + > > +In contrast to architecture restriction lists, of which at most one can > > +be added to a dependency, build profile restriction formulas consist of > > +multiple restriction lists. > > It would be good to rewrite this using must/must > not/required/prohibited -- the Policy normative magic words. Significantly rephrased. > > Each list is enclosed in angular brackets > > +(less than sign and greater than sign). Each of the space separated > > +terms of a restriction list is the optionally negated name of a build > > +profile. > > "Each of the space-separated terms of a restriction list is the > possibly-negated name of a build profile." Yes, thanks. > > Negation happens by prefixing the name with an exclamation > > +mark. In contrast to architecture restriction lists, positive and > > +negative terms can be mixed. > > "may be mixed" to use the Policy normative magic words. Yes, thanks. > > +One or more restriction lists form a restriction formula. A restriction > > +formula can be evaluated as a disjunctive normal form expression. This > > +is, each term within a restriction list is AND-ed together while the > > +restriction lists in a restriction formula are OR-ed together. This also > > +means that 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 the same > > +name was set for the build and to "false" otherwise. Optional negation > > +with an exclamation mark is applied before evaluating conjunctions and > > +disjunctions. > > I think that the sense of "set for the build" should be explained. > Indeed, it would be good to just describe what build profiles are before > getting into how they are evaluated. What sort of things are they used > for? How do they help with bootstrapping? > Probably you want to refer to "debian/rules and DEB_BUILD_PROFILES" and > put the general introduction there. The reference definitely makes sense and I readily added it. We further rephrased it to improve readability, but I disagree about going into bootstrapping here as build profiles are a wider concept applicable way beyond bootstrapping. > > +``debian/rules`` and ``DEB_BUILD_PROFILES`` > > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > + > > +The environment variable ``DEB_BUILD_PROFILES`` may be set to a space > > +separated unordered list of build profiles that are active for this > > +build. All build profiles not listed in that variable are considered > > +disabled and therefore no build profiles are enabled by default. The > > +meaning of the following build profiles has been standardized: > > Please rewrite this intro using the normative words. I was struggling to see how this is not normative. Nevertheless, we found it difficult to read and rephrased it hoping that you may find it more normative now. > Policy can standardise them, here. I'm not sure what you want me to change here. > > +``nocheck`` > > + This profile extends the meaning of the ``nocheck`` tag in > > + ``DEB_BUILD_OPTIONS`` and may only be enabled in combination with > > + setting 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 neither the profile nor the tag > > + may functionally change the emitted binary packages nor the set of > > + binary packages. If tests happen to be installed into a binary > > + package, consider supporting the ``noinsttest`` build profile. > > + > > +``noinsttest`` > > + Disable binary packages consisting entirely of automated tests, > > + manual tests, example/demo programs and test tools. Other packages > > + may not functionally change when this profile is enabled. Note that > > + dependencies used for building these tests often con only be dropped > > + when enabling both the ``noinsttest`` and the ``nocheck`` build > > + profile and therefore such dependencies tend to be conditional to > > + ``<!nocheck> <!noinsttest>``. > > These should probably be rewritten using the normative words, too. Rephrased, thanks. As much as we may continue word smithing this text, I suggest that the perfect is the enemy of the good. By now, not having this text in policy seems worse to me than having a buggy description of build profiles. Helmut
>From 17d3b9a27b5edb707d1ef1e170f6c3a6f5df76a6 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]> 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 9f06cc9..b492790 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 @@ -1251,6 +1253,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..dfce035 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 considered satisfied 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 +``nopython`` 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

