Depends
Format
Fields with a List of Dependencies | ||
Dependencies | Conflicts | Suggestions |
Build-Depends | Build-Conflicts | Enhances |
Build-Depends-Arch | Build-Conflicts-Arch | Provides |
Build-Depends-Indep | Build-Conflicts-Indep | Recommends |
Built-Using | Replaces | |
Depends | Conflicts | Suggests |
Pre-Depends | Breaks | |
Ubuntu-Depends |
Most packages depend on others which depend on others... building an entire, at times very complex directed acyclic graph of packages (often miscalled a package tree).
This field defines the dependencies of a package. Only the direct dependencies are to be specified unless you need a very specific version of another package for your package to function. Each dependency is the name of a package. For example, the wpkg-dev package depends on the wpkg package:
Package: wpkg-dev Depends: wpkg
When a package depends on multiple packages, each package name can be specified with a comma as the separator. For example, you may create a package the depends on the wpkg libraries and also requires boost:
Depends: wpkg, boost
Version Specification
Each dependency can also be constrained by a version (by default any version is accepted.) In case of a Provides, versions cannot be specified because the different packages that may apply will all have a different version scheme. With a direct package name, you may require it to have a very specific version, a range of versions, a given version or older, or a given version or newer. This is defined by adding version information between parenthesis with a relation operator. For example, you may required boost version 1.50 or more:
Depends: boost (>= 1.50)
The version test supports the following operators:
- << -- any version smaller than the one specified is acceptable
- <= -- any version smaller or equal to the one specified is acceptable
- = -- that exact version is acceptable
- >= -- any version larger or equal to the one specified is acceptable; this is the default in case no operator is defined
- >> -- any version larger than the one specified
Note that there is no "not equal" operator. This is by choice. In most cases, >= is what you want anyway.
To define a range, you enter two entries with the same package name:
Depends: boost (>= 1.22), boost (<= 1.37)
Architecture Specific Dependencies
Furthermore, you can specify to what architecture this dependency applies. This is done using square brackets with the name of the architecture:
Depends: boost (>= 1.50) [linux]
This is useful when you build the same archive on different architecture and use a dynamic variable to define the Architecture or use the control.info file. The test can also be inverted with the ! operator so the dependency applies to all architectures except the one specified.
Depends: boost (>= 1.50) [!win32]
Multiple architectures can also be specified when separated by spaces. In this case, all the architectures must either be used without the ! operator or they must all be used with the ! operator. For example:
Depends: boost (>= 1.50) [linux freebsd] Depends: boost (>= 1.50) [!win32 !mac9]
Multiple Acceptable Dependencies
The comma separator between dependencies is taken as an AND operator. So packages specified on the and and on the right are both required.
It is also possible to use the | operator to add dependencies with an OR operator meansing that if at least one of the specified packages satisfies the dependency, then the Depends is accepted as valid.
Depends: postfix | sendmail
It is rare that the | operator can be used, although you can have some code in your package to test what is installed and thus react appropriately.
IMPORTANT NOTE
The parser is very closely checking the validity of these rules. You cannot have two commas or | in a row, for example.
Example of Depends that end up in a non-installable environment
There is an example of packages a, b, c, d, e and f where b and c depend on different versions of package d. Because a requires b and c, all final directed acyclic graphs end up being invalid (in this case, only 2 graphs.)
The command line used is as follow (the -D is used to get the pictures):
wpkg -D 4 --repository repository --root target --install repository/pa_1.0_linux-amd64.deb
First there is the complete directed acyclic graph of all the packages available for the install command.
The package marked as (exp) is the only explicit package specified on the command line (see above.)
The packages marked as (avl) are those available in the repository directory. Here we see pa to pf all available.
As we can see pb depends on pd version 1.0 and pc depends on pd version 2.0. Because of that, one of the pd versions is marked as a invalid (see images below) in both possible cases available.
Note that the graph does not really show the fact: but know that the pa (avl) package is completely ignored because the pa (exp) has priority (it can be the exact same file or two different files.)
The following two images present the conflicts found when trying to build a valid directed acyclic graph:
The dependency definition in the pb package is:
Depends: pd (= 1.0)
The dependency definition in the pc package is:
Depends: pd (= 2.0)
It is rare that you would use the equal (=) operator like this. By default, when you do not use an operator (which means >=) you would get these two entries:
Depends: pd (1.0) Depends: pd (2.0)
And that means the directed acyclic graph on the right would work because pb would accept either pd 1.0 or pd 2.0.
Potential Complexity of a Directed Acyclic Graph
Vladeta Jovavic calculated the complexity of directed acyclic graphs (DAGs) which grows extremely quickly. In most cases, we do not see our dependency graph complexity grow quite that fast because part of the graph is very much like a simple tree. However, it gives a good idea of the potential complexity of the task.
Number of Packages | Potential Complexity | Digits |
---|---|---|
1 | 1 | 1 |
2 | 1 | 1 |
3 | 3 | 1 |
4 | 25 | 2 |
5 | 543 | 3 |
6 | 29,281 | 5 |
7 | 3,781,503 | 7 |
8 | 1,138,779,265 | 10 |
9 | 783,702,329,343 | 12 |
10 | 1,213,442,454,842,881 | 16 |
11 | 4,175,098,976,430,598,143 | 19 |
12 | 31,603,459,396,418,917,607,425 | 23 |
13 | 521,939,651,343,829,405,020,504,063 | 27 |
14 | 18,676,600,744,432,035,186,664,816,926,721 | 32 |