[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#749826: Documenting `Multi-Arch: foreign`



Hello,

On Sun 06 Apr 2025 at 07:27am +02, Helmut Grohne wrote:

> Updated patch attached.

Thanks very much.  Here's a review.

> diff --git a/policy/ch-controlfields.rst b/policy/ch-controlfields.rst
> index 3151816..0e7d489 100644
> --- a/policy/ch-controlfields.rst
> +++ b/policy/ch-controlfields.rst
> @@ -1307,6 +1307,154 @@ This list is intentionally incomplete. You should consult the
>  documentation of the tool or package in question for which keywords it
>  defines and when they are needed.
>
> +.. _s-f-Multi-Arch:
> +
> +``Multi-Arch``
> +~~~~~~~~~~~~~~
> +
> +A Debian installation may combine packages from multiple architectures.
> +The ``Multi-Arch`` header enables individual packages to declare their
> +support for this feature. It may occur only in the control file of a
> +binary package or in the per-package fields paragraph of a source
> +package control file.

I'm not sure what you mean by "per-package fields paragraph of a source
package control file".

Also, "may" is a Policy magic word so shouldn't be used in the ways it
is used in this paragraph.  I suggest "A Debian installation can" and
"It must not occur in ..." or similar.

> The semantics of permitted values are ``no``
> +(default), ``foreign``, ``same`` and ``allowed`` as described
> +individually.

Just

    The permitted values are ... .

is enough I think.

> +.. _s-f-Multi-Arch-no:
> +
> +``Multi-Arch: no``
> +^^^^^^^^^^^^^^^^^^
> +
> +When satisfying a dependency (using ``Depends``, ``Pre-Depends``,
> +``Provides``, ``Recommends``, or ``Suggests``), the architecture of the
> +depender and the architecture of the dependee being thus marked are
> +required to be equal. For negative dependency relations (``Breaks``,
> +``Conflicts``, and ``Replaces``) the architecture does not have to match
> +for the relation to take effect.

Simplify to:

    This means that a ``Depends``, ``Pre-Depends``, ``Provides``,
    ``Recommends`` or ``Suggests`` relation between packages is
    satisfied only by packages of the same architecture.  There is no
    effect on ``Breaks``, ``Conflicts`` and ``Replaces``.

> Architecture-independent packages are
> +treated as if they had the architecture value of the installed `dpkg`
> +package.  Furthermore, multiple instances of a package with the same
> +name and different architectures are not considered coinstallable.

Reorder:

    Furthermore, multiple instances of a package with the same name but
    different architectures are not coinstallable.
    Architecture-independent packages are treated as though they were
    architecture-dependent with the same architecture as the version of
    ``dpkg`` that's installed.

> +``Multi-Arch: foreign``
> +^^^^^^^^^^^^^^^^^^^^^^^
> +
> +A binary package may be marked ``Multi-Arch: foreign`` if the provided
> +interfaces are independent of the architecture of the package. Any
> +provided virtual packages (see :ref:`s-virtual`) inherit this property.
> +Given this header value, dependencies on this package are considered
> +satisfied even when the depender's architecture differs from the marked
> +package.

Reorder:

    This means that the interfaces the package provides are independent
    of its architecture, and that therefore it satisfies dependencies on
    a package of this name regardless of the architecture of the package
    declaring the dependency.  Any virtual packages provided ...

> +There are five main areas that can contribute to the interface of a
> +package and if any of them provides an architecture-dependent interface,
> +a package must not be marked with ``Multi-Arch: foreign``.

Is "must" right?  I think it's okay, but just to check, this would
always be an RC bug?

I think you need to talk about arch:all vs. arch:any here and how it is
(and is not) the same as having architecture-independent interfaces.

> +- The installed files of a package: Architecture-dependent packages may
> +  install different sets of files or files with different content for
> +  multiple architectures and these differences may contribute to the

s/multiple/different/

> +  interface (e.g. an endianess-dependent database file).  For
> +  architecture-independent binary packages, this aspect does not
> +  apply.

See above -- arch:all vs. arch:any kind of comes out of nowhere here,
and it's difficult to follow.  The reader thinks "wait a minute,
architecture-independent binary packages would always be m-e:foreign,
wouldn't they?  Oh, there must be edge cases?" and promptly gets lost.

> +- The behavior of installed files of a package: When interfacing with
> +  installed files by executing them, their behavior may contribute to
> +  the provided interface.  For instance, interfacing with shared and
> +  static libraries necessarily is architecture-dependent.  Whilst binary
> +  executables generally differ with architectures, the exposed interface
> +  (for example the command line interface, the content on standard
> +  input/output, the way they process files) may be independent of the
> +  architecture used to execute.  In that case, their interface may be
> +  considered architecture-independent.

This is dificult to follow.
I don't know what the first sentence means -- what is interfacing with
installed files, and whose provided interface is it?

> +- The dependencies of a package: A package may expose functionality of
> +  other packages by depending on them. The ABI of a shared library
> +  linked into an executable does not contribute to the interface, but
> +  the behavior of library functions used may do so. Development packages
> +  for shared libraries necessarily expose their own dependencies as
> +  their interface since they enable others to link such libraries. An
> +  extreme example is transitional packages, whose main purpose is to
> +  expose the functionality of their dependency.

I think I follow you here but it's very dense.  Could you give some very
simple examples to illustrate?

> +- Implicit and foreign dependencies of a package: Essential packages are
> +  implicitly depended upon and need not show up in ``Depends``. Yet
> +  their behaviour can be architecture-dependent. For instance, using
> +  ``dpkg --print-architecture`` can be used to emit the native
> +  architecture even though ``dpkg`` is marked ``Multi-Arch: foreign``.
> +  Similarly, calling ``pkgconf`` (without a prefix) will behave
> +  differently on different architectures as its search path is
> +  architecture-dependent even though ``pkgconf-bin`` is considered
> +  ``Multi-Arch: foreign``.

So why are these packages m-e:foreign?  This paragraph is difficult for
someone to think about what it would mean for the package they maintain
(which is our target audience).

> +The interfaces of a package are determined by its maintainer.  However,
> +some packages might expose architecture-specific dependencies when other
> +packages use them in a manner not intended by the maintainer.  This can
> +happen when it is not clear which parts of the package are its
> +interfaces.
> +
> +In such cases, where the package satisfies the criterion for
> +``Multi-Arch: foreign`` but might expose architecture dependency,
> +because it is not clear which parts of the package are its interfaces,
> +the interfaces of the package should be described in the file
> +``debian/README.multiarch``.
> +
> +Conversely, justifying the use of functionality that is not covered by
> +its offered interface with a dependency on such a package is not
> +allowed.

Can you reword this to use "should", "should not" etc. more often?
We're imposing requirements, here, so the normative status should be
clear.  Also, there is a switch here from describing requirements on the
maintainer of the m-e:foreign package to requirements on the maintainers
of rdeps.  It would be good to be explicit about that: "Packages
depending on a package marked m-e:foreign should not ..."

> +``Multi-Arch: same``
> +^^^^^^^^^^^^^^^^^^^^
> +
> +Multiple binary packages with the same name and version may be installed
> +concurrently if all of them carry this header valued ``same``. Any set
> +of packages with matching name and version being thus marked must
> +support the following properties.
>
> +- All filenames that are present in multiple of these packages must
> +  contain bit-identical content across architectures. [#]_
> +
> +  For files whose name is unique within this set, no such requirement
> +  exists. Therefore, such packages usually install most of their files
> +  below ``/usr/lib/${DEB_HOST_MULTIARCH}``.

For a set of packages which all have the same name and version, do we
ever want to allow some of them to have m-a:same and some of them not?
If we disallow that then this can be worded more straightforwardly:

    This means that other packages with the same name and version, but
    different architectures, are coinstallable.  All packages with this
    name and version must be declared ``Multi-Arch: same``.  For a given
    file name, if the package for one architecture installs a file
    there, then the packages for every other architecture must either
    install no file there, or a bit-identical file.  (Given this
    restriction, such packages usually install most of their files below
    ``/usr/lib/...``.)

> +- The maintainer scripts must be prepared to be configured or
> +  deconfigured multiple times.

Isn't this already implied by the general requirements on maintainer
scripts to be idempotent?

> In particular, ``postrm`` must consider
> +  that another instance may still be present.

How about:

    In particular, any ``postrm`` script must not assume that all
    instances of the package (i.e., instances for other architectures)
    are all gone.

> It may check the
> +  ``DPKG_MAINTSCRIPT_PACKAGE_REFCOUNT`` environment variable set by
> +  ``dpkg``.

What is the meaning of the value of this environment variable?

> +``Multi-Arch: allowed``
> +^^^^^^^^^^^^^^^^^^^^^^^
> +
> +A package marked this way behaves as if it were annotated with the
> +``no`` value except that a depender may now append ``:any`` to the
> +package name in a dependency relation field. In that case, the
> +dependency is considered satisfied even when the architecture of the
> +depender differs from the dependee's. Dependencies carrying an ``:any``
> +suffix can only be satisfied by packages marked ``Multi-Arch: allowed``.

As above, how about reordering it like this:

    This means the same as ``Multi-Arch: no`` except that a package
    depending on this package may choose to treat it as though it were
    marked ``Multi-Arch: foreign``.  This is done by appending ``:any``
    to the name of the package in the dependency relation field.  For
    example, where foo is ``Multi-Arch: allowed``, bar might have
    ``Depends: foo:any (>= 1.0)``.  Then bar's dependency on foo is
    satisfied even when bar and foo have different architectures.

    Only a ``Multi-Arch: allowed`` package satisfies a dependency with
    the ``:any`` suffix.

> +This value should be used rarely for cases where the package can be used
> +in an architecture-dependent way or in an architecture-independent way
> +and the decision of which applies is deferred to the depender. The most
> +common use is with programming language interpreters that enable loading
> +architecture-dependent plugins.

Can you avoid "should" here?  I don't think you intend to be normative.

> +
> +.. [#]
> +   As an exception, the ``libc6`` package is marked ``Multi-Arch: same``
> +   despite not fully complying with this requirement, because the
> +   location of the dynamic loader is not universally unique and cannot
> +   be changed without breakig ABI.

It would be helpful to scope "universally" I think.  Do you mean across
architectures, or across GNU/Linux distributions, or what?

Thanks again.

-- 
Sean Whitton

Attachment: signature.asc
Description: PGP signature


Reply to: