1000 lines
48 KiB
XML
1000 lines
48 KiB
XML
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
|
|
|
<chapter id='extendpoky'>
|
|
|
|
<title>Extending Poky</title>
|
|
<para>
|
|
This section provides information about how to extend the functionality
|
|
already present in Poky.
|
|
The section also documents standard tasks such as adding new
|
|
software packages, extending or customizing images or porting Poky to
|
|
new hardware (adding a new machine).
|
|
Finally, the section contains advice about how
|
|
to make changes to Poky to achieve the best results.
|
|
</para>
|
|
|
|
<section id='usingpoky-extend-addpkg'>
|
|
<title>Adding a Package</title>
|
|
<para>
|
|
To add a package into Poky you need to write a recipe for it.
|
|
Writing a recipe means creating a <filename>.bb</filename> file that sets some
|
|
variables.
|
|
For information on variables that are useful for recipes and for information about recipe naming
|
|
issues, see <link linkend='ref-varlocality-recipe-required'>Recipe Variables - Required</link>
|
|
appendix.
|
|
</para>
|
|
<para>
|
|
Before writing a recipe from scratch it is often useful to check
|
|
whether someone else has written one already.
|
|
OpenEmbedded is a good place to look as it has a wider scope and range of packages.
|
|
Because Poky aims to be compatible with OpenEmbedded, most recipes should
|
|
just work in Poky.
|
|
</para>
|
|
<para>
|
|
For new packages, the simplest way to add a recipe is to base it on a similar
|
|
pre-existing recipe.
|
|
Following are some examples showing how to add standard types of packages:
|
|
</para>
|
|
|
|
<section id='usingpoky-extend-addpkg-singlec'>
|
|
<title>Single .c File Package (Hello World!)</title>
|
|
<para>
|
|
Building an application from a single file that is stored locally (e.g. under
|
|
<filename>files/</filename>) requires a recipe that has the file listed in
|
|
the <glossterm><link linkend='var-SRC_URI'>SRC_URI</link></glossterm> variable.
|
|
Additionally, you need to manually write the <function>do_compile</function> and
|
|
<function>do_install</function> tasks.
|
|
The <glossterm><link linkend='var-S'>S</link></glossterm> variable defines the
|
|
directory containing the source code, which is set to <glossterm><link linkend='var-WORKDIR'>
|
|
WORKDIR</link></glossterm> in this case - the directory BitBake uses for the build.
|
|
</para>
|
|
<programlisting>
|
|
DESCRIPTION = "Simple helloworld application"
|
|
SECTION = "examples"
|
|
LICENSE = "MIT"
|
|
PR = "r0"
|
|
|
|
SRC_URI = "file://helloworld.c"
|
|
|
|
S = "${WORKDIR}"
|
|
|
|
do_compile() {
|
|
${CC} helloworld.c -o helloworld
|
|
}
|
|
|
|
do_install() {
|
|
install -d ${D}${bindir}
|
|
install -m 0755 helloworld ${D}${bindir}
|
|
}
|
|
</programlisting>
|
|
<para>
|
|
By default, the "helloworld", "helloworld-dbg" and "hellworld-dev"
|
|
packages are built.
|
|
For information on how to customize the packaging process, see
|
|
<link linkend='usingpoky-extend-addpkg-files'>Controlling Package Content</link>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-addpkg-autotools'>
|
|
<title>Autotooled Package</title>
|
|
<para>
|
|
Applications that use autotools such as <filename>autoconf</filename> and
|
|
<filename>automake</filename> require a recipe that has a source archive listed in
|
|
<glossterm><link linkend='var-SRC_URI'>SRC_URI</link></glossterm> and
|
|
<filename>also inherits autotools</filename>, which instructs BitBake to use the
|
|
<filename>autotools.bbclass</filename> containing the definitions of all the steps
|
|
needed to build an autotooled application.
|
|
The result of the build is automatically packaged.
|
|
And, if the application uses NLS for localization, packages with local information are
|
|
generated (one package per language).
|
|
Following is one example (<filename>hello_2.2.bb</filename>)
|
|
</para>
|
|
<programlisting>
|
|
DESCRIPTION = "GNU Helloworld application"
|
|
SECTION = "examples"
|
|
LICENSE = "GPLv2+"
|
|
LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
|
|
PR = "r0"
|
|
|
|
SRC_URI = "${GNU_MIRROR}/hello/hello-${PV}.tar.gz"
|
|
|
|
inherit autotools gettext
|
|
</programlisting>
|
|
<para>
|
|
<glossterm><link linkend='var-LIC_FILES_CHKSUM'>LIC_FILES_CHKSUM</link>
|
|
</glossterm> is used to <link linkend='usingpoky-configuring-LIC_FILES_CHKSUM'>
|
|
track source license change</link>.
|
|
You can quickly create autotool-based recipes in a manner similar to the previous example.
|
|
</para>
|
|
|
|
</section>
|
|
<section id='usingpoky-extend-addpkg-makefile'>
|
|
<title>Makefile-Based Package</title>
|
|
<para>
|
|
Applications that use GNU <filename>make</filename> also require a recipe that has
|
|
the source archive listed in <glossterm><link linkend='var-SRC_URI'>SRC_URI</link></glossterm>.
|
|
You do not need to add a <function>do_compile</function> step since by default BitBake
|
|
starts the <filename>make</filename> command to compile the application.
|
|
If you need additional <filename>make</filename> options you should store them in the
|
|
<glossterm><link linkend='var-EXTRA_OEMAKE'>EXTRA_OEMAKE</link></glossterm> variable.
|
|
Bitbake passes these options into the <filename>make</filename> GNU invocation.
|
|
Note that a <function>do_install</function> task is still required.
|
|
Otherwise BitBake runs an empty <function>do_install</function> task by default.
|
|
</para>
|
|
<para>
|
|
Some applications might require extra parameters to be passed to the compiler.
|
|
For example the application might need an additional header path.
|
|
You can accomplish this by adding to the <glossterm><link linkend='var-CFLAGS'>CFLAGS</link>
|
|
</glossterm> variable.
|
|
The following example shows this:
|
|
</para>
|
|
<programlisting>
|
|
CFLAGS_prepend = "-I ${S}/include "
|
|
</programlisting>
|
|
<para>
|
|
In the following example <filename>mtd-utils</filename> is a Makefile-based package:
|
|
</para>
|
|
<programlisting>
|
|
DESCRIPTION = "Tools for managing memory technology devices."
|
|
SECTION = "base"
|
|
DEPENDS = "zlib lzo e2fsprogs util-linux"
|
|
HOMEPAGE = "http://www.linux-mtd.infradead.org/"
|
|
LICENSE = "GPLv2"
|
|
|
|
SRC_URI = "git://git.infradead.org/mtd-utils.git;protocol=git;tag=v${PV}"
|
|
|
|
S = "${WORKDIR}/git/"
|
|
|
|
EXTRA_OEMAKE = "'CC=${CC}' 'CFLAGS=${CFLAGS} -I${S}/include -DWITHOUT_XATTR' \
|
|
'BUILDDIR=${S}'"
|
|
|
|
do_install () {
|
|
oe_runmake install DESTDIR=${D} SBINDIR=${sbindir} MANDIR=${mandir} \
|
|
INCLUDEDIR=${includedir}
|
|
install -d ${D}${includedir}/mtd/
|
|
for f in ${S}/include/mtd/*.h; do
|
|
install -m 0644 $f ${D}${includedir}/mtd/
|
|
done
|
|
}
|
|
</programlisting>
|
|
|
|
</section>
|
|
<section id='usingpoky-extend-addpkg-files'>
|
|
<title>Controlling Package Content</title>
|
|
<para>
|
|
You can use the variables <glossterm><link linkend='var-PACKAGES'>PACKAGES</link></glossterm> and
|
|
<glossterm><link linkend='var-FILES'>FILES</link></glossterm> to split an application into
|
|
multiple packages.
|
|
</para>
|
|
<para>
|
|
Following is an example that uses the "libXpm" recipe (<filename>libxpm_3.5.7.bb</filename>).
|
|
By default, the "libXpm" recipe generates a single package containing the library, along
|
|
with a few binaries.
|
|
You can modify the recipe to split the binaries into separate packages:
|
|
</para>
|
|
<programlisting>
|
|
require xorg-lib-common.inc
|
|
|
|
DESCRIPTION = "X11 Pixmap library"
|
|
LICENSE = "X-BSD"
|
|
DEPENDS += "libxext libsm libxt"
|
|
PR = "r3"
|
|
PE = "1"
|
|
|
|
XORG_PN = "libXpm"
|
|
|
|
PACKAGES =+ "sxpm cxpm"
|
|
FILES_cxpm = "${bindir}/cxpm"
|
|
FILES_sxpm = "${bindir}/sxpm"
|
|
</programlisting>
|
|
<para>
|
|
In the previous example we want to ship the "sxpm" and "cxpm" binaries
|
|
in separate packages.
|
|
Since "bindir" would be packaged into the main
|
|
<glossterm><link linkend='var-PN'>PN</link></glossterm>
|
|
package by default, we prepend the <glossterm><link linkend='var-PACKAGES'>PACKAGES</link>
|
|
</glossterm> variable so additional package names are added to the start of list.
|
|
This results in the extra <glossterm><link linkend='var-FILES'>FILES</link></glossterm>_*
|
|
variables then containing information defining which files and
|
|
directories go into which package.
|
|
Files included by earlier packages are skipped by latter packages.
|
|
Thus, the main <glossterm><link linkend='var-PN'>PN</link></glossterm> package does not include
|
|
the above listed files.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-addpkg-postinstalls'>
|
|
<title>Post Install Scripts</title>
|
|
|
|
<para>
|
|
To add a post-installation script to a package, add a <function>pkg_postinst_PACKAGENAME()
|
|
</function> function to the <filename>.bb</filename> file and use
|
|
<filename>PACKAGENAME</filename> as the name of the package you want to attach to the
|
|
<filename>postinst</filename> script.
|
|
Normally <glossterm><link linkend='var-PN'>PN</link></glossterm> can be used, which
|
|
automatically expands to PACKAGENAME.
|
|
A post-installation function has the following structure:
|
|
</para>
|
|
<programlisting>
|
|
pkg_postinst_PACKAGENAME () {
|
|
#!/bin/sh -e
|
|
# Commands to carry out
|
|
}
|
|
</programlisting>
|
|
<para>
|
|
The script defined in the post-installation function is called when the rootfs is made.
|
|
If the script succeeds, the package is marked as installed.
|
|
If the script fails, the package is marked as unpacked and the script is
|
|
executed when the image boots again.
|
|
</para>
|
|
<para>
|
|
Sometimes it is necessary for the execution of a post-installation
|
|
script to be delayed until the first boot.
|
|
For example, the script might need to be executed on the device itself.
|
|
To delay script execution until boot time, use the following structure for the
|
|
post-installation script:
|
|
</para>
|
|
<programlisting>
|
|
pkg_postinst_PACKAGENAME () {
|
|
#!/bin/sh -e
|
|
if [ x"$D" = "x" ]; then
|
|
# Actions to carry out on the device go here
|
|
else
|
|
exit 1
|
|
fi
|
|
}
|
|
</programlisting>
|
|
<para>
|
|
The previous example delays execution until the image boots again because the
|
|
<glossterm><link linkend='var-D'>D</link></glossterm> variable points
|
|
to the 'image' directory when the rootfs is being made at build time but
|
|
is unset when executed on the first boot.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-customimage'>
|
|
<title>Customising Images</title>
|
|
<para>
|
|
You can customize Poky images to satisfy particular requirements.
|
|
This section describes several methods and provides guidelines for each.
|
|
</para>
|
|
|
|
<section id='usingpoky-extend-customimage-custombb'>
|
|
<title>Customising Images Using Custom .bb Files</title>
|
|
<para>
|
|
One way to get additional software into an image is to create a custom image.
|
|
The following example shows the form for the two lines you need:
|
|
</para>
|
|
<programlisting>
|
|
IMAGE_INSTALL = "task-poky-x11-base package1 package2"
|
|
|
|
inherit poky-image
|
|
</programlisting>
|
|
<para>
|
|
By creating a custom image, a developer has total control
|
|
over the contents of the image.
|
|
It is important to use the correct names of packages in the
|
|
<glossterm><link linkend='var-IMAGE_INSTALL'>IMAGE_INSTALL</link></glossterm> variable.
|
|
You must use the OpenEmbedded notation and not the Debian notation for the names
|
|
(e.g. "glibc-dev" instead of "libc6-dev").
|
|
</para>
|
|
<para>
|
|
The other method for creating a custom image is to modify an existing image.
|
|
For example, if a developer wants to add "strace" into "poky-image-sato", they can use
|
|
the following recipe:
|
|
</para>
|
|
<programlisting>
|
|
require poky-image-sato.bb
|
|
|
|
IMAGE_INSTALL += "strace"
|
|
</programlisting>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-customimage-customtasks'>
|
|
<title>Customising Images Using Custom Tasks</title>
|
|
<para>
|
|
For complex custom images, the best approach is to create a custom task package
|
|
that is used to build the image or images.
|
|
A good example of a tasks package is <filename>meta/recipes-sato/tasks/task-poky.bb
|
|
</filename>.
|
|
The <glossterm><link linkend='var-PACKAGES'>PACKAGES</link></glossterm>
|
|
variable lists the task packages to build along with the complementary
|
|
-dbg and -dev packages.
|
|
For each package added, you can use
|
|
<glossterm><link linkend='var-PACKAGES'>RDEPENDS</link></glossterm>
|
|
and <glossterm><link linkend='var-PACKAGES'>RRECOMMENDS</link></glossterm>
|
|
entries to provide a list of packages the parent task package should contain.
|
|
Following is an example:
|
|
</para>
|
|
<para>
|
|
<programlisting>
|
|
DESCRIPTION = "My Custom Tasks"
|
|
|
|
PACKAGES = "\
|
|
task-custom-apps \
|
|
task-custom-apps-dbg \
|
|
task-custom-apps-dev \
|
|
task-custom-tools \
|
|
task-custom-tools-dbg \
|
|
task-custom-tools-dev \
|
|
"
|
|
|
|
RDEPENDS_task-custom-apps = "\
|
|
dropbear \
|
|
portmap \
|
|
psplash"
|
|
|
|
RDEPENDS_task-custom-tools = "\
|
|
oprofile \
|
|
oprofileui-server \
|
|
lttng-control \
|
|
lttng-viewer"
|
|
|
|
RRECOMMENDS_task-custom-tools = "\
|
|
kernel-module-oprofile"
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
In the previous example, two task packages are created with their dependencies and their
|
|
recommended package dependencies listed: <filename>task-custom-apps</filename>, and
|
|
<filename>task-custom-tools</filename>.
|
|
To build an image using these task packages, you need to add
|
|
"task-custom-apps" and/or "task-custom-tools" to <glossterm><link
|
|
linkend='var-IMAGE_INSTALL'>IMAGE_INSTALL</link></glossterm> or other forms
|
|
of image dependencies as described in other areas of this section.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-customimage-imagefeatures'>
|
|
<title>Customising Images Using Custom <glossterm>
|
|
<link linkend='var-IMAGE_FEATURES'>IMAGE_FEATURES</link></glossterm></title>
|
|
<para>
|
|
Ultimately users might want to add extra image "features" as used by Poky with the
|
|
<glossterm><link linkend='var-IMAGE_FEATURES'>IMAGE_FEATURES</link></glossterm>
|
|
variable.
|
|
To create these features, the best reference is
|
|
<filename>meta/classes/poky-image.bbclass</filename>, which shows how poky achieves this.
|
|
In summary, the file looks at the contents of the
|
|
<glossterm><link linkend='var-IMAGE_FEATURES'>IMAGE_FEATURES</link></glossterm>
|
|
variable and then maps them into a set of tasks or packages.
|
|
Based on this information the <glossterm><link linkend='var-IMAGE_INSTALL'> IMAGE_INSTALL</link>
|
|
</glossterm> variable is generated automatically.
|
|
Users can add extra features by extending the class or creating a custom class for use
|
|
with specialized image <filename>.bb</filename> files.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-customimage-localconf'>
|
|
<title>Customising Images Using local.conf</title>
|
|
<para>
|
|
It is possible to customise image contents by abusing variables used by distribution
|
|
maintainers in local.conf.
|
|
This method only allows the addition of packages and is not recommended.
|
|
</para>
|
|
<para>
|
|
For example, to add the "strace" package into the image the you would add this to the
|
|
<filename>local.conf</filename> file:
|
|
</para>
|
|
<programlisting>
|
|
DISTRO_EXTRA_RDEPENDS += "strace"
|
|
</programlisting>
|
|
<para>
|
|
However, since the <glossterm><link linkend='var-DISTRO_EXTRA_RDEPENDS'>
|
|
DISTRO_EXTRA_RDEPENDS</link></glossterm> variable is for
|
|
distribution maintainers, adding packages using this method is not as simple as adding
|
|
them using a custom <filename>.bb</filename> file.
|
|
Using the <filename>local.conf</filename> file method could result in some packages
|
|
requiring recreation.
|
|
For example, if packages were previously created and the image was rebuilt then the packages
|
|
would need to be recreated.
|
|
</para>
|
|
<para>
|
|
Cleaning task-* packages is required because they use the
|
|
<glossterm><link linkend='var-DISTRO_EXTRA_RDEPENDS'>
|
|
DISTRO_EXTRA_RDEPENDS</link></glossterm> variable.
|
|
You do not have to build them by hand because Poky images depend on the packages they contain.
|
|
This means dependencies are automatically built when the image builds.
|
|
For this reason we don't use the "rebuild" task.
|
|
In this case the "rebuild" task does does not care about
|
|
dependencies - it only rebuilds the specified package.
|
|
</para>
|
|
<programlisting>
|
|
bitbake -c clean task-boot task-base task-poky
|
|
bitbake poky-image-sato
|
|
</programlisting>
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section id="platdev-newmachine">
|
|
<title>Porting Poky to a New Machine</title>
|
|
<para>
|
|
Adding a new machine to Poky is a straightforward process.
|
|
This section provides information that gives you an idea of the changes you must make.
|
|
The information covers adding machines similar to those Poky already supports.
|
|
Although well within the capabilities of Poky, adding a totally new architecture might require
|
|
changes to <filename>gcc/glibc</filename> and to the site information.
|
|
Consequently, the information is beyond the scope of this manual.
|
|
</para>
|
|
|
|
<section id="platdev-newmachine-conffile">
|
|
<title>Adding the Machine Configuration File</title>
|
|
<para>
|
|
To add a machine configuration you need to add a <filename>.conf</filename> file
|
|
with details of the device being added to <filename>conf/machine/</filename>.
|
|
The name of the file determines the name Poky uses to reference the new machine.
|
|
</para>
|
|
<para>
|
|
The most important variables to set in this file are <glossterm>
|
|
<link linkend='var-TARGET_ARCH'>TARGET_ARCH</link></glossterm>
|
|
(e.g. "arm"), <glossterm><link linkend='var-PREFERRED_PROVIDER'>
|
|
PREFERRED_PROVIDER</link></glossterm>_virtual/kernel (see below) and
|
|
<glossterm><link linkend='var-MACHINE_FEATURES'>MACHINE_FEATURES
|
|
</link></glossterm> (e.g. "kernel26 apm screen wifi").
|
|
You might also need other variables like <glossterm><link linkend='var-SERIAL_CONSOLE'>SERIAL_CONSOLE
|
|
</link></glossterm> (e.g. "115200 ttyS0"), <glossterm>
|
|
<link linkend='var-KERNEL_IMAGETYPE'>KERNEL_IMAGETYPE</link>
|
|
</glossterm> (e.g. "zImage") and <glossterm><link linkend='var-IMAGE_FSTYPES'>
|
|
IMAGE_FSTYPES</link></glossterm> (e.g. "tar.gz jffs2").
|
|
You can find full details on these variables in the reference section.
|
|
You can leverage many existing machine <filename>.conf</filename> files from
|
|
<filename>meta/conf/machine/</filename>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id="platdev-newmachine-kernel">
|
|
<title>Adding a Kernel for the Machine</title>
|
|
<para>
|
|
Poky needs to be able to build a kernel for the machine.
|
|
You need to either create a new kernel recipe for this machine, or extend an
|
|
existing recipe.
|
|
You can find several kernel examples in the <filename>meta/recipes-kernel/linux</filename>
|
|
directory that can be used as references.
|
|
</para>
|
|
<para>
|
|
If you are creating a new recipe, the "normal" recipe-writing rules apply for setting
|
|
up a <glossterm><link linkend='var-SRC_URI'>SRC_URI</link></glossterm>.
|
|
This means specifying any necessary patches and setting <glossterm>
|
|
<link linkend='var-S'>S</link></glossterm> to point at the source code.
|
|
You need to create a "configure" task that configures the unpacked kernel with a defconfig.
|
|
You can do this by using a <filename>make defconfig</filename> command or
|
|
more commonly by copying in a suitable defconfig and and then running
|
|
<filename>make oldconfig</filename>.
|
|
By making use of "inherit kernel" and potentially some of the
|
|
<filename>linux-*.inc</filename> files, most other functionality is
|
|
centralized and the the defaults of the class normally work well.
|
|
</para>
|
|
<para>
|
|
If you are extending an existing kernel, it is usually a matter of adding a
|
|
suitable <filename>defconfig</filename> file.
|
|
The file needs to be added into a location similar to <filename>defconfig</filename> files
|
|
used for other machines in a given kernel.
|
|
A possible way to do this is by listing the file in the
|
|
<glossterm><link linkend='var-SRC_URI'>SRC_URI</link></glossterm>
|
|
and adding the machine to the expression in
|
|
<glossterm><link linkend='var-COMPATIBLE_MACHINE'>COMPATIBLE_MACHINE</link></glossterm>:
|
|
</para>
|
|
<programlisting>
|
|
COMPATIBLE_MACHINE = '(qemux86|qemumips)'
|
|
</programlisting>
|
|
</section>
|
|
|
|
<section id="platdev-newmachine-formfactor">
|
|
<title>Adding a Formfactor Configuration File</title>
|
|
<para>
|
|
A formfactor configuration file provides information about the
|
|
target hardware on which Poky is running, and that Poky cannot
|
|
obtain from other sources such as the kernel. Some examples of
|
|
information contained in a formfactor configuration file include
|
|
framebuffer orientation, whether or not the system has a keyboard,
|
|
the positioning of the keyboard in relation to the screen, and
|
|
screen resolution.
|
|
</para>
|
|
<para>
|
|
Sane defaults should be used in most cases, but if customisation is
|
|
necessary you need to create a <filename>machconfig</filename> file
|
|
under <filename>meta/packages/formfactor/files/MACHINENAME/</filename>
|
|
where <literal>MACHINENAME</literal> is the name for which this infomation
|
|
applies. For information about the settings available and the defaults, please see
|
|
<filename>meta/packages/formfactor/files/config</filename>. Below is one
|
|
example for qemuarm:
|
|
</para>
|
|
<programlisting>
|
|
HAVE_TOUCHSCREEN=1
|
|
HAVE_KEYBOARD=1
|
|
|
|
DISPLAY_CAN_ROTATE=0
|
|
DISPLAY_ORIENTATION=0
|
|
#DISPLAY_WIDTH_PIXELS=640
|
|
#DISPLAY_HEIGHT_PIXELS=480
|
|
#DISPLAY_BPP=16
|
|
DISPLAY_DPI=150
|
|
DISPLAY_SUBPIXEL_ORDER=vrgb
|
|
</programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='usingpoky-changes'>
|
|
<title>Making and Maintaining Changes</title>
|
|
|
|
<para>
|
|
We recognise that people will want to extend/configure/optimise Poky for
|
|
their specific uses, especially due to the extreme configurability and
|
|
flexibility Poky offers. To ensure ease of keeping pace with future
|
|
changes in Poky we recommend making changes to Poky in a controlled way.
|
|
</para>
|
|
<para>
|
|
Poky supports the idea of <link
|
|
linkend='usingpoky-changes-layers'>"layers"</link> which when used
|
|
properly can massively ease future upgrades and allow segregation
|
|
between the Poky core and a given developer's changes. Some other advice on
|
|
managing changes to Poky is also given in the following section.
|
|
</para>
|
|
|
|
<section id="usingpoky-changes-layers">
|
|
<title>Bitbake Layers</title>
|
|
|
|
<para>
|
|
Often, people want to extend Poky either through adding packages
|
|
or overriding files contained within Poky to add their own
|
|
functionality. Bitbake has a powerful mechanism called
|
|
layers which provides a way to handle this extension in a fully
|
|
supported and non-invasive fashion.
|
|
</para>
|
|
|
|
<para>
|
|
The Poky tree includes several additional layers which demonstrate
|
|
this functionality, such as meta-emenlow and meta-extras.
|
|
The meta-emenlow layer is an example layer enabled by default. The meta-extras
|
|
repostory is not enabled by default but enabling any layer is as easy as adding
|
|
the layers path to the BBLAYERS variable in your bblayers.conf. this is how
|
|
meta-extras are enabled in Poky builds:
|
|
</para>
|
|
<para>
|
|
<literallayout class='monospaced'>LCONF_VERSION = "1"
|
|
|
|
BBFILES ?= ""
|
|
BBLAYERS = " \
|
|
/path/to/poky/meta \
|
|
/path/to/poky/meta-emenlow \
|
|
/path/to/poky/meta-extras \
|
|
"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Bitbake parses the conf/layer.conf of each of the layers in BBLAYERS
|
|
to add the recipes, classes and configuration contained within the layer to Poky.
|
|
To create your own layer, independent of the main Poky repository,
|
|
you need only create a directory with a conf/layer.conf file and
|
|
add the directory to your bblayers.conf.
|
|
</para>
|
|
|
|
<para>
|
|
The meta-emenlow/conf/layer.conf demonstrates the required syntax:
|
|
<literallayout class='monospaced'># We have a conf and classes directory, add to BBPATH
|
|
BBPATH := "${BBPATH}:${LAYERDIR}"
|
|
|
|
# We have a recipes directory containing both .bb and .bbappend files, add to BBFILES
|
|
BBFILES := "${BBFILES} ${LAYERDIR}/recipes/*/*.bb \
|
|
${LAYERDIR}/recipes/*/*.bbappend"
|
|
|
|
BBFILE_COLLECTIONS += "emenlow"
|
|
BBFILE_PATTERN_emenlow := "^${LAYERDIR}/"
|
|
BBFILE_PRIORITY_emenlow = "6"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
As can be seen, the layers recipes are added to
|
|
<glossterm> <link linkend='var-BBFILES'>BBFILES</link></glossterm>. The
|
|
BBFILE_COLLECTIONS variable is then appended to with the
|
|
layer name. The BBFILE_PATTERN variable is immediately expanded
|
|
with a regular expression used to match files from BBFILES into
|
|
a particular layer, in this case by using the base pathname.
|
|
The BBFILE_PRIORITY variable then assigns different
|
|
priorities to the files in different layers. This is useful
|
|
in situations where the same package might appear in multiple
|
|
layers and allows you to choose which layer should 'win'.
|
|
Note the use of <glossterm><link linkend='var-LAYERDIR'>
|
|
LAYERDIR</link></glossterm> with the immediate expansion operator.
|
|
<glossterm><link linkend='var-LAYERDIR'>LAYERDIR</link></glossterm>
|
|
expands to the directory of the current layer and
|
|
requires use of the immediate expansion operator so that Bitbake
|
|
does not lazily expand the variable when it's parsing a
|
|
different directory.
|
|
</para>
|
|
|
|
<para>
|
|
Additional bbclass and configuration files can be locationed by
|
|
bitbake through the addition to the BBPATH
|
|
environment variable. In this case, the first file with the
|
|
matching name found in BBPATH is the one that is used, just
|
|
like the PATH variable for binaries. It is therefore recommended
|
|
that you use unique bbclass and configuration file names in your
|
|
custom layer.
|
|
</para>
|
|
|
|
<para>
|
|
The recommended approach for custom layers is to store them in a
|
|
git repository of the format meta-prvt-XXXX and have this repository
|
|
cloned alongside the other meta directories in the Poky tree.
|
|
This way you can keep your Poky tree and it's configuration entirely
|
|
inside POKYBASE.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='usingpoky-changes-commits'>
|
|
<title>Committing Changes</title>
|
|
|
|
<para>
|
|
Modifications to Poky are often managed under some kind of source
|
|
revision control system. The policy for committing to such systems
|
|
is important as some simple policy can significantly improve
|
|
usability. The tips below are based on the policy followed for the
|
|
Poky core.
|
|
</para>
|
|
|
|
<para>
|
|
It helps to use a consistent style for commit messages when committing
|
|
changes. We've found a style where the first line of a commit message
|
|
summarises the change and starts with the name of any package affected
|
|
work well. Not all changes are to specific packages so the prefix could
|
|
also be a machine name or class name instead. If a change needs a longer
|
|
description this should follow the summary:
|
|
</para>
|
|
|
|
<literallayout class='monospaced'>
|
|
bitbake/data.py: Add emit_func() and generate_dependencies() functions
|
|
|
|
These functions allow generation of dependency data between funcitons and
|
|
variables allowing moves to be made towards generating checksums and allowing
|
|
use of the dependency information in other parts of bitbake.
|
|
|
|
Signed-off-by: Richard Purdie rpurdie@linux.intel.com
|
|
</literallayout>
|
|
|
|
<para>
|
|
Any commit should be self contained in that it should leave the
|
|
metadata in a consistent state, buildable before and after the
|
|
commit. This helps ensure the autobuilder test results are valid
|
|
but is good practice regardless.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='usingpoky-changes-prbump'>
|
|
<title>Package Revision Incrementing</title>
|
|
|
|
<para>
|
|
If a committed change will result in changing the package output
|
|
then the value of the <glossterm><link linkend='var-PR'>PR</link>
|
|
</glossterm> variable needs to be increased (commonly referred to
|
|
as 'bumped') as part of that commit. Only integer values are used
|
|
and <glossterm><link linkend='var-PR'>PR</link></glossterm> =
|
|
"r0" should be added into new recipes as, while this is the
|
|
default value, not having the variable defined in a recipe makes
|
|
it easy to miss incrementing it when updating the recipe.
|
|
When upgrading the version of a package (<glossterm><link
|
|
linkend='var-PV'>PV</link></glossterm>), the <glossterm><link
|
|
linkend='var-PR'>PR</link></glossterm> variable should be reset to "r0".
|
|
</para>
|
|
|
|
<para>
|
|
The aim is that the package version will only ever increase. If
|
|
for some reason <glossterm><link linkend='var-PV'>PV</link></glossterm>
|
|
will change and but not increase, the <glossterm><link
|
|
linkend='var-PE'>PE</link></glossterm> (Package Epoch) can
|
|
be increased (it defaults to '0'). The version numbers aim to
|
|
follow the <ulink url='http://www.debian.org/doc/debian-policy/ch-controlfields.html'>
|
|
Debian Version Field Policy Guidelines</ulink> which define how
|
|
versions are compared and hence what "increasing" means.
|
|
</para>
|
|
|
|
<para>
|
|
There are two reasons for doing this, the first is to ensure that
|
|
when a developer updates and rebuilds, they get all the changes to
|
|
the repository and don't have to remember to rebuild any sections.
|
|
The second is to ensure that target users are able to upgrade their
|
|
devices via their package manager such as with the <command>
|
|
opkg upgrade</command> commands (or similar for
|
|
dpkg/apt or rpm based systems). The aim is to ensure Poky has
|
|
upgradable packages in all cases.
|
|
</para>
|
|
</section>
|
|
<section id='usingpoky-changes-collaborate'>
|
|
<title>Using Poky in a Team Environment</title>
|
|
|
|
<para>
|
|
It may not be immediately clear how Poky can work in a team environment,
|
|
or scale to a large team of developers. The specifics of any situation
|
|
will determine the best solution and poky offers immense flexibility in
|
|
that aspect but there are some practises that experience has shown to work
|
|
well.
|
|
</para>
|
|
|
|
<para>
|
|
The core component of any development effort with Poky is often an
|
|
automated build testing framework and image generation process. This
|
|
can be used to check that the metadata is buildable, highlight when
|
|
commits break the builds and provide up to date images allowing people
|
|
to test the end result and use them as a base platform for further
|
|
development. Experience shows that buildbot is a good fit for this role
|
|
and that it works well to configure it to make two types of build -
|
|
incremental builds and 'from scratch'/full builds. The incremental builds
|
|
can be tied to a commit hook which triggers them each time a commit is
|
|
made to the metadata and are a useful acid test of whether a given commit
|
|
breaks the build in some serious way. They catch lots of simple errors
|
|
and whilst they won't catch 100% of failures, the tests are fast so
|
|
developers can get feedback on their changes quickly. The full builds
|
|
are builds that build everything from the ground up and test everything.
|
|
They usually happen at preset times such as at night when the machine
|
|
load isn't high from the incremental builds.
|
|
<ulink url='http://autobuilder.pokylinux.org:8010'>poky autobuilder</ulink>
|
|
is an example implementation with buildbot.
|
|
</para>
|
|
|
|
<para>
|
|
Most teams have pieces of software undergoing active development. It is of
|
|
significant benefit to put these under control of a source control system
|
|
compatible with Poky such as git or svn. The autobuilder can then be set to
|
|
pull the latest revisions of these packages so the latest commits get tested
|
|
by the builds allowing any issues to be highlighted quickly. Poky easily
|
|
supports configurations where there is both a stable known good revision
|
|
and a floating revision to test. Poky can also only take changes from specific
|
|
source control branches giving another way it can be used to track/test only
|
|
specified changes.
|
|
</para>
|
|
<para>
|
|
Perhaps the hardest part of setting this up is the policy that surrounds
|
|
the different source control systems, be them software projects or the Poky
|
|
metadata itself. The circumstances will be different in each case but this is
|
|
one of Poky's advantages - the system itself doesn't force any particular policy
|
|
unlike a lot of build systems, allowing the best policy to be chosen for the
|
|
circumstances.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='usingpoky-changes-updatingimages'>
|
|
<title>Updating Existing Images</title>
|
|
|
|
<para>
|
|
Often, rather than reflashing a new image you might wish to install updated
|
|
packages into an existing running system. This can be done by sharing the <filename class="directory">tmp/deploy/ipk/</filename> directory through a web server and then on the device, changing <filename>/etc/opkg/base-feeds.conf</filename> to point at this server, for example by adding:
|
|
</para>
|
|
<literallayout class='monospaced'>
|
|
src/gz all http://www.mysite.com/somedir/deploy/ipk/all
|
|
src/gz armv7a http://www.mysite.com/somedir/deploy/ipk/armv7a
|
|
src/gz beagleboard http://www.mysite.com/somedir/deploy/ipk/beagleboard</literallayout>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='usingpoky-modifing-packages'>
|
|
<title>Modifying Package Source Code</title>
|
|
|
|
<para>
|
|
Poky is usually used to build software rather than modifying
|
|
it. However, there are ways Poky can be used to modify software.
|
|
</para>
|
|
|
|
<para>
|
|
During building, the sources are available in <glossterm><link
|
|
linkend='var-WORKDIR'>WORKDIR</link></glossterm> directory.
|
|
Where exactly this is depends on the type of package and the
|
|
architecture of target device. For a standard recipe not
|
|
related to <glossterm><link
|
|
linkend='var-MACHINE'>MACHINE</link></glossterm> it will be
|
|
<filename>tmp/work/PACKAGE_ARCH-poky-TARGET_OS/PN-PV-PR/</filename>.
|
|
Target device dependent packages use <glossterm><link
|
|
linkend='var-MACHINE'>MACHINE
|
|
</link></glossterm>
|
|
instead of <glossterm><link linkend='var-PACKAGE_ARCH'>PACKAGE_ARCH
|
|
</link></glossterm>
|
|
in the directory name.
|
|
</para>
|
|
|
|
<tip>
|
|
<para>
|
|
Check the package recipe sets the <glossterm><link
|
|
linkend='var-S'>S</link></glossterm> variable to something
|
|
other than standard <filename>WORKDIR/PN-PV/</filename> value.
|
|
</para>
|
|
</tip>
|
|
<para>
|
|
After building a package, a user can modify the package source code
|
|
without problem. The easiest way to test changes is by calling the
|
|
"compile" task:
|
|
</para>
|
|
|
|
<programlisting>
|
|
bitbake -c compile -f NAME_OF_PACKAGE
|
|
</programlisting>
|
|
|
|
<para>
|
|
"-f" or "--force" is used to force re-execution of the specified task.
|
|
Other tasks may also be called this way. But note that all the modifications
|
|
in <glossterm><link linkend='var-WORKDIR'>WORKDIR</link></glossterm>
|
|
are gone once you executes "-c clean" for a package.
|
|
</para>
|
|
|
|
<section id='usingpoky-modifying-packages-quilt'>
|
|
<title>Modifying Package Source Code with quilt</title>
|
|
|
|
<para>
|
|
By default Poky uses <ulink
|
|
url='http://savannah.nongnu.org/projects/quilt'>quilt</ulink>
|
|
to manage patches in <function>do_patch</function> task.
|
|
It is a powerful tool which can be used to track all
|
|
modifications done to package sources.
|
|
</para>
|
|
|
|
<para>
|
|
Before modifying source code it is important to
|
|
notify quilt so it will track changes into new patch
|
|
file:
|
|
<programlisting>
|
|
quilt new NAME-OF-PATCH.patch
|
|
</programlisting>
|
|
|
|
Then add all files which will be modified into that
|
|
patch:
|
|
<programlisting>
|
|
quilt add file1 file2 file3
|
|
</programlisting>
|
|
|
|
Now start editing. At the end quilt needs to be used
|
|
to generate final patch which will contain all
|
|
modifications:
|
|
<programlisting>
|
|
quilt refresh
|
|
</programlisting>
|
|
|
|
The resulting patch file can be found in the
|
|
<filename class="directory">patches/</filename> subdirectory of the source
|
|
(<glossterm><link linkend='var-S'>S</link></glossterm>) directory. For future builds it
|
|
should be copied into
|
|
Poky metadata and added into <glossterm><link
|
|
linkend='var-SRC_URI'>SRC_URI</link></glossterm> of a recipe:
|
|
<programlisting>
|
|
SRC_URI += "file://NAME-OF-PATCH.patch"
|
|
</programlisting>
|
|
|
|
This also requires a bump of <glossterm><link
|
|
linkend='var-PR'>PR</link></glossterm> value in the same recipe as we changed resulting packages.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
<section id='usingpoky-configuring-LIC_FILES_CHKSUM'>
|
|
<title>Track license change</title>
|
|
<para>
|
|
The license of one upstream project may change in the future, and Poky provides
|
|
one mechanism to track such license change - <glossterm>
|
|
<link linkend='var-LIC_FILES_CHKSUM'>LIC_FILES_CHKSUM</link></glossterm> variable.
|
|
</para>
|
|
|
|
<section id='usingpoky-specifying-LIC_FILES_CHKSUM'>
|
|
<title>Specifying the LIC_FILES_CHKSUM variable </title>
|
|
|
|
<programlisting>
|
|
LIC_FILES_CHKSUM = "file://COPYING; md5=xxxx \
|
|
file://licfile1.txt; beginline=5; endline=29;md5=yyyy \
|
|
file://licfile2.txt; endline=50;md5=zzzz \
|
|
..."
|
|
</programlisting>
|
|
|
|
<para>
|
|
<glossterm><link linkend='var-S'>S</link></glossterm> is the default directory
|
|
for searching files listed in <glossterm><link linkend='var-LIC_FILES_CHKSUM'>
|
|
LIC_FILES_CHKSUM</link></glossterm>. Relative path could be used too:
|
|
</para>
|
|
|
|
<programlisting>
|
|
LIC_FILES_CHKSUM = "file://src/ls.c;startline=5;endline=16;\
|
|
md5=bb14ed3c4cda583abc85401304b5cd4e"
|
|
LIC_FILES_CHKSUM = "file://../license.html;md5=5c94767cedb5d6987c902ac850ded2c6"
|
|
</programlisting>
|
|
|
|
<para>
|
|
The first line locates a file in <glossterm><link linkend='var-S'>
|
|
S</link></glossterm>/src/ls.c, and the second line refers to a file in
|
|
<glossterm><link linkend='var-WORKDIR'>WORKDIR</link></glossterm>, which is the parent
|
|
of <glossterm><link linkend='var-S'>S</link></glossterm>
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section id='usingpoky-LIC_FILES_CHKSUM-explanation-of-syntax'>
|
|
<title>Explanation of syntax</title>
|
|
|
|
<para>
|
|
This parameter lists all the important files containing the text
|
|
of licenses for the
|
|
source code. It is also possible to specify on which line the license text
|
|
starts and on which line it ends within that file using the "beginline" and
|
|
"endline" parameters. If the "beginline" parameter is not specified then license
|
|
text begins from the 1st line is assumed. Similarly if "endline" parameter is
|
|
not specified then the license text ends at the last line in the file is
|
|
assumed. So if a file contains only licensing information, then there is no need
|
|
to specify "beginline" and "endline" parameters.
|
|
</para>
|
|
<para>
|
|
The "md5" parameter stores the md5 checksum of the license text. So if
|
|
the license text changes in any way from a file, then its md5 sum will differ and will not
|
|
match with the previously stored md5 checksum. This mismatch will trigger build
|
|
failure, notifying developer about the license text md5 mismatch, and allowing
|
|
the developer to review the license text changes. Also note that if md5 checksum
|
|
is not matched while building, the correct md5 checksum is printed in the build
|
|
log which can be easily copied to .bb file.
|
|
</para>
|
|
<para>
|
|
There is no limit on how many files can be specified on this parameter. But generally every
|
|
project would need specifying of just one or two files for license tracking.
|
|
Many projects would have a "COPYING" file which will store all the
|
|
license information for all the source code files. If the "COPYING" file
|
|
is valid then tracking only that file would be enough.
|
|
</para>
|
|
<tip>
|
|
<para>
|
|
1. If you specify empty or invalid "md5" parameter; then while building
|
|
the package, bitbake will give md5 not matched error, and also show the correct
|
|
"md5" parameter value both on the screen and in the build log
|
|
</para>
|
|
<para>
|
|
2. If the whole file contains only license text, then there is no need to
|
|
specify "beginline" and "endline" parameters.
|
|
</para>
|
|
</tip>
|
|
</section>
|
|
</section>
|
|
<section id='usingpoky-configuring-DISTRO_PN_ALIAS'>
|
|
<title>Handle package name alias</title>
|
|
<para>
|
|
Poky implements a distro_check task which automatically connects to major distributions
|
|
and checks whether they contains same package. Sometimes the same package has different
|
|
names in different distributions, which results in a mismatch from distro_check task
|
|
This can be solved by defining per distro recipe name alias -
|
|
<glossterm><link linkend='var-DISTRO_PN_ALIAS'>DISTRO_PN_ALIAS</link></glossterm>
|
|
</para>
|
|
|
|
<section id='usingpoky-specifying-DISTRO_PN_ALIAS'>
|
|
<title>Specifying the DISTRO_PN_ALIAS variable </title>
|
|
|
|
<programlisting>
|
|
DISTRO_PN_ALIAS_pn-PACKAGENAME = "distro1=package_name_alias1 \
|
|
distro2=package_name_alias2 \
|
|
distro3=package_name_alias3 \
|
|
..."
|
|
</programlisting>
|
|
<para>
|
|
Use space as the delimiter if there're multiple distro aliases
|
|
</para>
|
|
<tip>
|
|
<para>
|
|
The current code can check if the src package for a recipe exists in the latest
|
|
releases of these distributions automatically.
|
|
</para>
|
|
<programlisting>
|
|
Fedora, OpenSuSE, Debian, Ubuntu, Mandriva
|
|
</programlisting>
|
|
<para>
|
|
For example, this command will generate a report, listing which linux distros include the
|
|
sources for each of the poky recipe.
|
|
</para>
|
|
<programlisting>
|
|
bitbake world -f -c distro_check
|
|
</programlisting>
|
|
<para>
|
|
The results will be stored in the build/tmp/log/distro_check-${DATETIME}.results file.
|
|
</para>
|
|
</tip>
|
|
</section>
|
|
</section>
|
|
</chapter>
|
|
|
|
<!--
|
|
vim: expandtab tw=80 ts=4
|
|
-->
|