Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Bit Bake Basics

Download as pdf or txt
Download as pdf or txt
You are on page 1of 23

Bitbake Basics

Author: Johannes Buerle

XS Embedded GmbH

Copyright 2012 XS Embedded GmbH


All rights reserved. No part of this document may be reproduced, stored in a retrieval system, or transmitted in any form or by
any means, without the prior written permission of the publisher.

confidential Page 1 of 23
History

Rev. Status Change Date Name

0.1 Initial creation of document 2012-05-25 JBaeuerle

confidential Page 2 of 23
Table of Contents
1 General Information ........................................................................................................................ 4
1.1 Purpose .................................................................................................................................... 4
2 Build Process in General ................................................................................................................ 4
2.1 bitbake Tool .............................................................................................................................. 4
2.2 Directory Structure .................................................................................................................... 4
2.2.1 General ............................................................................................................................ 4
2.2.2 Collections ....................................................................................................................... 5
2.3 Configuration files ..................................................................................................................... 5
2.3.1 local.conf ......................................................................................................................... 5
2.3.2 bitbake.conf ..................................................................................................................... 5
2.3.3 Distributions ..................................................................................................................... 5
2.3.4 Machines ......................................................................................................................... 5
3 Classes ........................................................................................................................................... 6
3.1 Content ..................................................................................................................................... 6
3.2 Usage ....................................................................................................................................... 6
3.3 Common classes ...................................................................................................................... 6
4 Images ............................................................................................................................................ 7
4.1 Tasks ........................................................................................................................................ 7
5 Recipes ........................................................................................................................................... 8
5.1 metadata ................................................................................................................................... 8
5.2 Comments ................................................................................................................................ 9
5.3 Intended platform ...................................................................................................................... 9
5.3.1 Target recipes ................................................................................................................. 9
5.3.2 Native recipes (host) ....................................................................................................... 9
5.3.3 SDK recipes (host) ........................................................................................................ 10
5.4 Variables ................................................................................................................................. 10
5.4.1 Reading ......................................................................................................................... 11
5.4.2 Setting ........................................................................................................................... 11
5.4.3 Appending and prepending ........................................................................................... 11
5.4.4 Linebreaks ..................................................................................................................... 11
5.5 Directories ............................................................................................................................... 12
5.6 Package revisions................................................................................................................... 12
5.7 Package relations ................................................................................................................... 12
5.8 Sources ................................................................................................................................... 13
5.9 Build steps .............................................................................................................................. 14
5.9.1 do_fetch ......................................................................................................................... 14
5.9.2 do_unpack ..................................................................................................................... 14
5.9.3 do_patch ........................................................................................................................ 15
5.9.4 do_configure.................................................................................................................. 15
5.9.5 do_compile .................................................................................................................... 16
5.9.6 do_install ....................................................................................................................... 16
5.9.7 do_stage ........................................................................................................................ 16
5.9.8 do_package ................................................................................................................... 17
5.9.9 do_clean ........................................................................................................................ 17
5.9.10 Extension of existing tasks ............................................................................................ 17
5.9.11 User-defined tasks ........................................................................................................ 18
6 Advanced ...................................................................................................................................... 18
6.1 Devshell .................................................................................................................................. 18
6.1.1 find and grep ................................................................................................................. 19
6.1.2 creating patches ............................................................................................................ 19
6.2 Determining Dependencies of packages and build tasks....................................................... 20
6.3 Virtual packages ..................................................................................................................... 21
6.4 Precedence of recipe versions ............................................................................................... 21
6.5 Setting preferred providers and versions ............................................................................... 22
Appendix A: Documents........................................................................................................................ 23
Appendix B: Abbreviations .................................................................................................................... 23

confidential Page 3 of 23
1 General Information
1.1 Purpose
This document contains information about the usage of bitbake and implementation details useful for
writing recipes. Chapters 2 to 5 contain general information about bitbake, the project environment
and the recipe syntax. In the last chapter some advanced techniques working in a bitbake
environment are explained.

2 Build Process in General


2.1 bitbake Tool
Bitbake is a tool-suite implemented in python. It is able to build software packages ranging from a
single package for a specific target platform up to complete operating systems delivered as file
system images.

bitbake is always invoked in the project root directory. The syntax of the bitbake tool is as follows:

bitbake [additional arguments] [recipe name]

where [additional arguments] may be one of

Argument Description
-c [task] Execute a particular build task for the given
recipe
-f Force a particular build operation with -c
-e print environment variables for a build of the
given recipe
-s Print a list of all recipes with current and preferred
versions, this argument does not evaluate the
recipe name
-g Create a Graphviz dependency dump for the
given recipe and all recursive dependencies

If no additional arguments except the package name are given the build of the package is started or
continued if parts of the build are already finished. If building the package was successfully performed
in the past nothing is done.

2.2 Directory Structure


2.2.1 General
Every bitbake project creates a number of directories. Depending on the project configuration the
location may differ. All paths are given relative to the project root.

Directory/Description Usual Paths


Overall working directory tmp
Collection folders optstack
project
tmp/collection
Project related configuration conf
<collection folder>/conf
Downloaded sources downloads
tmp/sources
Working directory for a single package tmp/work/<platform>/<package name>
Staging directories, containing development tmp/staging/<platform>

confidential Page 4 of 23
resources of packages already build tmp/sysroots/<platform>
Deployment of package containing all build tmp/deploy/<package format>/<platform>
packages
Deployment of file system images tmp/deploy/images

2.2.2 Collections
A collection is a folder containing build descriptions for multiple packages. These are build
instructions, configuration and tooling. The build descriptions are called recipes. See section 5 for
details about recipes.
The recipe subfolder is mandatory and contains the build descriptions for the single packages
The conf subfolder is optional and contains configuration data for the use by recipes
The classes subfolder is optional and contains classes that can be included in the recipes.
Classes contain common declarations shared by multiple recipes.

2.3 Configuration files


A project always refers to a specific distribution and a specific machine. The distribution declaration
contains details about the targeted OS. A machine declaration contains details about the used
hardware. Further configuration files contain specifications that do not fit in distribution-related or
machine-related configuration. Prior to any other operation the configuration files are used to build the
basic environment for the project. The configuration values are cached and are accessed during all
following bitbake operations.

2.3.1 local.conf
The local.conf file is located in the 'conf' subdirectory of the project root directory. The main
configuration contains references to all other configuration files. Usually working directory (TMPDIR),
download directory (DL_DIR) and deploy directory (DEPLOY_DIR) are declared here. The local.conf
itself or a referenced configuration file contains the search patterns for the directories containing the
actual package build declarations (recipes + classes). Finally the local.conf usually contains project
related settings about preferred providers and versions of packages.

2.3.2 bitbake.conf
The bitbake.conf configuration file contains the details about the operation of bitbake. Among the
numerous details are:
working directories for all stages of operation
standard configuration for compiler tool chain
download mirrors
standard packaging behavior
package/recipe default variables

2.3.3 Distributions
A distribution determines the details of the used operating system. This includes kernel version, used
compiler suite and version, the basic C library and preferred packaging format of images. These are
all files that match the pattern <>/conf/distro. Distribution configuration files can include other
distribution configuration files.

2.3.4 Machines
A machine declaration contains specific configuration values for specific target hardware. Machine
configurations are located in all folders that match the pattern <>/conf/machine. Some of the usual
machine specific values are TARGET_ARCH, KERNEL_IMAGETYPE, TARGET_FPU, and
MACHINE_FEATURES. Machine configuration files can include other files to inherit values from other
machine configurations.

confidential Page 5 of 23
3 Classes
Classes encapsulate common functionality needed by several recipes. Recipes which are based on
classes are much smaller as lots of the declarations are handled in the common class. Classes are
located in special directories separated from the recipes. Class files have the suffix '.bbclass'.

3.1 Content
A class can contain the following
inheritance of other classes
declare/extend tasks (do_...)
tooling scripts in either shell or python code
variables (for example path variables or build details)

3.2 Usage
A class file can be used by adding

inherit [class]

to a recipe, the suffix .bbclass does not have to be added here.

A recipe that includes a class contains all functionality declared in the class file. It is possible to inherit
from multiple classes at the same time. In case several recipes contain conflicting declarations the
order of inclusion is important, the latest declaration overwrites earlier declarations.

inherit a #declares CONFIGURATION


inherit b #also declares CONFIGURATION

do_configure() {
./configure ${CONFIGURATION} # CONFIGURATION from class b is used
}

3.3 Common classes


The following list contains the most common classes

Class Description
autotools Declares that a package is built with Autotools.
do_configure, do_compile and do_install use
standard tools from the Autotools suite
cmake Declares that a package is built with cmake.
do_configure is invokes cmake, do_compile and
do_install use the Makefiles generated by cmake
native Recipe builds native tools (for host use)
skd/nativesdk Recipe builds native tools for sdk use, difference
to native is the deployment of all sdk packages as
standalone sdk without further need for bitbake
base Common declarations for all recipes
image Marks a recipe as image (See section 4 for
explanation)
task Marks a recipe as task (See section 4.1 for
explanation)
pkgconfig Contains extra declarations for recipes providing
pkgconfig files (.pc)
kernel Declares that a package builds a Linux kernel

confidential Page 6 of 23
4 Images
An image is the base class for deployable/installable root file systems. An image is a recipe that it is
derived from the image.bbclass. There are a lot of file system formats which can be used. The
decision is made in the project configuration. Some examples are:
ext3
ext2
jffs
.tar.gz

The result of building an image is a file system image in the requested format. It can be deployed to
an SD card, flash memory or used as network boot image.
Please note that the rootfs does not necessarily contain the kernel and the kernel modules which are
required for correct operation of the system. It may be necessary to deploy these separately.

An example for an image is the following code:

# minimalist image with XSe contributions for OIP platform


#gives you wayland compositor and qt

IMAGE_PREPROCESS_COMMAND = "create_etc_timestamp"

IMAGE_INSTALL = "task-boot task-xse-graphics"

export IMAGE_BASENAME = "xse-image"


IMAGE_LINGUAS ?= ""

inherit image

The most important declarations in this file are marked in bold font. The image is derived from the
image.bbclass (by using 'inherit image') and contains the packages declared in IMAGE_INSTALL.
There are two options to include packages into an image, either every package for itself or lists of
packages grouped in special task recipes. A task can be used to setup a list of similar packages (for
example all packages used for audio processing and audio output). Instead of referencing every
single package for itself the task can be included with a single statement.
The variable IMAGE_BASENAME declares the filename of the generated image in the file system of
the build host.
Example: When creating a tar.gz archive containing all files in a directory tree, the filename of the
.tar.gz archive will contain the string value from IMAGE_BASENAME.

The image class (image.bbclass) declares common variables or processes. Any recipe derived from
image (by using 'inherit') implicitly uses this functionality. The declarations from above override the
values from the base class. The resulting files are small in size but offer the complete functionality.
For a full control over all image functionality it is necessary to examine the image base class.

As long as images differ by the value of IMAGE_BASENAME multiple images can be built in parallel
in the same built directory. In fact they will share the underlying packages and only differ in the
resulting image.

4.1 Tasks
As mentioned before a task groups packages under a single task name. All packages of a task can be
referenced in an image with a single statement. Tasks are useful when creating different images in
the same project. The different images can be composed out of the related tasks instead of large lists
of packages.
Tasks are recipes derived from the task class (task.bbclass). The important declarations are marked
in bold font. The task recipe uses the RDEPENDS mechanism to add all required packages to the
runtime dependencies of the task recipe itself (in the given case task-xse-graphics).

confidential Page 7 of 23
Similar to the image class the task class (task.bbclass) declares common variables or processes.

To improve readability and maintainability of the task, all packages are grouped into space-separated
lists of packages, later accessed by the RDEPENDS variable.

DESCRIPTION = "Task for XSe graphics packages"


inherit task

PR = "r0"
PV = "0.0.1"

PACKAGE_ARCH = "${MACHINE_ARCH}"

PACKAGES = "task-xse-graphics"

PREREQUISITES_PACKAGES = " \
libstdc++ \
strace \
dbus-wox11 \
cairo-wox11 \
xkbcommon \
xkb-config \
"

WAYLAND_PACKAGES = " \
wayland \
wayland-image-files \
wayland-ivi \
wayland-c2d-compositor \
wayland-xse-clients \
wayland-demos \
"

QT_PACKAGES = " \
qt-everywhere-qpa \
qt-everywhere-qpa-demos \
qt-everywhere-qpa-examples \
"

RDEPENDS_task-xse-graphics = " \
${PREREQUISITES_PACKAGES} \
${WAYLAND_PACKAGES} \
${QT_PACKAGES} \
"

5 Recipes
Compared to images or tasks, recipes describe the build of a single package. The recipe file contains
all information required for building the related package. The project configuration in either
bitbake.conf or collections.inc declares where recipe files can be located. All recipes that match a
given configuration are parsed before anything is built. This is necessary to determine package
dependencies prior to building the packages. The list of matching recipes is stored in a cache,
therefore it is not necessary to parse all recipes every time bitbake is called. The following sections
explain details of the recipe mechanisms.

5.1 metadata
Metadata is usually located at the beginning of a recipe. It does not directly influence the build. Some
of the information is used to collect an overview over used licenses in the project. A usual build

confidential Page 8 of 23
artifact of bitbake are installation packages for either build host and target, those packages use some
of the information given in this section.

SECTION = "libs"
DESCRIPTION = "shared library for GIF images"
AUTHOR = "author"
LICENSE = "MIT"
HOMEPAGE = " www.ungif.org/"

As long as no reserved names in the bitbake context are used, this section can be extended by own
keywords. An example is the responsibility inside a company regarding creation and integration of
recipes.

XSE_RESPONSIBLE = "USER_X"
XSE_MAINTAINER = "USER_Y"

5.2 Comments
Comments are complete lines starting with the '#' character. The rest of the line to the next line break
is part of the comment. Comments are omitted when parsing the recipes

#
# Comment
#

5.3 Intended platform


Recipes can target the different architectures involved in the build. Without any declaration a package
is built for the target platform. Some recipes may require tools running on the host platform. These
are called native tools. They are never used outside a bitbake build environment. A third category,
called cross tools or sdk tools, contains native tools that are used without bitbake, usually in form of a
SDK.

5.3.1 Target recipes


By standard all recipes are built for the architecture of the target system which is declared by the
chosen machine in the project configuration. Such a recipe uses the cross compiler either build by the
bitbake itself or delivered and included as prebuilt compiler suite.
Naming convention for target recipes is usually

<package>_<revision/version>.bb

An example is libungif_4.3.bb. The underscore character '_' is used by bitbake to determine the
package version. Alternatively the variable PV can be set in a recipe without version information. Both
mechanisms lead to the same result. To avoid problems parsing package names and versions further
underscore characters have be avoided in the recipe filename.

5.3.2 Native recipes (host)


Native tools are executed on the build host. They are required as part of the build process by one or
other recipes. Native tools are always built using the system default compiler. Build artifacts are not
visible in root file system images. A recipe is declared as native tool by the following signature

inherit native

Native recipes differ from target recipes by the string '-native' in the recipe name. An example is

expat-native_1.95.7.bb

confidential Page 9 of 23
There are some examples of tools that are required for both target and host. If the build process is the
same the following signature marks a recipe as both target and native.

BBCLASSEXTEND = "native"

Nevertheless a recipe with the BBCLASSEXTEND declaration does not automatically build both
target and host version of the recipe. The declaration avoids the need for two separate files with the
same content. Host and target versions have to be built separately by calling 'bitbake expat' for the
target version and 'bitbake expat-native' for the host version.

5.3.3 SDK recipes (host)


SDK recipes are similar to native recipes. They are built for the use on the host platform with the
native system compiler. Compared to the native recipes they are not used inside the bitbake build
environment. They are used as part of a cross tool chain (SDK). SDK recipes and native recipes are
built in a similar way, the difference is the deployment and the further use in the build. A cross tool
chain is usually intended for developers to allow for a cross platform workflow without having the full
bitbake environment.

A SDK recipe contains the following signature

inherit sdk

Sometimes nativesdk is used instead of sdk. This depends on the actual bitbake environment and the
collection provider (e.g. openembedded repo, MontaVista collections). The staging directory for sdk
recipes differs from the staging directory for native packages. Usually the staging directory for all sdk
packages is archived as a whole directory. The result can be used for cross-platform development.

5.4 Variables
Two kinds of variables can be used in recipes. Since recipes are usually derived from classes
(.bbclass) or .inc declaration files a lot of variables are already available without explicitly being
mentioned in the actual recipe file. These variables can affect behavior outside the recipe. The
second category consists of variables declared by the developer. These variables are only visible
inside the recipe.
A variable can either have a recipe-global or task-local visibility. All variables inside any task only
have local visibility. They can be used as storage for values between different calls in the task.

do_compile(){
CPUS = $(getconf _NPROCESSORS_ONLN)
make -j $CPUS
}

The above example uses a shell command to retrieve the number of processors available at the host
build platform and stores the result in the user variable CPUS. This name is not used out the compile
task , therefore CPUS is a task-local variable. The value of CPUS is later used to invoke 'make' with
the number of parallel processes to be executed. CPUS will not be visible outside the do_compile
block. The CPUS variable is accessed as usual shell variable by prepending a simple '$' character.
The task-local variables cannot be derived from other recipes (.inc) o classes (.bblcass).

The next example is a user defined variable with recipe-global visibility. The variable is visible for all
other variables and tasks in the recipe. The initialization and access follow the bitbake syntax. If the
variable matches the name of a derived variable from another recipe or class the value is replaced in
the scope of the recipe. If the name is not reserved or not used already, a variable with visibility in the
complete recipe is created.

CPUS = "4"

confidential Page 10 of 23
do_compile(){
make -j ${CPUS}
}

5.4.1 Reading
Shell variables inside tasks are accessed as usual by prepending a '$' character. The result of a
command line call can be accessed by using usual brackets. The values of these variables cannot be
used outside the current task.

$VARIABLE_NAME
$(COMMAND)

The variables declared outside of tasks (recipe-global) are accessed in a different manner regardless
where the variable is read. It is possible to access such variables inside and outside of tasks.

${VARIABLE_NAME}

5.4.2 Setting
As before the operation for setting shell variables inside tasks follows the shell conventions.

LD_LIBRARY_PATH=/usr/lib

The bitbake variables are declared with the convention that the value is given in double quotes. Inside
the double quotes lists of several values can be created using the whitespace character. Before and
after the assignment operator further whitespace characters are needed.

VARIABLE = "VALUE1 VALUE2"

Here it is possible here to use conditional assignments. A variable is set to a given value if no value
was given before. The syntax is

VARIABLE ? = "VALUE"

5.4.3 Appending and prepending


Bitbake variables can be altered by appending or prepending values.

Operator Description Example


+= append to variable EXTRA_OECONF += "--with-giflib"
_append same as += EXTRA_OECONF_append ="--with-giflib"
=+ prepend to variable EXTRA_OECONF =+ "--debug"
_prepend same as =+ EXTRA_OECONF_prepend = "--debug"

Note that tasks themselves are a list of commands stored in a variable by the name of do_... Tasks
can be extended by using the '_append' or '_prepend' operator.

5.4.4 Line breaks


Usually a variable reaches to the end of the current line. To optimize readability variables can be
expanded over multiple lines. Every line that contains a '\' as last character continues in the next line.
The double quote character required as boundary of the variable value is located in the first line and
the last line.

Example:

confidential Page 11 of 23
EXTRA_OECONF = " \
--nodebug \
--with-giflib \
--build-tools \
"

5.5 Directories
Some variables for standard directories commonly occur in the recipes. Except for the source
directory reference all other values should normally not be changed by the developer.

Variable Description
WORKDIR location of working directory, takes the target
platform into account
S Subdirectory of WORKDIR where sources for
build are located. This value has to be set
according to the package source directory name.
D Destination directory for installation of build
artifacts
STAGING_DIR Destination directory for the installation of build
artifacts into the staging directory.

5.6 Package revisions


There are several variables in each recipe identifying package name (PN), version (PV) and revision
(PR). Name and version are already given by the recipe name in most cases. If the recipe name does
not already contain a version it can be set manually by the user. The package revision is a value that
is incremented when major details of the recipe or the package sources change. An incrimination of
the package revision is a reliable way to tell bitbake that major changes occurred and all intermediate
stages in the build process have to be executed. This feature is required during development to avoid
the need for a complete clean build of the root file system image. It is a common problem if underlying
sources changed by new patches are not recognized in all stages of the build (staging, deployment of
packages and generation of image)

Variable Description Example (using recipe


test_1.2.bb)
PN The package name as given by the recipe filename Automatically set to 'test'
PV The package version as given by the recipe filename, Automatically set to '1.2', else
usually identical with the version of the source PV = "1.2"
file/archive.
PR The package revision increment for use during PR = "r0"
development

The above example will lead to a package ${PN}-${PV}-${PR} (e.g. test-1.2-r0) which is also used as
name for ${WORKDIR}.

5.7 Package relations


Recipes usually contain dependencies to other recipes; these can be both target and native
packages. Dependencies are either build-time dependencies or runtime-dependencies. A build-time
dependency declares package relation at build time. An example is libpng that has a dependency to
zlib. During the configuration of libpng the headers and libraries (static and shared) of zlib are
required. A runtime-dependency declares package relations at runtime in the resulting root file system
image. An example is the OpenGL test application eglgears that requires a valid graphics driver at
runtime.

To declare dependencies the following options are available:

confidential Page 12 of 23
Relation Description Example
[recipe]
DECLARATION
PROVIDES A package provides certain functionality [amd-gpu_11.09.01]
at build-time. Functionality is not referred PROVIDES = "gpu-driver"
to by package name but by the
PROVIDES statement. Another package
can provide the same functionality.
RPROVIDES One or more package provides certain [glibc]
functionality at runtime. RPROVIDES = "libstdc++"
DEPENDS A package depends on a package or [openglapp]
functionality declared with PROVIDES at DEPENDS += "libunfig libpng gpu-
built time. driver"
REDEPENDS A package depends on a package or [xse-image]
functionality declared with PROVIDES at RDEPENDS += "task-xse-graphics"
built time.
RRECOMMENDS / A package contains dependencies to [a]
RSUGGESTS other recipes which are not mandatory RSUGGESTS += "a-tools"
but useful at runtime (user experience)
RCONFLICTS A package with the RCONFLICTS [qt-everywhere-qpa]:
statement cannot exist in a root file RCONFLICTS += "qt-everywhere-
system with the conflicting package qws"
RREPLACES A package contains a replacement for a [libungif]
functionality with another name RREPLACES += "giflib"

5.8 Sources
Sources for the build of a package are declared using the SRC_URI variable. Each line in the variable
SRC_URI contains a link to a source which can be used in parallel. In the bitbake implementation
each category is realized in a 'fetcher'. The standard bitbake environment supports the following types
of sources:

Type of source Example


local file file://configure.patch (relative path)
file:///home/.../.../.../dbus-1.2.24(absolute paths)
svn repository svn://svn01/components/libabc/
git repository git://gitorious.org/webkit/webkit.git
http link http://dbus.freedesktop.org/releases/dbus/dbus-
1.5.12.tar.gz
ftp link ftp://ftp.simplesystems.org/pub/libpng/png/src/png.tar.gz

The local file can be referenced by absolute and relative paths. An absolute path starts at the root of
the file system '/'. Relative paths start in the recipe folder. As default behavior two paths are searched
for files with relative path names.
a 'files' subfolder
a separate subfolder named exactly after the recipe, oof several versions of the recipe are
available the version must be given (dbus-1.2.24 for a recipe dbus_1.2.24.bb)

The following block contains a valid SRC_URI declaration.

SRC_URI += " \
http://dbus.freedesktop.org/releases/dbus/dbus-1.5.12.tar.gz \
git://anongit.freedesktop.org/git/dbus/dbus-glib \
file://change1.patch \
file://change2.patch\
file://change3.patch \
"

confidential Page 13 of 23
All sources are copied to the local directory ${WORKDIR} for building. If a link leads to an archive the
archive contents are extracted into the local directory. The corresponding variable ${S} has to be set
to a valid build path. A usual recipe fetching sources from a single source leads to a single build
directory. A recipe should always contain a single package which is built standalone. Sources from
other depots make sense in case of configuration or application data that is required during the build
but not actively built itself.

5.9 Build steps


The following sections each contain descriptions about the standard build tasks of bitbake.
Some base classes provide build logic. For example the classes autotools.bbclass or cmake.bbclass
contain specialized implementations of some tasks. Developers can extend or replace any of the
tasks to meet requirements for the build of a package. If no particular build system is used the
standard task implementation of bitbake is used. This standard implementation only exists for the
configure and compile task. For details about the standard implementations refer to base.bbclass and
the related classes for autotools, cmake and bitbake.

5.9.1 do_fetch
This task is responsible for collecting the sources declared by SRC_URI. In case of ftp or http sources
a special module retrieves the sources from network sources. In case of svn/cvs/git complex modules
handle the checkout process (svn,cvs) or cloning process (git). In case of local files a simple copy
command of the file in the link is invoked. In case of archived files the archive is copied to the
workspace. If the resource behind SRC_URI is a usual directory in the filesystem the do_fetch will
cause problems as it does not know how to handle extracted data in the local filesystem. In that case
an empty implementation of do_fetch is required. The ': ' character tells bitbake that a task does not
have a specific implementation.

do_fetch() {
:
}

The result is a copy of the sources in tmp/downloads or tmp/sources. The actual location depends on
the project configuration in local.conf or any included configuration file.

5.9.2 do_unpack
do_unpack retrieves the sources from the downloads/sources directory and copies the sources into
the local working directory of the recipe which is ${WORKDIR}. A subfolder with the value of the last
path component of SRC_URI is used. This may differ from the automatically generated source folder
${S}. In the following example there is a naming problem. The recipe name is 'qt-webkit_535.2.bb'
and the resource name is 'webkit'.

[qt-webkit_535.2.bb]

SRC_URI = "git://gitorious.org/webkit/webkit.git "

S = "${WORKDIR}/webkit"

Due to the value of SRC_URI a subfolder 'webkit' is created. Sources are extracted/copied to this
folder. Opposed to the folder that is actually used, bitbake automatically generates the value for ${S}
with the following information:

${WORKDIR}/${PN}-${PV}-${PR}

All tasks after do_unpack will therefore have the wrong working directory. In such a case the value of
${S} has to be adjusted accordingly for the following tasks to work.

confidential Page 14 of 23
do_unpack contains a python standard implementation that cannot be extended by shell commands.
Any additions in do_unpack_append or do_unpack_prepend have to be written in python code. If shell
commands need to be executed in this block the python call os.system('<COMMAND>') can be used.

5.9.3 do_patch
The next step is to apply patches to the sources in the working directory ${S}. All files from SRC_URI
that match the filetype '.patch' are collected and applied to the sources.

SRC_URI = "
git://gitorious.org/webkit/webkit.git \
file://enable_cross_compile.patch \
file://add_wayland_id.patch \
file://omit_tools.patch \
"

In this case the 3 patches which are stored in ${WORKDIR} are applied to ${S}. This requires for
patches that match the directory structure of the source directory. The first line of a patch usually
contains the command that was used for creating the patch. The following two lines in this patch
contain references to old and new file. The patch was created using two directories 'a' and 'b'. This
first level is not handled by the patch tool and omitted per default. The rest of the path has to match
the structure in the source tree. In the given example this path is '
Source/WebCore/platform/qt/CursorQt.cpp '.

diff --git a/Source/WebCore/platform/qt/CursorQt.cpp


b/Source/WebCore/platform/qt/CursorQt.cpp
index 5883600..e7854dd 100644
--- a/Source/WebCore/platform/qt/CursorQt.cpp
+++ b/Source/WebCore/platform/qt/CursorQt.cpp
@@ -75,6 +75,8 @@ Cursor& Cursor::operator=(const Cursor& other)
#ifndef QT_NO_CURSOR
static QCursor* createCustomCursor(Image* image, const IntPoint& hotSpot)
{
+ if (!image->nativeImageForCurrentFrame())
+ return 0;
IntPoint effectiveHotSpot = determineHotSpot(image, hotSpot);
return new QCursor(*(image->nativeImageForCurrentFrame()),
effectiveHotSpot.x(), effectiveHotSpot.y());
}
@@ -197,6 +199,8 @@ void Cursor::ensurePlatformCursor() const
break;
case Custom:
m_platformCursor = createCustomCursor(m_image.get(), m_hotSpot);
+ if (!m_platformCursor)
+ m_platformCursor = new QCursor(Qt::ArrowCursor);
break;
default:
ASSERT_NOT_REACHED();

If a patch cannot be applied due to mismatching levels the do_patch process fails and emits an error
message. For an advanced description how to create patches refer to section 6.1.2.

5.9.4 do_configure
As patches often affect configuration files the do_configure process is invoked after the application of
the patches. This task contains all steps needed to successfully configure the project. In case of more
complex build systems as autotools or cmake this step is covered by standard implementations in the
according classes. Without the use of such a build system by 'inherit ' a non-standard
implementation can be provided by the developer. The default behavior for the configure task is to do
nothing. The implementation of do_configure is assumed to be written in shell commands.

confidential Page 15 of 23
do_configure() {

}

In case a standard build system is used the following variables can be used to pass configuration
options without the need to change the implementation of this task itself. In case of a configure script
for the use with autotools the variable EXTRA_OECONF can be used to add configuration options. In
a similar way the variable EXTRA_OECMAKE contains cmake parameters for a build with cmake.
The '-D' prefix before the actual values follows the same syntax as the command line interface of the
cmake tool.

EXTRA_OECMAKE = " \
-DOPENGL_INCLUDE_DIR=${STAGING_INCDIR} \
-DOPENGL_LIBRARY_DIR=${STAGING_LIBDIR} \
-DUSE_WAYLAND=ON \
"

5.9.5 do_compile
This task actually performs the build of the package. It invokes compilers and other native tools. As
before certain build systems as autotools and cmake provide standard implementation that can be
extended to match special requirements. In case none of the standard build systems are used the
developer has to provide the implementation. The standard operation for a recipe without a standard
build system is the call of 'make' in the source directory ${S}.

do_compile() {

}

5.9.6 do_install
During installation the build artifacts from the compile task and configuration/data files for runtime are
installed into the ${WORKDIR}/image directory. The upcoming tasks after do_install work with the
data from this directory. The standard implementation of do_install is empty. In most cases the install
task is the call of 'make install', but the details depend on the chosen build system. Developers can
provide extensions or own implementations for the install task in shell code.

5.9.7 do_stage
The task do_stage is similar to the task do_install, the difference is the location where the files are
copied to. Target of the sdo_stage task are the staging directories. Depending on inheritance from
native or sdk different staging directories are available. The usual staging directory for target related
data is ${STAGING_DIR}. For native packages ${STAGING_DIR_NATIVE} can be used. Based on
these two variables some more variables are derived. These are

Variable Description
STAGING_BINDIR[_NATIVE] Directory for binaries in staging area, usually /usr/bin
appended to target or native staging directory
STAGING_LIBDIR[_NATIVE] Directory for libraries in staging area, usually /usr/lib
appended to target or native staging directory
STAGING_INCDIR[_NATIVE] Directory for headers in staging area, usually /usr/include
appended to target or native staging directory
STAGING_DATADIR[_NATIVE] Directory for application data in staging area, usually
/usr/share appended to target or native staging directory

confidential Page 16 of 23
5.9.8 do_package
The build artifacts of a recipe are usually split into several packages. The bitbake configuration
declares the following standard packages that are composed of files matching search patterns in the
${WORKDIR}/image directory.

Package Example Patterns (related to ${WORKDIR}/image)


${PN} /usr/bin/*
/usr/lib/*.so
/usr/share/
/etc/
${PN}-dev /usr/include/*
/usr/lib/*.la
/usr/lib/*.a
/usr/lib/pkconfig/*
${PN}-dbg /usr/bin/.debug/*
/usr/lib/.debug/*

There are further default packages containing documentation (${PN}-doc), locale settings (${PN}-
locale) or static libraries (${PN}-static).

Developers can easily extend the package definitions by new search paths or even by new packages.
An existing package can be extended by the mentioned append/prepend operators. Usually the
append operator '+=' is used.

Example:

FILES_${PN}-dev += "/usr/share/config/conftool.pl"

New packages can be declared by adding them to the PACKAGES variable and declaring their
content:

PACKAGES += "${PN}-tests ${PN}-demos"

FILES_${PN}-tests = " \
/usr/bin/test* \
/usr/share/tests-descriptions/* \
"
FILES_${PN}-demos = "/usr/share/demos/*"

All packages resulting from building a recipe are copied to the packaging deployment folder.
Depending on the environment configuration ipk packages or opkg packages can be used. In the
source tree these are located in <BUILDDIR>/tmp/deploy/ipk/ respectively
<BUILDDIR>/tmp/deploy/opkg. Packages are separated by the targeted platform. These packages
can be installed on the respective systems if a package management is available. The usual
operation is the creation of the final image which is based on the packages in these folders.

5.9.9 do_clean
do_clean performs a cleanup of the whole working directory. Libraries and headers exported to the
staging directories are also deleted. This task is useful during the development of new recipes or the
introduction of major changes to existing recipes.

5.9.10 Extension of existing tasks


All build steps can be extended with the _append and _prepend mechanisms. It is important to match
the used syntax of the original task as declared in base.bblcass.

The following tasks can be extended using python code:


do_fetch

confidential Page 17 of 23
do_unpack
do_patch
do_stage
do_package

The following tasks can be extended using shell code:


do_configure
do_compile
do_install

Extensions to python code must match the indentation levels. In the base.bbclass a tabulator
character '\t' is used to separate these levels. Usually a single level should be sufficient. If greater
blocks of python code are required it may make sense to declare a function in a separate file and call
this function in an according _prepend or _append section.

A simple example changing file access rights after the common do_unpack task is given below. The
task is implemented in python.

do_unpack_append() {
os.system('chmod -R u+w ${S}')
}

This special extension arose from a problem where some SCMs (Source Code Management
systems) as Perforce or Synergy set file access rights to read-only. bitbake copies these sources in
the do_unpack task without changing the file access rights. Further tasks as do_patch need write
access to these files. The limited access rights result in a failure of the complete build. The above
code example sets the access rights of all files in the source directory ${S} to enable write access to
the complete directory.
Tasks with shell code can are extended in an similar way.

5.9.11 User-defined tasks


Developers are able to introduce new tasks for single or multiple recipes. Such a declaration contains
the name and the execution order related to the existing tasks.

addtask something [after task1] [before task2]

[python] do_something(){

}

The first line declares the order in which the task is executed. At least one of the two declarations
'before' or 'after' is required. The following identifier refers to an existing task. It is possible to use both
declarations in the same line. The python keyword in the next line indicates that the task is
implemented in python. If the implementation shall be done as shell code the python keyword is
omitted. After the 'python' keyword the task implementation is provided, starting with the task name.

6 Advanced
6.1 Devshell
devshell is an extra task that can be used when working on a local machine (either virtual machine or
native build host). When working on a remote system, i.e. a build server the use of the devshell
feature is more complicated. Ssh communication with X forwarding is required to display the
upcoming devshell window. For further explanation about X forwarding refer to the man page of ssh,
especially the switches -X and -Y.

confidential Page 18 of 23
The devshell is a shell with the prompt in the current working directory. The build environment
consisting of compiler and tools is already correctly declared. The devshell is very useful when
creating new recipes based upon existing code. It is possible to introduce code fixes and creating
patches out of the fixes. Depending on the origin of the source code changes can be directly
commited to svn/git.
The devshell can be used to call configure scripts, compiler and linker with a higher verbosity or log
level. This advanced verbosity is useful when examining build failures.

6.1.1 find and grep


The find and grep tools are very powerful in revealing the origin of dependencies and implementation
details in base classes. find can be used to search for files matching a pattern. Suppose a recipe
contains a dependency to dlt. find can be used to reveal the source of the dlt recipe in a collection.
This can be useful when exploring recipes inside a provided collection or having several
implementations or versions of a package. The following example requires that the private working
directory is the project root.

find ./tmp/collections -name '*dlt*.bb'

A possible output could be the following:

./tmp/collections/genivi-compliance-1201031414/genivi-
compliance/recipes/dlt/dlt-viewer_2.2.0.bb
./tmp/collections/genivi-compliance-1201031414/genivi-
compliance/recipes/dlt/dlt-viewer_2.3.0.bb
./tmp/collections/genivi-compliance-1201031414/genivi-
compliance/recipes/dlt/dlt-daemon_2.2.0.bb
./tmp/collections/genivi-compliance-1201031414/genivi-
compliance/recipes/dlt/dlt-daemon_2.3.0.bb

The grep tool is useful to reveal the origin of declarations, independent in what file the declaration is
made. Suppose the meaning of the expression EXTRA_OECMAKE is unclear.

A call to

grep -R "EXTRA_OECMAKE" ./tmp/collections

reveals declarations and invocations of the given expression. Compared to find the complete line with
the found statement is printed to the console.

. /tmp/collections/genivi-updates-1201040908/genivi-
updates/classes/cmake.bbclass: ${EXTRA_OECMAKE} \
./tmp/collections/genivi-compliance-1201031414/genivi-
compliance/recipes/layer-management/layer-management_0.8.1.bb:EXTRA_OECMAKE
= "-DGLESv2_INCLUDE_DIR=${STAGING_INCDIR} \
./tmp/collections/genivi-compliance-1201031414/genivi-
compliance/recipes/layer-management/layer-management_0.9.3.bb:EXTRA_OECMAKE
= "-DGLESv2_INCLUDE_DIR=${STAGING_INCDIR} \
./tmp/collections/genivi-compliance-1201031414/genivi-
compliance/recipes/cmake/cmake_2.8.3.bb:EXTRA_OECMAKE=" \

The find command is usually required to find recipe files providing certain functionality whilst the grep
command is used to reveal the origin of declarations.

6.1.2 creating patches


Patches can be created with the diff tool in a Unix environment. It is important to start the diff tool in
the correct directory. When using the devshell task of the bitbake tool chain the folder is already

confidential Page 19 of 23
correct. Without the devshell task the working directory for a given package is used (see section 2.2.1
for the exact location).
Diff can be used to compare whole directory trees or single files. Diff is invoked with references to old
and new file:

diff -ru <old file> <new file>

The -r flag tells diff to recursively scan complete directory hierarchies. The -u flag results in the unified
diff format that is required for the creation of patches.
If changes in multiple files shall be covered by a single patch file the whole directory tree can be
compared. The most convenient way to achieve this is to create a backup of the original folder and
copy all contents to a second folder which will then contain the changes. In the following example the
original data is located in the folder 'dlt-daemon-save'. The folder 'dlt-daemon' is a copy with all
required changes applied. The pipe operator in the shell environment '>' can be used to generate the
patch file out of the diff tool output.

cd <WORKDIR>
diff -ru dlt-daemon-save dlt-daemon > directory-diff.patch

To create patches for single files a similar technique is applied. After creating a backup ('configure-
save.ac' in the following example) the changes are applied to the original file ('configure.ac'). The diff
tool is invoked from the same directory as before but contains references to the two single files.

cd <WORKDIR>
diff -ru dlt-daemon/configure-save.ac dlt-daemon/configure.ac > file-
diff.patch

As next step the patch files are copied into the recipe folder (using a subfolder either named 'files' or
containing the recipe name). The patch is finally registered in the recipe by adding a line to
'SRC_URI'.

SRC_URI += "file-diff.patch;apply=yes"

The additional 'apply=yes' statement can be set to 'no' for testing purposes. The line with the correct
path of the patch does not have to be entirely deleted; therefore information is not lost and can easily
be reactivated.

6.2 Determining Dependencies of packages and build tasks


Dependencies of build tasks and packages can easily be determined with the output of the

bitbake -g <package>

call.

Three files are created as a result. The first file 'package-depends.dot' contains the dependencies on
package-level. This file contains all dependencies of the sub packages <PN>, <PN>-dev, <PN>-dbg
and <PN>-locale, where <PN> is the package name. All other sub packages declared by the user (for
example <PN>-tools) are also included.

"wayland-ivi" -> "wayland"

A second file 'pn-depends.dot' declares the origin of the recipe a package. It contains package
names, package version including revision and the recipe filename.

"wayland-ivi" [label="wayland-ivi :0.0.1-r1\n


<ROOTPATH>/tmp/collections/Graphics/Graphics/wayland/wayland-ivi_0.0.1.bb"]

confidential Page 20 of 23
The third file 'task-depends.dot' declares precedence among the tasks. These declarations are not
limited to tasks of the same package. A task of package A often depends on another task in package
B.

"wayland-xse-clients.do_package" -> "shasum-native.do_package"


"wayland-xse-clients.do_package" -> "wayland-xse-clients.do_install"

These files are generated upon specific project configuration. They are useful to understand and
determine the build behavior of bitbake in a specific platform based project. These files can be used
to uncover reasons for the inclusion of a specific package. In many cases the declarations in
'DEPENDS += ' introduce recursive dependencies that contain wrong packages.

These files are valid graphs in the dot syntax. Using the Unix command-line tool 'dot' or the GUI
based Graphviz tool chain graphs can be generated. However the usability of this feature is limited as
these three files contain such large numbers of nodes that the resulting graph usually does not fit on a
screen page. The examination of these files with a common text editor is more practicable.

6.3 Virtual packages


Virtual packages are used to declare a common interface that is provided by multiple recipes. The
configuration in each project offers the possibility to switch between different implementations of the
given functionality without changing the recipe files themselves. Using virtual packages a single
collection can be used in different projects or for different platforms with different constraints. The
configuration of the project contains the declaration of the actual implementation. A package can be
declared to provide a virtual interface by adding

PROVIDES += "virtual/<functionality>"

to the recipe. The package additionally provides the usual functionality.

Example:
A package 'amd-gpu' provides the functionality 'amd-gpu' and 'virtual/gpu' at the same time. It can be
referred by both names. Suppose that a recipe 'osg' in a specific collection has dependencies to a
graphics driver with the actual implementation varying between different projects/platforms. The effort
of providing several recipes for the different platforms can be avoided by declaring the dependency of
the 'osg' recipe to 'virtual/gpu' in a single recipe. Each project contains its own recipe file containing a
different implementation of 'virtual/gpu'. This project specific recipe can be part of a platform specific
collection.

A recipe referring to a virtual interface declares one of the following statements

DEPENDS += "virtual/<functionality>"
RDEPENDS += "virtual/<functionality>"

6.4 Precedence of recipe versions


The default behavior of bitbake when finding different versions of the same package is to take the
most recent one. The version number is retrieved from either the recipe name or the 'PV='
declarations. The user can influence this behavior by changing the value of
DEFAULT_PREFERENCE. Usually all packages use the standard value of '0' when no explicit
declaration is made.

Bitbake will always choose the recipe with the highest version containing the highest value. Suppose
three versions 1.1, 1.2 and 1.3 of a package are provided. Without any other information bitbake will
chose version 1.3 as it is the highest version number. By setting the DEFAULT_PREFERENCE of
version 1.2 to a value higher than '0' this version will now be taken by default. Setting the precedence
of version 1.2 to '-1' leads to the selection of version 1.3 as it is the highest version number with the
highest preference. When setting both version 1.2 and 1.3 to a precedence of'-1' version 1.1 will be
chosen.

confidential Page 21 of 23
It is possible to introduce precedence rules based on different platforms. In that case the platform
identifier as given in the platform declaration is appended to the DEFAULT_PREFERENCE keyword.

DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_imx6qsb = "1"

These declarations would lead to the selection of version 1.3 for the imx6qsb platform while using
version 1.2 for all other platforms.

6.5 Setting preferred providers and versions


When using virtual interfaces or several versions of the same package the preferred providers and
versions can be used to clarify which version of the package shall be used. These declarations are
located in project-specific or at least collection-specific configuration.

A preferred provider is declared by appending the package name and provider to the keyword
'PREFERRED_PROVIDER'. A preferred is always used in conjunction with a functionality declared as
virtual/<>.
The 'PREFERRED_VERSION' can be used to declare preferred versions of all packages (either
virtual or usual packages). The declaration is similar to that of the preferred provider. A preferred
version always overrides default preference settings as explained in section 6.4.

PREFERRED_PROVIDER_virtual/gpu = "amd-gpu"
PREFERRED_VERSION_virtual/gpu = "0.2.5"

PREFERRED_VERSION_dlt-daemon = "1.5.4"

PREFERRED_VERSION_libungif = "2.9.1"
PREFERRED_VERSION_libungif_imx53qsb = "2.8.8"

There are cases where the most recent version of a package may not be working for a specific
platform. In that case an older version from the collection can be used. The declarations about
preferred provider and version enable collections to be used across a huge number of projects at the
same time.

confidential Page 22 of 23
Appendix A: Documents

Document Reference

Appendix B: Abbreviations

Abbreviation Description

confidential Page 23 of 23

You might also like