Virtuals

Virtuals are merely packages that are in the category of virtual. They use their dependency string to specify the providers for the virtual and do not install any files. Since they are regular ebuilds, there can be several versions of a virtual (which can be helpful when a package may be provided by another in some versions, and not others — see the perl virtuals for an example of this). One other difference (besides not installing any files) is that a virtual does not define HOMEPAGE and LICENSE variables. Since it installs no files, it really does not have a license.

Before adding a new virtual, it should be discussed on gentoo-dev.

An example of a virtual:

EAPI=8

DESCRIPTION="Virtual for C++ tr1 <type_traits>"
SLOT="0"
KEYWORDS="~alpha amd64 arm hppa ~ia64 ~mips ppc ppc64 ~s390 sparc x86 ~x64-macos"

RDEPEND="|| ( >=sys-devel/gcc-4.1 dev-libs/boost )"

Looks familar...right? It should since it's going to look just like a regular ebuild.

KEYWORDS in virtual packages

Since virtual packages do not install any files, they do not follow the regular arch testing procedure. Instead, the developer can immediately set the KEYWORDS of a virtual to the union of KEYWORDS of its providers. In particular, if a new virtual is created for a stable package, the virtual is committed straight to stable.

For example, if you have two packages: dev-libs/liblinux with KEYWORDS="amd64 ~x86" and dev-libs/libbsd with KEYWORDS="~amd64-fbsd ~x86-fbsd", the resulting virtual will have:

KEYWORDS="amd64 ~x86 ~amd64-fbsd ~x86-fbsd"

RDEPEND="|| ( dev-libs/liblinux dev-libs/libbsd )"

Virtuals and subslots

Like regular packages, virtuals can define subslots that can be used to trigger rebuilds of their reverse dependencies. For this to work, a new version of the virtual is created for each subslot of the providers, where each version contains dependencies on a specific subslot.

For example, a virtual for different packages providing ABI-compatible libfoo.so.1 libraries could look like the following:

EAPI=8

DESCRIPTION="Virtual for libfoo.so.1"
SLOT="0/1"

RDEPEND="
    || (
        dev-libs/libfoo:0/1
        dev-libs/libfoo-alternate:0/1
        dev-libs/bigpack:0/libfoo-1+libbar-0
        dev-libs/bigpack:0/libfoo-1+libbar-1
    )
"

Virtuals can also be used when one of the providers is being obsoleted in favor of another that breaks ABI compatibility while remaining API-compatible. In this case, multiple versions of the virtual are created, each specifying a single provider and a unique subslot.

For example, if dev-libs/libfoo (libfoo.so.0) is being replaced by dev-libs/newfoo (libfoo.so.1), virtual/libfoo-0.ebuild would contain:

EAPI=8

DESCRIPTION="Virtual for libfoo.so.0"
SLOT="0/0"

RDEPEND="dev-libs/libfoo:0/0"

while virtual/libfoo-1.ebuild would contain:

EAPI=8

DESCRIPTION="Virtual for libfoo.so.1"
SLOT="0/1"

RDEPEND="dev-libs/newfoo:0/1"