10

I'm curious to understand how ~ is processed in a dependency by Apt or how it's defined for deb files (I'm not sure exactly where the syntax is defined).

I ran into it with respect to dependencies of the Ubuntu (Focal) meta package python3 which has the dependency constraint: python3.8 >= 3.8.2-1~ (see here).

I believe package versions are defined so that they lexically sort in order, but when I checked ubuntu focal, there is no version of python3.8 that sorts lexically >= 3.8.2-1~ but there is a version 3.8.10-0ubuntu1~20.04.4 inferring that either Ubuntu Focal's dependencies are broken (they are not) or there is some special meaning to ~ in a dependency.

The only documentation I can find on the topic is Debian's Declaring relationships between packages. But this doesn't mention a ~ or pattern matching.

So what is the meaning of the trailing ~ in a .deb dependency?

2 Answers 2

10

The documentation on the Version control field states (see the page for the full algorithm):

First the initial part of each string consisting entirely of non-digit characters is determined. These two parts (one of which may be empty) are compared lexically. If a difference is found it is returned.

The lexical comparison is a comparison of ASCII values modified so that all the letters sort earlier than all the non-letters and so that a tilde sorts before anything, even the end of a part. For example, the following parts are in sorted order from earliest to latest: ~~, ~~a, ~, the empty part, a.

A footnote adds this about the tilde:

One common use of ~ is for upstream pre-releases. For example, 1.0~beta1~svn1245 sorts earlier than 1.0~beta1, which sorts earlier than 1.0.

7

Tildes in versions are described in the section of Policy on versions. Basically, tildes sort before anything.

Thus >= 3.8.2-1~ is satisfied by any version starting with 3.8.2-1, including versions with suffixes starting with a tilde themselves, such as 3.8.2-1~bpo (as would be used for backports), as long as there aren’t two tildes in a row. In fact such dependencies, with a tilde at the very end of the version (including the Debian revision), are typically used to facilitate backports.

Since this is specifically what your question is about, and isn’t addressed by Debian Policy, it’s worth going into more detail. A typical version dependency would look like python3.8 >= 3.8.2-1, requiring version 3.8.2-1 or later of the python3.8 package. This would be satisfiable by any later upstream version of Python 3.8, and any later Debian revision of the package (3.8.2-2, or 3.8.2-1ubuntu1, etc.). But it wouldn’t be satisfied by backports, which have versions of the form 3.8.2-1~bpo10+1; since the tilde sorts before the empty string, 3.8.2-1~bpo10+1 is considered to be less than 3.8.2-1. Backporting packages using versioned dependencies of this form thus requires changing their dependencies, which goes counter to the general rule that backports should be as close as possible to the original package.

So adding a tilde as the last character of a version in a versioned dependency helps relax the dependency slightly: it allows versions with the same prefix, and a tilde-separated suffix, to satisfy the versioned dependency. This is the opposite of the documented use of tildes for pre-releases, which result in versions which can’t satisfy strictly-versioned dependencies on the final release.

(Note that a tilde as the last character in a version number which includes a Debian revision, as given in the question, can’t allow upstream pre-releases — those would look like 3.8.2~pre1-1, which is less than 3.8.2-1~.)

Versions aren’t sorted lexically, they’re sorted by component, numerically if possible, lexically otherwise. Thus 3.8.10-0ubuntu1~20.04.4 does satisfy this relationship: 10 is greater than 2, so the dependency is satisfied and the comparison stops there.

3
  • 1
    If I understood the examples in Eduardo's quote correctly, >= 3.8.2-1~ would not be satisfied by 3.8.2-1~~whatever, since the second tilde would sort before an end-of-string after the first tilde. Not that I expect anyone to meet version numbers like that, but (again, if I got it right), the tilde isn't like a wildcard character, just an oddly-sorting one.
    – ilkkachu
    May 26 at 16:20
  • Yeah, now that I read the right documentation, it looks like it can be used as a wildcard, but only for >= and >> requirements where you know the package versions won't contain a ~. That makes a lot of sense in the case of meta packages. May 26 at 16:29
  • 1
    Note that this use as a wildcard, in last place in a Debian revision, is actually the opposite of the pre-release use described in Eduardo’s answer. May 27 at 15:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.