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"
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:
virtual/kernel
:
Provides the name of the kernel recipe to use when
building a kernel image.
virtual/bootloader
:
Provides the name of the bootloader to use when
building an image.
virtual/mesa
:
Provides gbm.pc
.
virtual/egl
:
Provides egl.pc
and possibly
wayland-egl.pc
.
virtual/libgl
:
Provides gl.pc
(i.e. libGL).
virtual/libgles1
:
Provides glesv1_cm.pc
(i.e. libGLESv1_CM).
virtual/libgles2
:
Provides glesv2.pc
(i.e. libGLESv2).