3.3.17. Using Virtual Providers

Prior to a build, if you know that several different recipes provide the same functionality, you can use a virtual provider (i.e. virtual/*) as a placeholder for the actual provider. The actual provider is determined at build-time.

A common scenario where a virtual provider is used would be for the kernel recipe. Suppose you have three kernel recipes whose PN values map to kernel-big, kernel-mid, and kernel-small. Furthermore, each of these recipes in some way uses a PROVIDES statement that essentially identifies itself as being able to provide virtual/kernel. Here is one way through the kernel class:

     PROVIDES += "${@ "virtual/kernel" if (d.getVar("KERNEL_PACKAGE_NAME") == "kernel") else "" }"
                

Any recipe that inherits the kernel class is going to utilize a PROVIDES statement that identifies that recipe as being able to provide the virtual/kernel item.

Now comes the time to actually build an image and you need a kernel recipe, but which one? You can configure your build to call out the kernel recipe you want by using the PREFERRED_PROVIDER variable. As an example, consider the x86-base.inc include file, which is a machine (i.e. MACHINE) configuration file. This include file is the reason all x86-based machines use the linux-yocto kernel. Here are the relevant lines from the include file:

     PREFERRED_PROVIDER_virtual/kernel ??= "linux-yocto"
     PREFERRED_VERSION_linux-yocto ??= "4.15%"
                

When you use a virtual provider, you do not have to "hard code" a recipe name as a build dependency. You can use the DEPENDS variable to state the build is dependent on virtual/kernel for example:

     DEPENDS = "virtual/kernel"
                

During the build, the OpenEmbedded build system picks the correct recipe needed for the virtual/kernel dependency based on the PREFERRED_PROVIDER variable. If you want to use the small kernel mentioned at the beginning of this section, configure your build as follows:

     PREFERRED_PROVIDER_virtual/kernel ??= "kernel-small"
                

Note

Any recipe that PROVIDES a virtual/* item that is ultimately not selected through PREFERRED_PROVIDER does not get built. Preventing these recipes from building is usually the desired behavior since this mechanism's purpose is to select between mutually exclusive alternative providers.

The following lists specific examples of virtual providers: