Ubuntu – How does APT choose the specific package to install in order to provide a virtual package needed as a dependency

apt

For example, awk is a virtual package provided by original-awk, mawk and gawk.

Trying to install it directly yields:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package awk is a virtual package provided by:
  original-awk:i386 2012-12-20-4
  mawk:i386 1.3.3-17ubuntu2
  gawk:i386 1:4.1.1+dfsg-1
  original-awk 2012-12-20-4
  mawk 1.3.3-17ubuntu2
  gawk 1:4.1.1+dfsg-1
You should explicitly select one to install.

E: Package 'awk' has no installation candidate

However many virtual packages are needed as dependencies by the packages installed by default, for example awk itself is needed by base-files, which checking the APT logs is installed along with a bunch of other packages through apt-get --yes; somehow APT ends up picking one of the three automatically (I'm pretty sure that's mawk, but that's not the point of the question).

How does APT choose the specific package to install in this case?

Best Answer

How does APT choose the specific package to install in this case?

APT doesn't select a package. It tells:

You should explicitly select one to install.

If you try to manually select a package, it wouldn't be installed.

In the case of base-files depending on awk it is irrelevant. First, it actually PreDepends on awk, forcing dpkg to install awk before starting to install base-files; second, mawk have priority required which are installed at system installation, and apt nags you if you try to remove it. So, just don't do it.

Now, according to sources, apt tries first of satisfying the dependency before trying with virtual packages (i.e., if depends are firefox | www-browser, checks if any of the packages are installed, then try to install firefox if neither is). If the non-virtual package isn't available, it seems to just iterate over all packages which provides the virtual package, if no other dependencies are broken. Other comments evidence of this behavior are this which leads to GrpIterator::FindPreferredPkg function.