diff options
author | Cliff Brake <cbrake@bec-systems.com> | 2009-02-25 08:31:16 -0500 |
---|---|---|
committer | Cliff Brake <cbrake@bec-systems.com> | 2009-02-25 08:31:16 -0500 |
commit | 8a7ae36c691b44efdc1d0935535e850cc3ffc8d7 (patch) | |
tree | 37177e6be31e69978e175a336e501beb19724e47 /docs/usermanual | |
parent | cdbe198009d0b73bca24ae7aada4401ae2f0b630 (diff) | |
parent | 98238944c784e673cab4691a861f3d9fa61f85a4 (diff) |
Merge branch 'org.openembedded.dev' of git@git.openembedded.net:openembedded into org.openembedded.dev
Diffstat (limited to 'docs/usermanual')
31 files changed, 10839 insertions, 0 deletions
diff --git a/docs/usermanual/Makefile b/docs/usermanual/Makefile new file mode 100644 index 0000000000..5649442ed5 --- /dev/null +++ b/docs/usermanual/Makefile @@ -0,0 +1,60 @@ +topdir = . +manual = $(topdir)/usermanual.xml +# types = pdf txt rtf ps xhtml html man tex texi dvi +# types = pdf txt +types = $(xmltotypes) $(htmltypes) $(docbooktotypes) +xmltotypes = +docbooktotypes = dvi pdf ps rtf tex texi txt +htmltypes = html xhtml +htmlxsl = $(if $(filter $@,$(foreach type,$(htmltypes),$(type)-nochunks)),docbook-utf8.xsl,http://docbook.sourceforge.net/release/xsl/current/$@/chunk.xsl) +htmlcssfile = docbook.css +htmlcss = $(topdir)/html.css +# htmlcssfile = +# htmlcss = +cleanfiles = $(foreach i,$(types),$(topdir)/$(i)) + +ifdef DEBUG +define command + $(1) +endef +else +define command + @echo $(2) $(3) $(4) + @$(1) >/dev/null +endef +endif + +all: $(types) + +lint: $(manual) FORCE + $(call command,xmllint --xinclude --postvalid --noout $(manual),XMLLINT $(manual)) + +$(types) $(foreach type,$(htmltypes),$(type)-nochunks): lint FORCE + +$(foreach type,$(htmltypes),$(type)-nochunks): $(if $(htmlcss),$(htmlcss)) $(manual) + @mkdir -p $@ +ifdef htmlcss + $(call command,install -m 0644 $(htmlcss) $@/$(htmlcssfile),CP $(htmlcss) $@/$(htmlcssfile)) +endif + $(call command,xsltproc --stringparam base.dir $@/ $(if $(htmlcssfile),--stringparam html.stylesheet $(htmlcssfile)) $(htmlxsl) $(manual) > $@/index.$(patsubst %-nochunks,%,$@),XSLTPROC $@ $(manual)) + +$(htmltypes): $(if $(htmlcss),$(htmlcss)) $(manual) + @mkdir -p $@ +ifdef htmlcss + $(call command,install -m 0644 $(htmlcss) $@/$(htmlcssfile),CP $(htmlcss) $@/$(htmlcssfile)) +endif + $(call command,xsltproc --param use.id.as.filename 1 --stringparam base.dir $@/ $(if $(htmlcssfile),--stringparam html.stylesheet $(htmlcssfile)) $(htmlxsl) $(manual),XSLTPROC $@ $(manual)) + +$(xmltotypes): $(manual) + $(call command,xmlto --extensions -o $(topdir)/$@ $@ $(manual),XMLTO $@ $(manual)) + +$(docbooktotypes): $(manual) + $(call command,docbook2$@ $(manual),DOCBOOK2 $@ $(manual)) + +clean: + rm -rf $(cleanfiles) + +$(foreach i,$(types) $(foreach type,$(htmltypes),$(type)-nochunks),clean-$(i)): + rm -rf $(patsubst clean-%,%,$@) + +FORCE: diff --git a/docs/usermanual/README b/docs/usermanual/README new file mode 100644 index 0000000000..f2aecf8a6e --- /dev/null +++ b/docs/usermanual/README @@ -0,0 +1,18 @@ +To generate the user-manual, run: + + make <type> + +in this directory, where type is one of: + + xhtml + html + dvi + pdf + ps + rtf + tex + texi + txt + +For html and xhtml you need xsltproc installed. +For the other you need docbook-utils installed. diff --git a/docs/usermanual/chapters/.mtn2git_empty b/docs/usermanual/chapters/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/docs/usermanual/chapters/.mtn2git_empty diff --git a/docs/usermanual/chapters/common_use_cases.xml b/docs/usermanual/chapters/common_use_cases.xml new file mode 100644 index 0000000000..4497683fa9 --- /dev/null +++ b/docs/usermanual/chapters/common_use_cases.xml @@ -0,0 +1,409 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter id="chapter_common_use_cases"> + <title>Common Use-cases/tasks</title> + + <section id="commonuse_new_distro"> + <title>Creating a new Distribution</title> + + <para>Creating a new distribution is not complicated, however we urge you + to try existing distributions first, because it's also very easy to do + wrong. The config need to be created in /conf/distro directory. So what + has to be inside? <itemizedlist> + <listitem> + <para><command>DISTRO_VERSION</command> so users will know which + version of distribution they use.</para> + </listitem> + + <listitem> + <para><command>DISTRO_TYPE</command> (release/debug) variable is + used in some recipes to enable/disable some features - for example + kernel output on screen for "debug" builds.</para> + </listitem> + + <listitem> + <para>Type of libc used: will it be glibc + (<command>TARGET_OS</command> = "linux") or uclibc + (<command>TARGET_OS</command> = "linux-uclibc")?</para> + </listitem> + + <listitem> + <para>Toolchain versions - for example gcc 3.4.4 based distro will + have: <screen> +PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial" +PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc:gcc-cross" +PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}g++:gcc-cross" + +PREFERRED_VERSION_binutils = "2.16" +PREFERRED_VERSION_binutils-cross = "2.16" + +PREFERRED_VERSION_gcc = "3.4.4" +PREFERRED_VERSION_gcc-cross = "3.4.4" +PREFERRED_VERSION_gcc-initial-cross = "3.4.4" + </screen></para> + </listitem> + + <listitem> + <para><command>DISTRO_FEATURES</command> which describe which + features distro has. More about it in <link + linkend="task-base">task-base</link> section.</para> + </listitem> + + <listitem> + <para>Versions of kernels used for supported devices: <screen> +PREFERRED_VERSION_linux-omap1_omap5912osk ?= "2.6.18+git" +PREFERRED_VERSION_linux-openzaurus ?= "2.6.17" + </screen></para> + </listitem> + + <listitem> + <para>To get more stable build it is good to make use of + sane-srcdates.inc file which contain working SRCDATE for many of + floating recipes. <screen> +require conf/distro/include/sane-srcdates.inc + </screen> It also should have global <command>SRCDATE</command> + value set (format is ISO date: YYYYMMDD): <screen> +SRCDATE = "20061014" + </screen></para> + </listitem> + </itemizedlist></para> + </section> + + <section id="commonuse_new_machine"> + <title>Adding a new Machine</title> + + <para>To be able to build for device OpenEmbedded have to know it, so + machine config file need to be written. All those configs are stored in + /conf/machine/ directory.</para> + + <para>As usual some variables are required: <itemizedlist> + <listitem> + <para><command>TARGET_ARCH</command> which describe which CPU + architecture does machine use.</para> + </listitem> + + <listitem> + <para><command>MACHINE_FEATURES</command> which describe which + features device has. More about it in <link + linkend="task-base">task-base</link> section.</para> + </listitem> + + <listitem> + <para><command>PREFERRED_PROVIDER_virtual/kernel</command> has to + point into proper kernel recipe for this machine.</para> + </listitem> + </itemizedlist></para> + + <para>Next kernel recipe needs to be added.</para> + </section> + + <section id="commonuse_new_package"> + <title>Adding a new Package</title> + + <para>This section is a stub, help us by expanding it. Learn by example, go through the + recipes that are already there and mimic them to do what you want.</para> + + <section> + <title>building from unstable source code</title> + <para>Building against the latest, bleeding-edge source has some intricacies of its own. + For one, it is desirable to pin down a souce code revision that is known to build to + prevent random breakage in OE at the most inopportune time for all OE users. Here is + how to do that properly. + <itemizedlist> + <listitem><para>for svn: add 'PV = "1.1+svnr${SRCREV}"' to your bb file.</para></listitem> + <listitem><para>for cvs: add 'PV = "1.1+cvs${SRCREV}"' to your bb file.</para></listitem> + </itemizedlist> + Accompany either with an entry to conf/distro/include/sane-srcrevs.inc for a revision that you know + builds successfully. + </para> + <para> + If you really absolutely have to follow the latest commits, you can do that by adding + 'SRCREV_pn-linux-davinci ?= ${AUTOREV}' to your local.conf, for example. In this case, + you'd build against the most recent and unstable source for the pn-linux-davinci package. + </para> + </section> + </section> + + <section id="commonuse_new_image"> + <title>Creating your own image</title> + + <para>Creating own image is easy - only few variables needs to be set: + <itemizedlist> + <listitem> + <para><command>IMAGE_BASENAME</command> to give a name for your own + image</para> + </listitem> + + <listitem> + <para><command>PACKAGE_INSTALL</command> to give a list of packages + to install into the image</para> + </listitem> + + <listitem> + <para><command>RDEPENDS</command> to give a list of recipes which + are needed to be built to create this image</para> + </listitem> + + <listitem> + <para><command>IMAGE_LINGUAS</command> is an optional list of + languages which has to be installed into the image</para> + </listitem> + </itemizedlist> Then adding of the <emphasis>image</emphasis> class use: + <screen> +inherit image +</screen> And the image recipe is ready for usage.</para> + </section> + + <section id="commonuse_prebuilt_toolchain"> + <title>Using a prebuilt toolchain to create your packages</title> + + <para>It might be necessary to integrate a prebuilt toolchain and other + libraries but still be use OpenEmbedded to build packages. One of many + approaches is shown and discussed here.</para> + + <section> + <title>The toolchain</title> + + <para>We assume the toolchain provides a C and C++ compiler, an + assembler and other tools to build packages. The list below shows a gcc + 3.4.4 toolchain for ARM architectures using glibc. We assume that the + toolchain is in your <command>PATH</command>.</para> + + <screen> +<command>ls</command> pre-built/cross/bin + +arm-linux-g++ +arm-linux-ld +arm-linux-ranlib +arm-linux-ar +arm-linux-g77 +arm-linux-readelf +arm-linux-as +arm-linux-gcc +arm-linux-gcc-3.4.4 +arm-linux-c++ +arm-linux-size +arm-linux-c++filt +arm-linux-nm +arm-linux-strings +arm-linux-cpp +arm-linux-objcopy +arm-linux-strip +arm-linux-objdump +</screen> + </section> + + <section> + <title>The prebuilt libraries</title> + + <para>We need the header files and the libraries itself. The following + directory layout is assume. <command>PRE_BUILT</command> has two + subdirectories one is called <emphasis>include</emphasis> and holds the + header files and the other directory is called <emphasis>lib</emphasis> + and holds the shared and static libraries. Additionally a Qt2 directory + is present having a <emphasis>include</emphasis> and + <emphasis>lib</emphasis> sub-directory.</para> + + <screen> +<command>ls</command> $PRE_BUILT +include +lib +qt2 +</screen> + </section> + + <section> + <title>Setting up OpenEmbedded</title> + + <para>OpenEmbedded will be setup here. We assume that your machine and + distribution is not part of OpenEmbedded and they will be created ad-hoc + in the <emphasis>local.conf</emphasis> file. You will need to have + <application>BitBake</application> and a current OpenEmbedded version + available.</para> + + <section> + <title>Sourcable script</title> + + <para>To ease the usage of OpenEmbedded we start by creating a + source-able script. This is actually a small variation from the + already seen script. We will name it <emphasis>build_source</emphasis> + and you will need to source it.</para> + + <screen> +BITBAKE_PATH=/where/is/bitbake/bin +TOOLCHAIN=/where/is/toolchain/bin +HOST_TOOLS=/where/is/hosttools/bin +export PRE_BUILT=/where/is/pre-built + +export PATH=$BITBAKE_PATH:$TOOLCHAIN:$HOST_TOOLS:$PATH +export OEDIR=$PWD +export LOCALDIR=$PWD/secret-isv + </screen> + + <para>Use <command>source build_source</command> to source the script, + use <command>env</command> to check that the variable where + exported.</para> + </section> + + <section> + <title>Creating the local.conf</title> + + <para>We will configure OpenEmbedded now, it is very similar to what + we have done above.</para> + + <screen> +DL_DIR = "${OEDIR}/sources" +BBFILES := "${OEDIR}/openembedded/packages/*/*.bb ${LOCALDIR}/packages/*/*.bb" +BBFILE_COLLECTIONS = "upstream local" +BBFILE_PATTERN_upstream = "^${OEDIR}/openembedded/packages/" +BBFILE_PATTERN_local = "^${LOCALDIR}/packages/" +BBFILE_PRIORITY_upstream = "5" +BBFILE_PRIORITY_local = "10" +BBMASK = "" + </screen> + + <para>${OEDIR}/openembedded will be a upstream release of + OpenEmbedded. Above we have assumed it is in the current working + directory. Additionally we have a ${LOCALDIR}, we combine these two + directories as a special <link linkend="collections">BitBake + Collection</link>.</para> + + <screen> +# +# machine stuff +# +MACHINE = "secret-killer" +PACKAGE_EXTRA_ARCHS = "armv4 armv4t armv5te iwmmxt xscale"" +TARGET_CC_ARCH = "-mcpu=xscale -mtune=iwmmxt" +TARGET_ARCH = "arm" +PACKAGE_ARCH="xscale" + </screen> + + <para>We tell OpenEmbedded that we build for the ARM platform and + optimize for xscale and iwmmxt.</para> + + <screen> +INHERIT += " package_ipk debian" +TARGET_OS = "linux" +TARGET_FPU = "soft" +DISTRO = "secret-disro" +DISTRO_NAME = "secret-distro" +DISTRO_VERSION = "x.y.z" +DISTRO_TYPE = "release" + </screen> + + <para>Create a distribution ad-hoc as well. We tell OpenEmbedded that + we build for linux and glibc using soft float as fpu. If your + toolchain is a uclibc toolchain you will need to set + <command>TARGET_OS</command> to linux-uclibc.</para> + + <screen> +export CC="${CCACHE}arm-linux-gcc-3.4.4 ${HOST_CC_ARCH}" +export CXX="${CCACHE}arm-linux-g++ ${HOST_CC_ARCH}" +export CPP="arm-linux-gcc-3.4.4 -E" +export LD="arm-linux-ld" +export AR="arm-linux-ar" +export AS="arm-linux-as" +export RANLIB="arm-linux-ranlib" +export STRIP="arm-linux-strip" + </screen> + + <para>The above variables replace the ones from + <emphasis>bitbake.conf</emphasis>. This will make OpenEmbedded use the + prebuilt toolchain.</para> + + <screen> +# +# point OE to the lib and include directory +# +TARGET_CPPFLAGS_append = " -I${PRE_BUILT}/include " +TARGET_LDFLAGS_prepend = " -L${PRE_BUILT}/qt2/lib -L${PRE_BUILT}/lib \ +-Wl,-rpath-link,${PRE_BUILT}/lib -Wl,-rpath-link,${PRE_BUILT}/qt2/lib " + +# special to Qt/Qtopia +QTDIR = "${PRE_BUILT}/qt2" +QPEDIR = "${PRE_BUILT}" +palmtopdir = "/opt/Qtopia" +palmqtdir = "/opt/Qtopia" + </screen> + + <para>We will add the <command>PRE_BUILT</command> libraries to the + include and library paths. And the same is done for the special + version of Qt we have in your <command>PRE_BUILT</command> + directory.</para> + + <screen> +ASSUME_PROVIDED += " virtual/${TARGET_PREFIX}gcc " +ASSUME_PROVIDED += " virtual/libc " +ASSUME_PROVIDED += " virtual/qte " +ASSUME_PROVIDED += " virtual/libqpe " +ASSUME_PROVIDED += " libqpe-opie " + </screen> + + <para>Now we have told <application>BitBake</application> that the C + library, compiler and Qtopia is already provided. These lines will + avoid building binutils, gcc initial, glibc, gcc.</para> + + <screen> +<command>source</command> build_source +<command>bitbake</command> your-killer-app + </screen> + + <para>You should be able to create the packages you want to using the + prebuilt toolchain now.</para> + </section> + </section> + + <section> + <title>Useful hints</title> + + <para>If you have more prebuilt libraries you need to add additional + <command>ASSUME_PROVIDED</command> lines to your + <emphasis>local.conf</emphasis>. Using <command>bitbake -vvv + PACKAGE</command> you can easily see the package names you could + <command>ASSUME_PROVIDED</command> if you have some prebuilt.</para> + </section> + + <section> + <title>Issues with this approach</title> + + <screen> +NOTE: Couldn't find shared library provider for libqtopia.so.1 +NOTE: Couldn't find shared library provider for libqtopia2.so.2 +NOTE: Couldn't find shared library provider for libqpe.so.1 +NOTE: Couldn't find shared library provider for libpthread.so.0 +NOTE: Couldn't find shared library provider for libstdc++.so.6 +NOTE: Couldn't find shared library provider for libqte.so.2 +NOTE: Couldn't find shared library provider for libgcc_s.so.1 +NOTE: Couldn't find shared library provider for libc.so.6 +NOTE: Couldn't find shared library provider for libm.so.6 +</screen> + + <para>OpenEmbedded tries to automatically add run-time dependencies + (RDEPENDS) to the package. It uses the <emphasis><link + linkend="shlibs">shlibs</link></emphasis> system to do add them, in this + case it was not able to find packages providing these libraries as they + are prebuilt. This means they will not be added to the RDEPENDS of the + just created package. The result can be fatal. If you use OpenEmbedded + to create images you will end up with a image without a libc being + installed. This will lead to a fatal failure. To workaround this issue + you could create a package for the metadata to install every needed + library and use ${BOOTSTRAP_EXTRA_RDEPENDS} to make sure this package is + installed when creating images.</para> + + <para>However, the correct way to resolve this is to provide explicit + mapping using ASSUME_SHLIBS variable. For example, for the libraries + above (partial): + <screen> +ASSUME_SHLIBS = "libqtopia2.so.2:qtopia2_2.4 libc.so.6:libc" +</screen> + The format is shlib_file_name:package[_version]. If a version is specified it will be + used as the minimal (>=) version for the dependency.</para> + </section> + </section> + + <section id="commonuse_new_package_format"> + <title>Using a new package format</title> + + <para>This section is a stub, help us by expanding it</para> + </section> +</chapter> diff --git a/docs/usermanual/chapters/comparing.xml b/docs/usermanual/chapters/comparing.xml new file mode 100644 index 0000000000..1347010977 --- /dev/null +++ b/docs/usermanual/chapters/comparing.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter id="chapter_comparing"> + <title>Comparing</title> + + <section id="comparing_buildroot"> + <title>buildroot</title> + + <para>Writing of <application>BitBake</application> recipes is more easy + and more intuitive than writing Makefiles while providing higher + flexibility. This allows you to tweak specific recipes for your very + special needs and to add new recipes very fast. You can build toolchains, + Software Distribution Kits (SDKs), complete Distributions or just single + packages. The flexibility of OpenEmbedded allows you to reuse the once + written recipes for many different purposes. OpenEmbedded provides + everything buildroot will be able to provide. But in contrast to buildroot + OpenEmbedded will allow you to achieve what you really want to achieve. + You can add new package formats, new filesystems, new output formats + easily. OpenEmbedded will suit your need.</para> + </section> + + <section id="comparing_crosstool"> + <title>crosstool</title> + + <para>Crosstool allows to create toolchains for you. It can only create + the initial toolchain for you. It will not compile other needed libraries + or applications for you, it will not be able to track dependencies or to + package them properly. OpenEmbedded supports all configurations crosstool + supports. You can start to create toolchains with OpenEmbedded, then as + your needs grow create a more complete SDK from already present base + libraries and applications and if you recognize you need to have packages + for the target you have them almost built already.</para> + </section> + + <section id="comparing_handmade"> + <title>handmade</title> + + <para>Cross-compilation is a tough business. It is not that + cross-compiling is hard itself but many people misuse the buildsystem they + use to build their software. This will lead to a variety of issues you can + run into. This can be failing tests on configuration because of executing + cross compiled binaries or crashes at run-time due wrong sizes of basic + types. When utilizing OpenEmbedded you avoid searching for patches at many + different places and will be able to get things done more quickly. + <application>OpenEmbedded</application> allows you to choose from a pool + of ready to use software packages.</para> + + <para>OpenEmbedded will create complete flashable images using different + output formats and filesystems. This allows you to create complete and + specialized distributions easily.</para> + </section> +</chapter>
\ No newline at end of file diff --git a/docs/usermanual/chapters/features.xml b/docs/usermanual/chapters/features.xml new file mode 100644 index 0000000000..8eecaa9ed4 --- /dev/null +++ b/docs/usermanual/chapters/features.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter id="chapter_special_features"> + <title>Special features</title> + + <section id="special_debian_naming"> + <title>Debian package naming <anchor id="debian" /></title> + + <screen>INHERIT += "debian"</screen> + + <para>Placing the above line into your <emphasis>${DISTRO}.conf</emphasis> + or <emphasis>local.conf</emphasis> will trigger renaming of packages if + they only ship one library. Imagine a package where the package name + (<command>PN</command>) is foo and this packages ships a file named + <command>libfoo.so.1.2.3</command>. Now this package will be renamed to + <command>libfoo1</command> to follow the Debian package naming + policy.</para> + </section> + + <section id="special_shlibs"> + <title>Shared Library handling (shlibs) <anchor id="shlibs" /></title> + + <para>Run-time Dependencies (<command>RDEPENDS</command>) will be added + when packaging the software. They should only contain the minimal + dependencies to run the program. OpenEmbedded will analyze each packaged + binary and search for <command>SO_NEEDED</command> libraries. The + libraries are absolutely required by the program then OpenEmbedded is + searching for packages that installs these libraries. these packages are + automatically added to the <command>RDEPENDS</command>. As a packager you + don't need to worry about shared libraries anymore they will be added + automatically.</para> + + <remark>NOTE: This does not apply to plug-ins used by the + program.</remark> + </section> + + <section id="special_bitbake_collections"> + <title>BitBake Collections <anchor id="collections" /></title> + + <para>This section is a stub, help us by expanding it</para> + + <para><screen> +BBFILES := "${OEDIR}/openembedded/packages/*/*.bb ${LOCALDIR}/packages/*/*.bb" +BBFILE_COLLECTIONS = "upstream local" +BBFILE_PATTERN_upstream = "^${OEDIR}/openembedded/packages/" +BBFILE_PATTERN_local = "^${LOCALDIR}/packages/" +BBFILE_PRIORITY_upstream = "5" +BBFILE_PRIORITY_local = "10" +</screen></para> + </section> + + <section id="special_task_base"> + <title>Task-base <anchor id="task-base" /></title> + + <para>Task-base is new way of creating basic root filesystems. Instead of + having each machine setting a ton of duplicate variables, this allow a + machine to specify its features and <command>task-base</command> builds it + a customised package based on what the machine needs along with what the + distro supports.</para> + + <para>To illustrate, the distro config file can say: <screen> +DISTRO_FEATURES = "nfs smbfs ipsec wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" +</screen> and the machine config: <screen> +MACHINE_FEATURES = "kernel26 apm alsa pcmcia bluetooth irda usbgadget" +</screen> and the resulting <command>task-base</command> would support pcmcia + but not usbhost.</para> + + <para>Task-base details exactly which options are either machine or distro + settings (or need to be in both). Machine options are meant to reflect + capabilities of the machine, distro options list things distribution + maintainers might want to add or remove from their distros images.</para> + </section> + + <section id="special_overrides"> + <title>Overrides <anchor id="overrides" /></title> + + <para>This section is a stub, help us by expanding it</para> + </section> +</chapter>
\ No newline at end of file diff --git a/docs/usermanual/chapters/getting_oe.xml b/docs/usermanual/chapters/getting_oe.xml new file mode 100644 index 0000000000..9238e4f29d --- /dev/null +++ b/docs/usermanual/chapters/getting_oe.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter id="chapter_getting_oe"> + <title>Getting Started</title> + + <section id="gettingoe_getting_bitbake"> + <title>Getting <application>BitBake</application></title> + + <para>The required version of <application>BitBake</application> is + changing rapidly. At the time of writing (end 2007) + <application>BitBake</application> 1.8.latest was required.</para> + + <para>A safe method is to get the <application>BitBake</application> from + a stable Subversion branch (those with an even minor number). <screen> +<command>svn</command> co http://svn.berlios.de/svnroot/repos/bitbake/branches/bitbake-1.8 +... +A bitbake-1.8/classes/base.bbclass +U bitbake-1.8 +At revision 827. + </screen> <application>BitBake</application> is checked out now; + this completes the first and most critical dependency of OpenEmbedded. + Issuing <command>svn</command> <command>up</command> in the + <emphasis>bitbake-1.8</emphasis> directory will update + <application>BitBake</application> to the latest stable version, but + generally it is a good idea to stick with a specific known working version + of <application>BitBake</application> until OpenEmbedded asks you to + upgrade.</para> + </section> + + <section id="gettingoe_getting_oe"> + <title>Getting OpenEmbedded</title> + + <para>The OpenEmbedded metadata has a high rate of development, so it's a + good idea to stay up to date. You'll need monotone 0.28 to get the + metadata and stay up to date. Monotone is available in most distributions + and has binaries at <ulink url="http://venge.net/monotone/">Monotone + homepage</ulink>.</para> + + <para>Next step is getting snapshot of database. <screen> +wget http://openembedded.org/snapshots/OE.mtn.bz2 http://openembedded.org/snapshots/OE.mtn.bz2.md5 +</screen> Or if you have monotone 0.30 or later: <screen> +wget http://www.openembedded.org/snapshots/OE-this-is-for-mtn-0.30.mtn.bz2 +wget http://www.openembedded.org/snapshots/OE-this-is-for-mtn-0.30.mtn.bz2.md5 +</screen> Then verify integrity of snapshot by checking md5sum. <screen> +md5sum -c OE.mtn.bz2.md5sum +</screen> Then unpack database. <screen> +bunzip OE.mtn.bz2 +</screen> Finally checkout the development branch. <screen> +mtn --db=OE.mtn co -b org.openembedded.dev +</screen></para> + </section> + + <section id="gettingoe_configuring_oe"> + <title>Configuring OpenEmbedded</title> + + <para>This section is a stub, help us by expanding it</para> + </section> + + <section id="gettingoe_building_software"> + <title>Building Software</title> + + <para>Once BitBake and OpenEmbedded are set up and configured, one can build + software and images like this: +<screen> +bitbake <recipe_name> +</screen> + </para> + + <para>This section is a stub, help us by expanding it</para> + </section> +</chapter>
\ No newline at end of file diff --git a/docs/usermanual/chapters/introduction.xml b/docs/usermanual/chapters/introduction.xml new file mode 100644 index 0000000000..cbe58332e1 --- /dev/null +++ b/docs/usermanual/chapters/introduction.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter id="chapter_introduction"> + <title>Introduction</title> + + <section id="intro_overview"> + <title>Overview</title> + + <para>Like any build tool (make, ant, jam), the OpenEmbedded build tool + BitBake controls how to build things and the build dependencies. But + unlike single project tools like <command>make</command> it is not based + on one makefile or a closed set of inter-dependent makefiles, but collects + and manages an open set of largely independent build descriptions (package + recipes) and builds them in proper order.</para> + + <para>To be more precise: <ulink + url="http://www.openembedded.org"><application>OpenEmbedded</application></ulink> + is a set of metadata used to cross-compile, package and install software + packages. <application>OpenEmbedded</application> is being used to build + and maintain a number of embedded Linux distributions, including + OpenZaurus, Ångström, Familiar and SlugOS.</para> + + <para>The primary use-case of <application>OpenEmbedded</application> are: + <itemizedlist> + <listitem> + <para>Handle cross-compilation.</para> + </listitem> + + <listitem> + <para>Handle inter-package dependencies</para> + </listitem> + + <listitem> + <para>Must be able to emit packages (tar, rpm, ipk)</para> + </listitem> + + <listitem> + <para>Must be able to create images and feeds from packages</para> + </listitem> + + <listitem> + <para>Must be highly configurable to support many machines, + distribution and architectures.</para> + </listitem> + + <listitem> + <para>Writing of metadata must be easy and reusable</para> + </listitem> + </itemizedlist></para> + + <para>Together with <ulink + url="http://bitbake.berlios.de/manual"><application>BitBake</application></ulink>, + OpenEmbedded satisfies all these and many more. Flexibility and power have + always been the priorities.</para> + </section> + + <section id="intro_history"> + <title>History</title> + + <para>OpenEmbedded was invented and founded by the creators of the + OpenZaurus project. At this time the project had pushed + <emphasis>buildroot</emphasis> to its limits. It supported the creation of + <emphasis>ipk</emphasis> packages, feeds and images and had support for + more than one machine. But it was impossible to use different patches, + files for different architectures, machines or distributions. To overcome + this shortcoming OpenEmbedded was created.</para> + + <para>After a few months other projects started using OpenEmbedded and + contributing back. On 7 December 2004 Chris Larson split the project into + two parts: BitBake, a generic task executor and OpenEmbedded, the metadata + for BitBake.</para> + </section> +</chapter> diff --git a/docs/usermanual/chapters/metadata.xml b/docs/usermanual/chapters/metadata.xml new file mode 100644 index 0000000000..f4cf3bc5e6 --- /dev/null +++ b/docs/usermanual/chapters/metadata.xml @@ -0,0 +1,129 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter id="chapter_metadata"> + <title>Metadata</title> + + <section id="metadata_file_layout"> + <title>File Layout</title> + + <para>OpenEmbedded has six directories three of them hold + <application>BitBake</application> metadata.</para> + + <para>The <emphasis>conf</emphasis> directory is holding the bitbake.conf, + machine and distribution configuration. bitbake.conf is read when + <application>BitBake</application> is started and this will include among + others a local.conf the machine and distribution configuration files. + These files will be searched in the <command>BBPATH</command> environment + variable.</para> + + <para><emphasis>classes</emphasis> is the directory holding + <application>BitBake</application> bbclass. These classes can be inherited + by the <application>BitBake</application> files. BitBake automatically + inherits the base.bbclass on every parsed file. <command>BBPATH</command> + is used to find the class.</para> + + <para>In <emphasis>packages</emphasis> the + <application>BitBake</application> files are stored. For each task or + application we have a directory. These directories store the real + <application>BitBake</application> files. They are the ones ending with + <emphasis>.bb</emphasis>. And for each application and version we have + one.</para> + </section> + + <section id="metadata_syntax"> + <title>Syntax</title> + + <para>OpenEmbedded has files ending with <emphasis>.conf</emphasis>, + <emphasis>.inc</emphasis>, <emphasis>.bb</emphasis> + and<emphasis>.bbclass</emphasis>. The syntax and semantic of these files + are best described in the <ulink + url="http://bitbake.berlios.de/manual"><application>BitBake</application> + manual</ulink>.</para> + </section> + + <section id="metadata_classes"> + <title>Classes</title> + + <para>OpenEmbedded provides special <application>BitBake</application> + classes to ease compiling, packaging and other things. FIXME.</para> + </section> + + <section id="metadata_writing_data"> + <title>Writing Meta Data (Adding packages)</title> + + <para>This page will guide you trough the effort of writing a .bb file or + <emphasis>recipe</emphasis> in BitBake speak.</para> + + <para>Let's start with the easy stuff, like the package description, + license, etc: <screen> +DESCRIPTION = "My first application, a really cool app containing lots of foo and bar" +LICENSE = "GPLv2" +HOMEPAGE = "http://www.host.com/foo/" + </screen> The description and license fields are mandatory, so + better check them twice.</para> + + <para>The next step is to specify what the package needs to build and run, + the so called <emphasis>dependencies</emphasis>: <screen> +DEPENDS = "gtk+" +RDEPENDS = "cool-ttf-fonts" + </screen> The package needs gtk+ to build ('DEPENDS') and + requires the 'cool-ttf-fonts' package to run ('RDEPENDS'). OE will add + run-time dependencies on libraries on its own via the so called + <emphasis>shlibs</emphasis>-code, but you need to specify everything other + by yourself, which in this case is the 'cool-ttf-fonts' package.</para> + + <para>After entering all this OE will know what to build before trying to + build your application, but it doesn't know where to get it yet. So let's + add the source location: <screen> +SRC_URI = "http://www.host.com/foo/files/${P}.tar.bz2;md5sum=yoursum" + </screen> This will tell the fetcher to where to download the + sources from and it will check the integrity using md5sum if you provided + the appropriate <emphasis>yoursum</emphasis>. You can make one by doing + <screen>md5sum foo-1.9.tar.bz2</screen> and replacing + <emphasis>yoursum</emphasis> with the md5sum on your screen. A typical + md5sum will look like this: <screen>a6434b0fc8a54c3dec3d6875bf3be8mtn </screen>Notice + the <emphasis>${P}</emphasis> variable, that one holds the package name, + <emphasis>${PN}</emphasis> in BitBake speak and the package version, + <emphasis>${PV}</emphasis> in BitBake speak. It's a short way of writing + <emphasis>${PN}-${PV}</emphasis>. Using this notation means you can copy + the recipe when a new version is released without having to alter the + contents. You do need to check if everything is still correct, because new + versions mean new bugs.</para> + + <para>Before we can move to the actual building we need to find out which + build system the package is using. If we're lucky, we see a + <emphasis>configure</emphasis> file in the build tree this is an indicator + that we can <emphasis>inherit autotools</emphasis> if we see a + <emphasis>.pro</emphasis> file, it might be qmake, which needs + <emphasis>inherit qmake</emphasis>. Virtually all gtk apps use autotools: + <screen> +inherit autotools pkgconfig + </screen> We are in luck! The package is a well-behaved + application using autotools and pkgconfig to configure and build it + self.</para> + + <para>Lets start the build: <screen> +<command>bitbake</command> foo + </screen> Depending on what you have built before and the + speed of your computer this can take a few seconds to a few hours, so be + prepared.</para> + + <para>.... some time goes by .....</para> + + <para>Your screen should now have something like this on it: <screen> +NOTE: package foo-1.9-r0: task do_build: completed +NOTE: package foo-1.9: completed +NOTE: build 200605052219: completed + </screen></para> + + <para>All looks well, but wait, let's scroll up: <screen> +NOTE: the following files where installed but not shipped: + /usr/weirdpath/importantfile.foo + </screen> OE has a standard list of paths which need to be + included, but it can't know everything, so we have to tell OE to include + that file as well: <screen> +FILES_${PN} += "/usr/weirdpath/importantfile.foo" + </screen> It's important to use <emphasis>+=</emphasis> so it + will get appended to the standard file-list, not replace the standard + one.</para> + </section> +</chapter>
\ No newline at end of file diff --git a/docs/usermanual/chapters/recipes.xml b/docs/usermanual/chapters/recipes.xml new file mode 100644 index 0000000000..c1ca456fa0 --- /dev/null +++ b/docs/usermanual/chapters/recipes.xml @@ -0,0 +1,3710 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter id="chapter_recipes" xreflabel="Recipes chapter"> + <title>Recipes</title> + + <section id="recipes_introduction" xreflabel="introduction"> + <title>Introduction</title> + + <para>A bitbake recipe is a set of instructions that describe what needs + to be done to retrieve the source code for some application, apply any + necessary patches, provide any additional files (such as init scripts), + compile it, install it and generated binary packages. The end result is a + binary package that you can install on your target device, and maybe some + intermediate files, such as libraries and headers, which can be used when + building other application.</para> + + <para>In many ways the process is similar to creating .deb or .rpm + packages for your standard desktop distributions with one major difference + - in OpenEmbedded everything is being cross-compiled. This often makes the + task far more difficult (depending on how well suited the application is + to cross compiling), then it is for other packaging systems and sometime + impossible.</para> + + <para>This chapter assumes that you are familiar with working with + bitbake, including the work flow, required directory structures, bitbake + configuration and the use of monotone. If you are not familiar with these + then first take a look at the chapter on bitbake usage.</para> + </section> + + <section id="recipes_syntax" xreflabel="syntax"> + <title>Syntax of recipes</title> + + <para>The basic items that make up a bitbake recipe file are:</para> + + <variablelist> + <varlistentry> + <term>functions</term> + + <listitem> + <para>Functions provide a series of actions to be performed. + Functions are usually used to override the default implementation of + a task function, or to compliment (append or prepend to an existing + function) a default function. Standard functions use sh shell + syntax, although access to OpenEmbedded variables and internal + methods is also available.</para> + + <para>The following is an example function from the sed + recipe:</para> + + <para><screen>do_install () { + autotools_do_install + install -d ${D}${base_bindir} + mv ${D}${bindir}/sed ${D}${base_bindir}/sed.${PN} +}</screen>It is also possible to implement new functions, that are not + replacing or complimenting the default functions, which are called + between existing tasks. It is also possible to implement functions + in python instead of sh. Both of these options are not seen in the + majority of recipes.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>variable assignments and manipulations</term> + + <listitem> + <para>Variable assignments allow a value to be assigned to a + variable. The assignment may be static text or might include the + contents of other variables. In addition to assignment, appending + and prepending operations are also supported.</para> + + <para>The follow example shows the some of the ways variables can be + used in recipes:<screen>S = "${WORKDIR}/postfix-${PV}" +PR = "r4" +CFLAGS += "-DNO_ASM" +SRC_URI_append = "file://fixup.patch;patch=1"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>keywords</term> + + <listitem> + <para>Only a few keywords are used in bitbake recipes. They are used + for things such as including common functions + (<emphasis>inherit</emphasis>), loading parts of a recipe from other + files (<emphasis>include</emphasis> and + <emphasis>require</emphasis>) and exporting variables to the + environment (export).</para> + + <para>The following example shows the use of some of these + keywords:<screen>export POSTCONF = "${STAGING_BINDIR}/postconf" +inherit autoconf +require otherfile.inc</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>comments</term> + + <listitem> + <para>Any lines that begin with a # are treated as comment lines and + are ignored.<screen># This is a comment</screen></para> + </listitem> + </varlistentry> + </variablelist> + + <para>The following is a summary of the most important (and most commonly + used) parts of the recipe syntax:</para> + + <variablelist> + <varlistentry> + <term>Line continuation: \</term> + + <listitem> + <para>To split a line over multiple lines you should place a \ at + the end of the line that is to be continued on the next line.</para> + + <screen>VAR = "A really long \ + line"</screen> + + <para>Note that there must not be anything (no spaces or tabs) after + the \.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Comments: #</term> + + <listitem> + <para>Any lines beginning with a # are comments and will be + ignored.<screen># This is a comment</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Using variables: ${...}</term> + + <listitem> + <para>To access the contents of a variable you need to access it via + <emphasis>${<varname>}</emphasis>:<screen>SRC_URI = "${SOURCEFORGE_MIRROR}/libpng/zlib-${PV}.tar.gz"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Quote all assignments</term> + + <listitem> + <para>All variable assignments should be quoted with double quotes. + (It may work without them at present, but it will not work in the + future).<screen>VAR1 = "${OTHERVAR}" +VAR2 = "The version is ${PV}"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Conditional assignment</term> + + <listitem> + <para>Conditional assignement is used to assign a value to a + variable, but only when the variable is currently unset. This is + commonly used to provide a default value for use when no specific + definition is provided by the machine or distro configuration of the + users local.conf configuration.</para> + + <para>The following example:<screen>VAR1 ?= "New value"</screen>will + set <emphasis role="bold">VAR1</emphasis> to <emphasis>"New + value"</emphasis> if its currently empty. However if it was already + set it would be unchanged. In the following <emphasis + role="bold">VAR1</emphasis> is left with the value + <emphasis>"Original value"</emphasis>:<screen>VAR1 = "Original value" +VAR1 ?= "New value"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Appending: +=</term> + + <listitem> + <para>You can append values to existing variables using the + <emphasis>+=</emphasis> operator. Note that this operator will add a + space between the existing content of the variable and the new + content.<screen>SRC_URI += "file://fix-makefile.patch;patch=1"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Prepending: =+</term> + + <listitem> + <para>You can prepend values to existing variables using the + <emphasis>=+</emphasis> operator. Note that this operator will add a + space between the new content and the existing content of the + variable.<screen>VAR =+ "Starts"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Appending: _append</term> + + <listitem> + <para>You can append values to existing variables using the + <emphasis>_append</emphasis> method. Note that this operator does + not add any additional space, and it is applied after all the + <emphasis>+=</emphasis>, and <emphasis>=+</emphasis> operators have + been applied.</para> + + <para>The following example show the space being explicitly added to + the start to ensure the appended value is not merged with the + existing value:<screen>SRC_URI_append = " file://fix-makefile.patch;patch=1"</screen>The + <emphasis>_append</emphasis> method can also be used with overrides, + which result in the actions only being performed for the specified + target or machine: [TODO: Link to section on overrides]<screen>SRC_URI_append_sh4 = " file://fix-makefile.patch;patch=1"</screen>Note + that the appended information is a variable itself, and therefore + it's possible to used <emphasis>+=</emphasis> or + <emphasis>=+</emphasis> to assign variables to the + <emphasis>_append</emphasis> information:<screen>SRC_URI_append = " file://fix-makefile.patch;patch=1" +SRC_URI_append += "file://fix-install.patch;patch=1"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Prepending: _prepend</term> + + <listitem> + <para>You can prepend values to existing variables using the + _prepend method. Note that this operator does not add any additional + space, and it is applied after all the <emphasis>+=</emphasis>, and + <emphasis>=+</emphasis> operators have been applied.</para> + + <para>The following example show the space being explicitly added to + the end to ensure the prepended value is not merged with the + existing value:<screen>CFLAGS_prepend = "-I${S}/myincludes "</screen>The + <emphasis>_prepend</emphasis> method can also be used with + overrides, which result in the actions only being performed for the + specified target or machine: [TODO: Link to section on + overrides]<screen>CFLAGS_prepend_sh4 = " file://fix-makefile.patch;patch=1"</screen>Note + that the appended information is a variable itself, and therefore + it's possible to used <emphasis>+=</emphasis> or + <emphasis>=+</emphasis> to assign variables to the + <emphasis>_prepend</emphasis> information:<screen>CFLAGS_prepend = "-I${S}/myincludes " +CFLAGS_prepend += "-I${S}/myincludes2 "</screen>Note also the lack of a space + when using += to append to a prepend value - remember that the += + operator is adding space itself.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Spaces vs tabs</term> + + <listitem> + <para>Spaces should be used for indentation, not hard tabs. Both + currently work, however it is a policy decision of OE that spaces + always be used.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Style: oe-stylize.py</term> + + <listitem> + <para>To help with using the correct style in your recipes there is + a python script in the contrib directory called + <emphasis>oe-stylize.py</emphasis> which can be used to reformat + your recipes to the correct style. The output will contain a list of + warning (to let you know what you did wrong) which should be edited + out before using the new file.<screen>contrib/oe-stylize.py myrecipe.bb > fixed-recipe.bb +vi fixed-recipe.bb +mv fixed.recipe.bb myrecipe.bb</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Using python for complex operations: ${@...}</term> + + <listitem> + <para>For more advanced processing it is possible to use python code + during variable assignments, for doing search and replace on a + variable for example.</para> + + <para>Python code is indicated by a proceeding @ sign in the + variable assignment.<screen>CXXFLAGS := "${@'${CXXFLAGS}'.replace('-frename-registers', '')}"</screen>More + information about using python is available in the <xref + linkend="recipes_advanced_python" /> section.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Shell syntax</term> + + <listitem> + <para>When describing a list of actions to take shell syntax is used + (as if you were writing a shell script). You should ensure that you + script would work with a generic sh and not require any bash (or + other shell) specific functionality. The same applies to various + system utilities (sed, grep, awk etc) that you may wish to use. If + in doubt you should check with multiple implementations - including + those from busybox.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>For a detailed description of the syntax for the bitbake recipe + files you should refer to the bitbake use manual.</para> + </section> + + <section id="recipes_versioning" xreflabel="versioning"> + <title>Recipe naming: Names, versions and releases</title> + + <para>Recipes in OpenEmbedded use a standard naming convention that + includes the package name and version number in the filename. In addition + to the name and version there is also a release number, which is indicates + changes to the way the package is built and/or packaged. The release + number is contained within the recipe itself.</para> + + <para>The expected format of recipe name is:<screen><package-name>_<version>.bb</screen></para> + + <para>where <emphasis><package-name></emphasis> is the name of the + package (application, library, module, or whatever it is that is being + packaged) and <emphasis>version</emphasis> is the version number.</para> + + <para>So a typical recipe name would be:<screen>strace_4.5.14.bb</screen>which + would be for version <emphasis>4.5.14</emphasis> of the + <emphasis>strace</emphasis> application.</para> + + <para>The release version is defined via the package release variable, PR, + contained in the recipe. The expected format is:<screen>r<n></screen>where + <emphasis><n></emphasis> is an integer number starting from 0 + initially and then incremented each time the recipe, or something that + effects the recipe, is modified. So a typical definition of the release + would be:<screen>PR = "r1"</screen>to specify release number + <emphasis>1</emphasis> (the second release, the first would have been + <emphasis>0</emphasis>). If there is no definition of PR in the recipe + then the default value of "r0" is used.</para> + + <para><note> + <para>It is good practice to always define PR in your recipes, even + for the <emphasis>"r0"</emphasis> release, so that when editing the + recipe it is clear that the PR number needs to be updated.</para> + + <para>You should always increment PR when modifying a recipe. + Sometimes this can be avoided if the change will have no effect on the + actual packages generated by the recipe, such as updating the SRC_URI + to point to a new host. If in any doubt then you should increase the + PR regardless of what has been changed.</para> + + <para>The PR value should never be decremented. If you accidentally + submit a large PR value for example then it should be left at the + value and just increased for new releases, not reset back to a lower + version.</para> + </note></para> + + <para>When a recipe is being processed some variables are automatically + set based on the recipe file name and can be used for other purposes from + within the recipe itself. These include:</para> + + <variablelist> + <varlistentry> + <term>PN</term> + + <listitem> + <para>The package name. Determined from the recipe filename - + everything up until the first underscore is considered to be the + package name. For the <command>strace_4.5.14.bb</command> recipe the + PN variable would be set to <emphasis>"strace"</emphasis>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>PV</term> + + <listitem> + <para>The package version. Determined from the recipe filename - + everything between the first underscore and the final .bb is + considered to be the package version. For the + <command>strace_4.5.14.bb</command> recipe the PV variable would be + set to <emphasis>"4.5.14"</emphasis>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>PR</term> + + <listitem> + <para>The package release. This is explicitly set in the recipe, or + if not set it defaults to "<emphasis>r0"</emphasis> if not + set.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>P</term> + + <listitem> + <para>The package name and versions separated by a hyphen.<screen>P = "${PN}-${PV}"</screen></para> + + <para>For the <command>strace_4.5.14.bb</command> recipe the P + variable would be set to + <emphasis>"strace-4.5.14"</emphasis>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>PF</term> + + <listitem> + <para>The package name, version and release separated by + hyphens.<screen>PF = "${PN}-${PV}-${PR}"</screen></para> + + <para>For the s<command>trace_4.5.14.bb recipe</command>, with PR + set to <emphasis>"r1"</emphasis> in the recipe, the PF variable + would be set to <emphasis>"strace-4.5.14-r1"</emphasis>.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>While some of these variables are not commonly used in recipes (they + are used internally though) both PN and PV are used a lot.</para> + + <para>In the following example we are instructing the packaging system to + include an additional directory in the package. We use PN to refer to the + name of the package rather than spelling out the package name:<screen>FILES_${PN} += "${sysconfdir}/myconf"</screen></para> + + <para>In the next example we are specifying the URL for the package + source, by using PV in place of the actual version number it is possible + to duplicate, or rename, the recipe for a new version without having to + edit the URL:<screen>SRC_URI = "ftp://ftp.vim.org/pub/vim/unix/vim-${PV}.tar.bz2"</screen></para> + </section> + + <section id="recipes_variables" xreflabel="variables"> + <title>Variables</title> + + <para>One of the most confusing part of bitbake recipes for new users is + the large amount of variables that appear to be available to change and/or + control the behaviour of some aspect of the recipe. Some variables, such + as those derived from the file name are reasonably obvious, others are not + at all obvious.</para> + + <para>There are several places where these variables are derived from + and/or used:</para> + + <orderedlist> + <listitem> + <para>A large number of variables are defined in the bitbake + configuration file conf/bitbake.conf - it's often a good idea to look + through that file when trying to determine what a particular variable + means.</para> + </listitem> + + <listitem> + <para>Machine and distribution configuration files in conf/machine and + conf/distro will sometimes define some variables specific to the + machine and/or distribution. You should look at the appropriate files + for your targets to see if anything is being defined that effects the + recipes you are building.</para> + </listitem> + + <listitem> + <para>Bitbake itself will define some variables. The FILE variables + that defines the name of the bitbake recipe being processed is set by + bitbake itself for example. Refer to the bitbake manual for more + information on the variables that bitbake sets.</para> + </listitem> + + <listitem> + <para>The classes, that are used via the inherit keyword, define + and/or use the majority of the remaining variables. A class is a like + a library that contain parts of a bitbake recipe that are used by + multiple recipes. To make them usable in more situations they often + include a large number of variables to control how the class + operates.</para> + </listitem> + </orderedlist> + + <para>Another important aspect is that there are three different types of + things that binaries and libraries are used for and they often have + different variables for each. These include:</para> + + <variablelist> + <varlistentry> + <term>target</term> + + <listitem> + <para>Refers to things built for the target are expected to be run + on the target device itself.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>native</term> + + <listitem> + <para>Refers to things built to run natively on the build host + itself.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>cross</term> + + <listitem> + <para>Refers to things built to run natively on the build host + itself, but produce output which is suitable for the target device. + Cross versions of packages usually only exist for things like + compilers and assemblers - i.e. things which are used to produce + binary applications themselves.</para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section id="recipes_header" xreflabel="header"> + <title>Header</title> + + <para>Practically all recipes start was the header section which describes + various aspects of the package that is being built. This information is + typically used directly by the package format (such as ipkg or deb) as + it's meta data used to describe the package.</para> + + <para>Variables used in the header include:</para> + + <variablelist> + <varlistentry> + <term>DESCRIPTION</term> + + <listitem> + <para>Describes what the software does. Hopefully this gives enough + information to a use to know if it's the right application for + them.</para> + + <para>The default description is: <emphasis>"Version ${PV}-${PR} of + package ${PN}"</emphasis>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>HOMEPAGE</term> + + <listitem> + <para>The URL of the home page of the application where new releases + and more information can be found.</para> + + <para>The default homepage is <emphasis>"unknown"</emphasis>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>SECTION</term> + + <listitem> + <para>The section is used to categorise the application into a + specific group. Often used by GUI based installers to help users + when searching for software.</para> + + <para>See <xref linkend="section_variable" /> for a list of the + available sections.</para> + + <para>The default section is <emphasis>"base"</emphasis>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>PRIORITY</term> + + <listitem> + <para>The default priority is + <emphasis>"optional"</emphasis>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>LICENSE</term> + + <listitem> + <para>The license for the application. If it is not one of the + standard licenses then the license itself must be included + (where?).</para> + + <para>As well as being used in the package meta-data the license is + also used by the src_distribute class.</para> + + <para>The default license is <emphasis>"unknown"</emphasis>.</para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section id="recipes_sources" xreflabel="sources"> + <title>Sources: Downloading, patching and additional files</title> + + <para>A recipes purpose is to describe how to take a software package and + build it for your target device. The location of the source file (or + files) is specified via the <xref linkend="src_uri_variable" /> in the + recipe. This can describe several types of URI's, the most common + are:</para> + + <variablelist> + <varlistentry> + <term>http and https</term> + + <listitem> + <para>Specifies files to be downloaded. A copy is stored locally so + that future builds will not download the source again.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>cvs, svn and git</term> + + <listitem> + <para>Specifies that the files are to be retrieved using the + specified version control system.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>files</term> + + <listitem> + <para>Plain files which are included locally. These can be used for + adding documentation, init scripts or any other files that need to + be added to build the package under openembedded.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>patches</term> + + <listitem> + <para>Patches are plain files which are treated as patched and + automatically applied.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>If a http, https or file URI refers to a compressed file, an archive + file or a compressed archive file, such as .tar.gz or .zip, then the files + will be uncompressed and extracted from the archive automatically.</para> + + <para>Archive files will be extracted from with the working directory, + <emphasis role="bold">${WORKDIR}</emphasis> and plain files will be copied + into the same directory. Patches will be applied from within the unpacked + source directory, <emphasis role="bold">${S}</emphasis>. (Details on these + directories is provided in the next section.)</para> + + <para>The following example from the havp recipe shows a typical <emphasis + role="bold">SRC_URI</emphasis> definition:<screen>SRC_URI = "http://www.server-side.de/download/havp-${PV}.tar.gz \ + file://sysconfdir-is-etc.patch;patch=1 \ + file://havp.init \ + file://doc.configure.txt \ + file://volatiles.05_havp"</screen></para> + + <para>This describes several files</para> + + <variablelist> + <varlistentry> + <term>http://www.server-side.de/download/havp-${PV}.tar.gz</term> + + <listitem> + <para>This is the URI of the havp source code. Note the use of the + <emphasis role="bold">${PV}</emphasis> variable to specify the + version. This is done to enable the recipe to be renamed for a new + version without the need the edit the recipe itself. Because this is + a .tar.gz compressed archive the file will be decompressed and + extracted in the working dir <emphasis + role="bold">${WORKDIR}</emphasis>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>file://sysconfdir-is-etc.patch;patch=1</term> + + <listitem> + <para>This is a local file that is used to patch the extracted + source code. The patch=1 is what specifies that this is a patch. The + patch will be applied from the unpacked source directory, <emphasis + role="bold">${S}</emphasis>. In this case <emphasis + role="bold">${S}</emphasis> will be <emphasis + role="bold">${WORKDIR}/havp-0.82</emphasis>, and luckily the + <emphasis role="bold">havp-0.82.tar.gz</emphasis> file extracts + itself into that directory (so no need to explicitly change + <emphasis role="bold">${S}</emphasis>).</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>file://havp.init file://doc.configure.txt + file://volatiles.05_havp"</term> + + <listitem> + <para>These are plain files which are just copied into the working + directory <emphasis role="bold">${WORKDIR}</emphasis>. These are + then used during the install task in the recipe to provide init + scripts, documentation and volatiles configuration information for + the package.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Full details on the <emphasis role="bold">SRC_URI</emphasis> + variable and all the support URI's is available in the <xref + linkend="src_uri_variable" /> section of the reference chapter.</para> + </section> + + <section id="recipes_directories" xreflabel="directories"> + <title>Directories: What goes where</title> + + <para>A large part of the work or a recipe is involved with specifying + where files and found and where they have to go. It's important for + example that programs do not try and use files from <emphasis + role="bold">/usr/include</emphasis> or <emphasis + role="bold">/usr/lib</emphasis> since they are for the host system, not + the target. Similarly you don't want programs installed into <emphasis + role="bold">/usr/bin</emphasis> since that may overwrite your host system + programs with versions that don't work on the host!</para> + + <para>The following are some of the directories commonly referred to in + recipes and will be described in more detail in the rest of this + section:</para> + + <variablelist> + <varlistentry> + <term>Working directory: WORKDIR</term> + + <listitem> + <para>This working directory for a recipe is where archive files + will be extracted, plain files will be placed, subdirectories for + logs, installed files etc will be created.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Unpacked source code directory: S</term> + + <listitem> + <para>This is where patches are applied and where the program is + expected to be compiled in.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Destination directory: D</term> + + <listitem> + <para>The destination directory. This is where your package should + be installed into. The packaging system will then take the files + from directories under here and package them up for installation on + the target.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Installation directories: bindir, docdir, ...</term> + + <listitem> + <para>There are a set of variables available to describe all of the + paths on the target that you may want to use. Recipes should use + these variables rather than hard coding any specific paths.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Staging directories: STAGING_LIBDIR, STAGING_INCDIR, ...</term> + + <listitem> + <para>Staging directories are a special area for headers, libraries + and other files that are generated by one recipe that may be needed + by another recipe. A library package for example needs to make the + library and headers available to other recipes so that they can link + against them.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>File path directories: FILE, FILE_DIRNAME, FILESDIR, + FILESPATH</term> + + <listitem> + <para>These directories are used to control where files are found. + Understanding these can help you separate patches for different + versions or releases of your recipes and/or use the same patch over + multiple versions etc.</para> + </listitem> + </varlistentry> + </variablelist> + + <section> + <title>WORKDIR: The working directory</title> + + <para>The working directory is where the source code is extracted, to + which plain files (not patches) are copied and where the logs and + installation files are created. A typical reason for needing to + reference the work directory is for the handling of non patch + files.</para> + + <para>If we take a look at the recipe for quagga we can see an example + non patch files for configuration and init scripts:<screen>SRC_URI = "http://www.quagga.net/download/quagga-${PV}.tar.gz \ + file://fix-for-lib-inpath.patch;patch=1 \ + file://quagga.init \ + file://quagga.default \ + file://watchquagga.init \ + file://watchquagga.default"</screen>The recipe has two init files + and two configuration files, which are not patches, but are actually + files that it wants to include in the generated packages. Bitbake will + copy these files into the work directory. So to access them during the + install task we refer to them via the <emphasis + role="bold">WORKDIR</emphasis> variable:<screen>do_install () { + # Install init script and default settings + install -m 0755 -d ${D}${sysconfdir}/default ${D}${sysconfdir}/init.d ${D}${sysconfdir}/quagga + install -m 0644 ${WORKDIR}/quagga.default ${D}${sysconfdir}/default/quagga + install -m 0644 ${WORKDIR}/watchquagga.default ${D}${sysconfdir}/default/watchquagga + install -m 0755 ${WORKDIR}/quagga.init ${D}${sysconfdir}/init.d/quagga + install -m 0755 ${WORKDIR}/watchquagga.init ${D}${sysconfdir}/init.d/watchquagga + ...</screen></para> + </section> + + <section> + <title>S: The unpacked source code directory</title> + + <para>Bitbake expects to find the extracted source for a package in a + directory called <emphasis + role="bold"><packagename>-<version></emphasis> in the + <emphasis role="bold">WORKDIR</emphasis> directory. This is the + directory in which it will change into before patching, compiling and + installating the package.</para> + + <para>For example, we have a package called <emphasis + role="bold">widgets_1.2.bb</emphasis> which we are extracting from the + <emphasis role="bold">widgets-1.2.tar.gz</emphasis> file. Bitbake + expects the source to end up in a directory called <emphasis + role="bold">widgets-1.2</emphasis> within the work directory. If the + source does not end up in this directory then bitbake needs to be told + this by explicitly setting <emphasis role="bold">S</emphasis>.</para> + + <para>If <emphasis role="bold">widgets-1.2.tar.gz</emphasis> actually + extracts into a directory called <emphasis + role="bold">widgets</emphasis>, without the version number, instead of + <emphasis role="bold">widgets-1.2</emphasis> then the <emphasis + role="bold">S</emphasis> variable will be wrong and patching and/or + compiling will fail. Therefore we need to override the default value of + <emphasis role="bold">S</emphasis> to specify the directory the source + was actually extracted into:<screen>SRC_URI = "http://www.example.com/software/widgets-${PN}.tar.gz" +S = "${WORKDIR}/widgets"</screen></para> + </section> + + <section> + <title>D: The destination directory</title> + + <para>The destination directory is where the completed application and + all of it's files are installed into in preparation for packaging. + Typically an installation would places files in directories such as + <emphasis role="bold">/etc</emphasis> and <emphasis + role="bold">/usr/bin</emphasis> by default. Since those directories are + used by the host system we do not want the packages to install into + those locations. Instead they need to install into the directories below + the destination directory.</para> + + <para>So instead of installing into <emphasis + role="bold">/usr/bin</emphasis> the package needs to install into + <emphasis role="bold">${D}/usr/bin</emphasis>.</para> + + <para>The following example from arpwatch shows the make install command + being passed a <emphasis role="bold">${D}</emphasis> as the <emphasis + role="bold">DESTDIR</emphasis> variable to control where the makefile + installs everything:<screen>do_install() { + ... + oe_runmake install DESTDIR=${D}</screen></para> + + <para>The following example from quagga shows the use of the destination + directory to install the configuration files and init scripts for the + package:<screen>do_install () { + # Install init script and default settings + install -m 0755 -d ${D}${sysconfdir}/default ${D}${sysconfdir}/init.d ${D}${sysconfdir}/quagga + install -m 0644 ${WORKDIR}/quagga.default ${D}${sysconfdir}/default/quagga + install -m 0755 ${WORKDIR}/quagga.init ${D}${sysconfdir}/init.d/quagga</screen><note> + <para>You should not use directories such as <emphasis + role="bold">/etc</emphasis> and <emphasis + role="bold">/usr/bin</emphasis> directly in your recipes. You should + use the variables that define these locations. The full list of + these variables can be found in the <xref + linkend="directories_installation" /> section of the reference + chapter.</para> + </note></para> + </section> + + <section> + <title>Staging directories</title> + + <para>Staging is used to make libraries, headers and binaries available + for the build of one recipe for use by another recipe. Building a + library for example requires that packages be created containing the + libraries and headers for development on the target as well as making + them available on the host for building other packages that need the + libraries and headers.</para> + + <para>Making the libraries, headers and binaries available for use by + other recipes on the host is called staging and is performed by the + <emphasis>stage</emphasis> task in the recipe. Any recipes that contain + items that are required to build other packages should have a + <emphasis>stage</emphasis> task to make sure the items are all correctly + placed into the staging area. The following example from clamav show the + clamav library and header being placed into the staging area:<screen>do_stage () { + oe_libinstall -a -so libclamav ${STAGING_LIBDIR} + install -m 0644 libclamav/clamav.h ${STAGING_INCDIR} +}</screen></para> + + <para>The following from the p3scan recipe show the path to the clamav + library and header being passed to the configure script. Without this + the configure script would either fail to find the library, or worse + still search the host systems directories for the library. Passing in + the location results in it searching the correct location and finding + the clamav library and headers:<screen>EXTRA_OECONF = "--with-clamav=${STAGING_LIBDIR}/.. \ + --with-openssl=${STAGING_LIBDIR}/.. \ + --disable-ripmime"</screen>While the staging directories are + automatically added by OpenEmbedded to the compiler and linking commands + it is sometimes necessary, as in the p3scan example above, to explicitly + specify the location of the staging directories. Typically this is + needed for autoconf scripts that search in multiple places for the + libraries and headers.</para> + + <note> + <para>Many of the helper classes, such as pkgconfig and autotools add + appropriate commands to the stage task for you. Check with the + individual class descriptions in the reference section to determine + what each class is staging automatically for you.</para> + </note> + + <para>A full list of staging directories can be found in the <xref + linkend="directories_staging" /> section in the reference + chapter.</para> + </section> + + <section id="recipes_filespath_dir" xreflabel="FILESPATH/FILESDIR"> + <title>FILESPATH/FILESDIR: Finding local files</title> + + <para>The file related variables are used by bitbake to determine where + to look for patches and local files.</para> + + <para>Typically you will not need to modify these, but it is useful to + be aware of the default values. In particular when searching for patches + and/or files (file:// URI's), the default search path is:</para> + + <variablelist> + <varlistentry> + <term>${FILE_DIRNAME}/${PF}</term> + + <listitem> + <para>This is the package name, version and release, such as + "<emphasis role="bold">strace-4.5.14-r1</emphasis>". This is very + rarely used since the patches would only be found for the one + exact release of the recipe.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>${FILE_DIRNAME}/${P}</term> + + <listitem> + <para>This is the package name and version, such as "<emphasis + role="bold">strace-4.5.14</emphasis>". This is by far the most + common place to place version specified patches.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>${FILE_DIRNAME}/${PN}</term> + + <listitem> + <para>This is the package name only, such as "<emphasis + role="bold">strace</emphasis>". This is not commonly used.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>${FILE_DIRNAME}/files</term> + + <listitem> + <para>This is just the directory called "<emphasis + role="bold">files</emphasis>". This is commonly used for patches + and files that apply to all version of the package.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>${FILE_DIRNAME}/</term> + + <listitem> + <para>This is just the base directory of the recipe. This is very + rarely used since it would just clutter the main directory.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Each of the paths is relative to <emphasis + role="bold">${FILE_DIRNAME}</emphasis> which is the directory in which + the recipe that is being processed is located.</para> + + <para>The full set of variables that control the file locations and + patch are:</para> + + <variablelist> + <varlistentry> + <term>FILE</term> + + <listitem> + <para>The path to the .bb file which is currently being + processed.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FILE_DIRNAME</term> + + <listitem> + <para>The path to the directory which contains the FILE which is + currently being processed.<screen>FILE_DIRNAME = "${@os.path.dirname(bb.data.getVar('FILE', d))}"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FILESPATH</term> + + <listitem> + <para>The default set of directories which are available to use + for the file:// URI's. Each directory is searched, in the + specified order, in an attempt to find the file specified by each + file:// URI: <screen>FILESPATH = "${FILE_DIRNAME}/${PF}:${FILE_DIRNAME}/${P}:\ +${FILE_DIRNAME}/${PN}:${FILE_DIRNAME}/files:${FILE_DIRNAME}"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FILESDIR</term> + + <listitem> + <para>The default directory to search for file:// URI's. Only used + if the file is not found in FILESPATH. This can be used to easily + add one additional directory to the search path without having to + modify the default FILESPATH setting. By default this is just the + first directory from FILESPATH. <screen>FILESDIR = "${@bb.which(bb.data.getVar('FILESPATH', d, 1), '.')}" </screen></para> + </listitem> + </varlistentry> + </variablelist> + + <para>Sometimes recipes will modify the <emphasis + role="bold">FILESPATH</emphasis> or <emphasis + role="bold">FILESDIR</emphasis> variables to change the default search + path for patches and files. The most common situation in which this is + done is when one recipe includes another one in which the default values + will be based on the name of the package doing the including, not the + included package. Typically the included package will expect the files + to be located in a directories based on it's own name.</para> + + <para>As an example the m4-native recipe includes the m4 recipe. This is + fine, except that the m4 recipes expects its files and patches to be + located in a directory called <emphasis role="bold">m4</emphasis> + directory while the native file name results in them being searched for + in <emphasis role="bold">m4-native</emphasis>. So the m4-native recipe + sets the <emphasis role="bold">FILESDIR</emphasis> variable to the value + that of m4 to add the actual m4 directory (where m4 itself has its files + stored) to the list of directories search for:<screen> include m4_${PV}.bb + inherit native + FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/m4"</screen></para> + </section> + </section> + + <section id="recipes_examples" xreflabel="examples"> + <title>Basic examples</title> + + <para>By now you should know enough about the bitbake recipes to be able + to create a basic recipe. We'll cover a simple single file recipe and then + a more advanced example that uses the autotools helper class (to be + described later) to build an autoconf based package.</para> + + <section id="recipes_helloworld_example" xreflabel="hello world example"> + <title>Hello world</title> + + <para>Now it's time for our first recipe. This is going to be one of the + simplest possible recipes: all code is included and there's only one + file to compile and one readme file. While this isn't all that common + it's a useful example because it doesn't depend on any of the helper + classes which can sometime hide a lot of what is going on.</para> + + <para>First we'll create the myhelloworld.c file and a readme file. + We'll place this in the files subdirectory, which is one of the places + that is searched for file:// URI's:<screen>mkdir packages/myhelloworld +mkdir packages/myhelloworld/files +cat > packages/myhelloworld/files/myhelloworld.c +#include <stdio.h> + +int main(int argc, char** argv) +{ + printf("Hello world!\n"); + return 0; +} +^D +cat > packages/myhelloworld/files/README.txt +Readme file for myhelloworld. +^D</screen></para> + + <para>Now we have a directory for our recipe, packages/myhelloworld, and + we've created a files subdirectory in there to store our local files. + We've created two local files, the C source code for our helloworld + program and a readme file. Now we need to create the bitbake + recipe.</para> + + <para>First we need the header section, which will contain a description + of the package and the release number. We'll leave the other header + variables out for now:<screen>DESCRIPTION = "My hello world program" +PR = "r0"</screen></para> + + <para>Next we need to tell it which files we want to be included in the + recipe, which we do via file:// URI's and the SRC_URI variable:<screen>SRC_URI = "file://myhelloworld.c \ + file://README.txt"</screen></para> + + <para>Note the use of the \ to continue a file and the file of file:// + local URI's, rather than other types such as http://.</para> + + <para>Now we need provide a compile task which tells bitbake how to + compile this program. We do this by defining a do_compile function in + the recipe and providing the appropriate commands:</para> + + <para><screen>do_compile() { + ${CC} ${CFLAGS} ${LDFLAGS} ${WORKDIR}/myhelloworld.c -o myhelloworld +}</screen></para> + + <para>Note the:</para> + + <itemizedlist> + <listitem> + <para>use of the pre-defined compiler variables, <emphasis + role="bold">${CC}</emphasis>, <emphasis + role="bold">${CFLAGS}</emphasis> and <emphasis + role="bold">${LDFLAGS}</emphasis>. These are setup automatically to + contain the settings required to cross-compile the program for the + target.</para> + </listitem> + + <listitem> + <para>use of <emphasis role="bold">${WORKDIR}</emphasis> to find the + source file. As mentioned previously all files are copied into the + working directory and can be referenced via the <emphasis + role="bold">${WORKDIR}</emphasis> variable.</para> + </listitem> + </itemizedlist> + + <para>And finally we want to install the program and readme file into + the destination directory so that it'll be packaged up correctly. This + is done via the install task, so we need to define a do_install function + in the recipe to describe how to install the package:<screen>do_install() { + install -m 0755 -d ${D}${bindir} ${D}${docdir}/myhelloworld + install -m 0644 ${S}/myhelloworld ${D}${bindir} + install -m 0644 ${WORKDIR}/README.txt ${D}${docdir}/myhelloworld +}</screen></para> + + <para>Note the:</para> + + <itemizedlist> + <listitem> + <para>use the <emphasis role="bold">install</emphasis> command to + create directories and install the files, not cp.</para> + </listitem> + + <listitem> + <para>way directories are created before we attempt to install any + files into them. The install command takes care of any + subdirectories that are missing, so we only need to create the full + path to the directory - no need to create the subdirectories.</para> + </listitem> + + <listitem> + <para>way we install everything into the destination directory via + the use of the <emphasis role="bold">${D} + </emphasis>variable.</para> + </listitem> + + <listitem> + <para>way we use variables to refer to the target directories, such + as <emphasis role="bold">${bindir}</emphasis> and <emphasis + role="bold">${docdir}</emphasis>.</para> + </listitem> + + <listitem> + <para>use of <emphasis role="bold">${WORKDIR}</emphasis> to get + access to the <emphasis role="bold">README.txt</emphasis> file, + which was provided via file:// URI.</para> + </listitem> + </itemizedlist> + + <para>We'll consider this release 0 and version 0.1 of a program called + helloworld. So we'll name the recipe myhelloworld_0.1.bb:<screen>cat > packages/myhelloworld/myhelloworld_0.1.bb +DESCRIPTION = "Hello world program" +PR = "r0" + +SRC_URI = "file://myhelloworld.c \ + file://README.txt" + +do_compile() { + ${CC} ${CFLAGS} ${LDFLAGS} ${WORKDIR}/myhelloworld.c -o myhelloworld +} + +do_install() { + install -m 0755 -d ${D}${bindir} ${D}${docdir}/myhelloworld + install -m 0644 ${S}/myhelloworld ${D}${bindir} + install -m 0644 ${WORKDIR}/README.txt ${D}${docdir}/myhelloworld +} +^D</screen>Now we are ready to build our package, hopefully it'll all work + since it's such a simple example:<screen>~/oe%> bitbake -b packages/myhelloworld/myhelloworld_0.1.bb +NOTE: package myhelloworld-0.1: started +NOTE: package myhelloworld-0.1-r0: task do_fetch: started +NOTE: package myhelloworld-0.1-r0: task do_fetch: completed +NOTE: package myhelloworld-0.1-r0: task do_unpack: started +NOTE: Unpacking /home/lenehan/devel/oe/local-packages/myhelloworld/files/helloworld.c to /home/lenehan/devel/oe/build/titan-glibc-25/tmp/work/myhelloworld-0.1-r0/ +NOTE: Unpacking /home/lenehan/devel/oe/local-packages/myhelloworld/files/README.txt to /home/lenehan/devel/oe/build/titan-glibc-25/tmp/work/myhelloworld-0.1-r0/ +NOTE: package myhelloworld-0.1-r0: task do_unpack: completed +NOTE: package myhelloworld-0.1-r0: task do_patch: started +NOTE: package myhelloworld-0.1-r0: task do_patch: completed +NOTE: package myhelloworld-0.1-r0: task do_configure: started +NOTE: package myhelloworld-0.1-r0: task do_configure: completed +NOTE: package myhelloworld-0.1-r0: task do_compile: started +NOTE: package myhelloworld-0.1-r0: task do_compile: completed +NOTE: package myhelloworld-0.1-r0: task do_install: started +NOTE: package myhelloworld-0.1-r0: task do_install: completed +NOTE: package myhelloworld-0.1-r0: task do_package: started +NOTE: package myhelloworld-0.1-r0: task do_package: completed +NOTE: package myhelloworld-0.1-r0: task do_package_write: started +NOTE: Not creating empty archive for myhelloworld-dbg-0.1-r0 +Packaged contents of myhelloworld into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/myhelloworld_0.1-r0_sh4.ipk +Packaged contents of myhelloworld-doc into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/myhelloworld-doc_0.1-r0_sh4.ipk +NOTE: Not creating empty archive for myhelloworld-dev-0.1-r0 +NOTE: Not creating empty archive for myhelloworld-locale-0.1-r0 +NOTE: package myhelloworld-0.1-r0: task do_package_write: completed +NOTE: package myhelloworld-0.1-r0: task do_populate_staging: started +NOTE: package myhelloworld-0.1-r0: task do_populate_staging: completed +NOTE: package myhelloworld-0.1-r0: task do_build: started +NOTE: package myhelloworld-0.1-r0: task do_build: completed +NOTE: package myhelloworld-0.1: completed +Build statistics: + Attempted builds: 1 +~/oe%></screen></para> + + <para>The package was successfully built, the output consists of two + .ipkg files, which are ready to be installed on the target. One contains + the binary and the other contains the readme file:<screen>~/oe%> ls -l tmp/deploy/ipk/*/myhelloworld* +-rw-r--r-- 1 lenehan lenehan 3040 Jan 12 14:46 tmp/deploy/ipk/sh4/myhelloworld_0.1-r0_sh4.ipk +-rw-r--r-- 1 lenehan lenehan 768 Jan 12 14:46 tmp/deploy/ipk/sh4/myhelloworld-doc_0.1-r0_sh4.ipk +~/oe%></screen></para> + + <para>It's worthwhile looking at the working directory to see where + various files ended up:<screen>~/oe%> find tmp/work/myhelloworld-0.1-r0 +tmp/work/myhelloworld-0.1-r0 +tmp/work/myhelloworld-0.1-r0/myhelloworld-0.1 +tmp/work/myhelloworld-0.1-r0/myhelloworld-0.1/patches +tmp/work/myhelloworld-0.1-r0/myhelloworld-0.1/myhelloworld +tmp/work/myhelloworld-0.1-r0/temp +tmp/work/myhelloworld-0.1-r0/temp/run.do_configure.21840 +tmp/work/myhelloworld-0.1-r0/temp/log.do_stage.21840 +tmp/work/myhelloworld-0.1-r0/temp/log.do_install.21840 +tmp/work/myhelloworld-0.1-r0/temp/log.do_compile.21840 +tmp/work/myhelloworld-0.1-r0/temp/run.do_stage.21840 +tmp/work/myhelloworld-0.1-r0/temp/log.do_configure.21840 +tmp/work/myhelloworld-0.1-r0/temp/run.do_install.21840 +tmp/work/myhelloworld-0.1-r0/temp/run.do_compile.21840 +tmp/work/myhelloworld-0.1-r0/install +tmp/work/myhelloworld-0.1-r0/install/myhelloworld-locale +tmp/work/myhelloworld-0.1-r0/install/myhelloworld-dbg +tmp/work/myhelloworld-0.1-r0/install/myhelloworld-dev +tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc +tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr +tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr/share +tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr/share/doc +tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr/share/doc/myhelloworld +tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr/share/doc/myhelloworld/README.txt +tmp/work/myhelloworld-0.1-r0/install/myhelloworld +tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr +tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr/bin +tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr/bin/myhelloworld +tmp/work/myhelloworld-0.1-r0/image +tmp/work/myhelloworld-0.1-r0/image/usr +tmp/work/myhelloworld-0.1-r0/image/usr/bin +tmp/work/myhelloworld-0.1-r0/image/usr/share +tmp/work/myhelloworld-0.1-r0/image/usr/share/doc +tmp/work/myhelloworld-0.1-r0/image/usr/share/doc/myhelloworld +tmp/work/myhelloworld-0.1-r0/myhelloworld.c +tmp/work/myhelloworld-0.1-r0/README.txt +~/oe%></screen>Things to note here are:</para> + + <itemizedlist> + <listitem> + <para>The two source files are in <emphasis + role="bold">tmp/work/myhelloworld-0.1-r0</emphasis>, which is the + working directory as specified via the <emphasis + role="bold">${WORKDIR}</emphasis> variable;</para> + </listitem> + + <listitem> + <para>There's logs of the various tasks in <emphasis + role="bold">tmp/work/myhelloworld-0.1-r0/temp</emphasis> which you + can look at for more details on what was done in each task;</para> + </listitem> + + <listitem> + <para>There's an image directory at <emphasis + role="bold">tmp/work/myhelloworld-0.1-r0/image</emphasis> which + contains just the directories that were to be packaged up. This is + actually the destination directory, as specified via the <emphasis + role="bold">${D}</emphasis> variable. The two files that we + installed were originally in here, but during packaging they were + moved into the install area into a subdirectory specific to the + package that was being created (remember we have a main package and + a -doc package being created.</para> + </listitem> + + <listitem> + <para>The program was actually compiled in the <emphasis + role="bold">tmp/work/myhelloworld-0.1-r0/myhelloworld-0.1</emphasis> + directory, this is the source directory as specified via the + <emphasis role="bold">${S}</emphasis> variable.</para> + </listitem> + + <listitem> + <para>There's an install directory at <emphasis + role="bold">tmp/work/myhelloworld-0.1-r0/install</emphasis> which + contains the packages that were being generated and the files that + go in the package. So we can see that the myhelloworld-doc package + contains the single file <emphasis + role="bold">/usr/share/doc/myhelloworld/README.txt</emphasis>, the + myhelloworld package contains the single file <emphasis + role="bold">/usr/bin/myhelloworld</emphasis> and the -dev, -dbg and + -local packages are all empty.</para> + </listitem> + </itemizedlist> + + <para>At this stage it's good to verify that we really did produce a + binary for the target and not for our host system. We can check that + with the file command:<screen>~/oe%> file tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr/bin/myhelloworld +tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr/bin/myhelloworld: ELF 32-bit LSB executable, Hitachi SH, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), for GNU/Linux 2.4.0, not stripped +~/oe%> file /bin/ls +/bin/ls: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), for GNU/Linux 2.4.0, stripped +~/oe%></screen>This shows us that the helloworld program is for an SH + processor (obviously this will change depending on what your target + system is), while checking the <emphasis role="bold">/bin/ls</emphasis> + program on host shows us that the host system is an AMD X86-64 system. + That's exactly what we wanted.</para> + </section> + + <section id="recipes_autoconf_example" xreflabel="autoconf example"> + <title>An autotools package</title> + + <para>Now for an example of a package that uses autotools. These are + programs that you need to run a configure script for, passing various + parameters, and then make. To make these work when cross-compiling you + need to provides a lot of variables to the configure script. But all the + hard work as already been done for you. There's an <xref + linkend="autotools_class" /> which takes care of most of the complexity + of building an autotools based packages.</para> + + <para>Let's take a look at the tuxnes recipe which is an example of a + very simple autotools based recipe:<screen>%~oe> cat packages/tuxnes/tuxnes_0.75.bb +DESCRIPTION = "Tuxnes Nintendo (8bit) Emulator" +HOMEPAGE = "http://prdownloads.sourceforge.net/tuxnes/tuxnes-0.75.tar.gz" +LICENSE = "GPLv2" +SECTION = "x/games" +PRIORITY = "optional" +PR = "r1" + +SRC_URI = "http://heanet.dl.sourceforge.net/sourceforge/tuxnes/tuxnes-0.75.tar.gz" + +inherit autotools</screen></para> + + <para>This is a really simple recipe. There's the standard header that + describes the package. Then the SRC_URI, which in this case is a http + URL that causes the source code to be downloaded from the specified URI. + And finally there's an "<emphasis role="bold">inherit + autotools</emphasis>" command which loads the autotools class. The + autotools class will take care of generating the require configure, + compile and install tasks. So in this case there's nothing else to do - + that's all there is to it.</para> + + <para>It would be nice if it was always this simple. Unfortunately + there's usually a lot more involved for various reasons including the + need to:</para> + + <itemizedlist> + <listitem> + <para>Pass parameters to configure to enable and disable + features;</para> + </listitem> + + <listitem> + <para>Pass parameters to configure to specify where to find + libraries and headers;</para> + </listitem> + + <listitem> + <para>Make modifications to prevent searching for headers and + libraries in the normal locations (since they below to the host + system, not the target);</para> + </listitem> + + <listitem> + <para>Make modifications to prevent the configure script from tying + to compile and run programs - any programs it compiles will be for + the target and not the host and so cannot be run.</para> + </listitem> + + <listitem> + <para>Manually implement staging scripts;</para> + </listitem> + + <listitem> + <para>Deal with lots of other more complex issues;</para> + </listitem> + </itemizedlist> + + <para>Some of these items are covered in more detail in the advanced + autoconf section.</para> + </section> + </section> + + <section id="recipes_depenencies" xreflabel="dependencies"> + <title>Dependencies: What's needed to build and/or run the + package?</title> + + <para>Dependencies should be familiar to anyone who has used an .rpm and + .deb based desktop distribution. A dependency is something that a package + requires either to run the package (a run-time dependency) or to build the + package (a build-time or compile-time, dependency).</para> + + <para>There are two variables provided to allow the specifications of + dependencies:</para> + + <variablelist> + <varlistentry> + <term>DEPENDS</term> + + <listitem> + <para>Specifies build-time dependencies, via a list of bitbake + recipes to build prior to build the recipe. These are programs + (flex-native) or libraries (libpcre) that are required in order to + build the package.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>RDEPENDS</term> + + <listitem> + <para>Specifies run-time dependencies, via a list of packages to + install prior to installing the current package. These are programs + or libraries that are required in order to run the program. Note + that libraries which are dynamically linked to an application will + be automatically detected and added to <emphasis + role="bold">RDEPENDS</emphasis> and therefore do not need to be + explicitly declared. If a library was dynamically loaded then it + would need to be explicitly listed.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>If we take openssh for an example, it requires zlib and openssl in + order to both built and run. In the recipe we have:<screen>DEPENDS = "zlib openssl"</screen>This + tells bitbake that it will need to build and stage zlib and openssl prior + to trying to build openssh, since openssh requires both of them. Note that + there is no <emphasis role="bold">RDEPENDS</emphasis> even though openssh + requires both of them to run. The run time dependencies on libz1 (the name + of the package containing the zlib library) and libssl0 (the name of the + package containing the ssl library) are automatically determined and added + via the auto shared libs dependency code.</para> + </section> + + <section id="recipes_methods" xreflabel="methods"> + <title>Methods: Inbuilt methods to make your life easier</title> + + <para>There are several helper functions defined by the base class, which + is included by default for all recipes. Many of these are used a lot in + both recipes and other classes.</para> + + <para>The most commonly seen, and most useful functions, include:</para> + + <variablelist> + <varlistentry> + <term>oe_runmake</term> + + <listitem> + <para>This function is used to run make. However unlike calling make + yourself this will pass the EXTRA_OEMAKE settings to make, will + display a note about the make command and will check for any errors + generated via the call to make.</para> + + <para>You should never have any reason to call make directly and + should also use oe_runmake when you need to run make.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>oe_runconf (autotools only)</term> + + <listitem> + <para>This function is used to run the configure script of a package + that is using the autotools class. This takes care of passing all of + the correct parameters for cross-compiling and for installing into + the appropriate target directory.</para> + + <para>It also passes the value of the <emphasis + role="bold">EXTRA_OECONF</emphasis> variable to the configure + script. For many situations setting <emphasis + role="bold">EXTRA_OECONF</emphasis> is sufficient and you'll have no + need to define your own configure task in which you call oe_runconf + manually.</para> + + <para>If you need to write your own <emphasis>configure</emphasis> + task for an autotools package you can use oe_runconf to manually + call the configure process when it is required. The following + example from net-snmp shows oe_runconf being called manually so that + the parameter for specifying the endianess can be computed and + passed in to the configure script:<screen>do_configure() { + # Additional flag based on target endiness (see siteinfo.bbclass) + ENDIANESS="${@base_conditional('SITEINFO_ENDIANESS', 'le', '--with-endianness=little', '--with-endianness=big', d)}" + oenote Determined endianess as: $ENDIANESS + oe_runconf $ENDIANESS +}</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>oe_libinstall</term> + + <listitem> + <para>This function is used to install <emphasis + role="bold">.so</emphasis>, <emphasis role="bold">.a</emphasis> and + associated libtool <emphasis role="bold">.la</emphasis> libraries. + It will determine the appropriate libraries to install and take care + of any modifications that may be require for <emphasis + role="bold">.la</emphasis> files.</para> + + <para>This function supports the following options:</para> + + <variablelist> + <varlistentry> + <term>-C <dir></term> + + <listitem> + <para>Change into the specified directory before attempting to + install a library. Used when the libraries are in + subdirectories of the main package.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>-s</term> + + <listitem> + <para>Require the presence of a <emphasis + role="bold">.so</emphasis> library as one of the libraries + that is installed.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>-a</term> + + <listitem> + <para>Require the presence of a <emphasis + role="bold">.a</emphasis> library as one of the libraries that + is installed.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>The following example from gdbm shows the installation of + <emphasis role="bold">.so</emphasis>, <emphasis + role="bold">.a</emphasis> (and associated <emphasis + role="bold">.la</emphasis>) libraries into the staging library + area:<screen>do_stage () { + oe_libinstall -so -a libgdbm ${STAGING_LIBDIR} + install -m 0644 ${S}/gdbm.h ${STAGING_INCDIR}/ +}</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>oenote</term> + + <listitem> + <para>Used to display an informational messages to the user.</para> + + <para>The following example from net-snmp uses oenote to tell the + user which endianess it determined was appropriate for the target + device:<screen>do_configure() { + # Additional flag based on target endiness (see siteinfo.bbclass) + ENDIANESS="${@base_conditional('SITEINFO_ENDIANESS', 'le', '--with-endianness=little', '--with-endianness=big', d)}" + oenote Determined endianess as: $ENDIANESS + oe_runconf $ENDIANESS +}</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>oewarn</term> + + <listitem> + <para>Used to display a warning message to the user, warning of + something that may be problematic or unexpected.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>oedebug</term> + + <listitem> + <para>Used to display debugging related information. These messages + will only be visible when bitbake is run with the <emphasis + role="bold">-D</emphasis> flag to enable debug output.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>oefatal</term> + + <listitem> + <para>Used to display a fatal error message to the user, and then + abort the bitbake run.</para> + + <para>The following example from linux-libc-headers shows the use of + oefatal to tell the user when it cannot find the kernel source code + for the specified target architecture:<screen>do_configure () { + case ${TARGET_ARCH} in + alpha*) ARCH=alpha ;; + arm*) ARCH=arm ;; + cris*) ARCH=cris ;; + hppa*) ARCH=parisc ;; + i*86*) ARCH=i386 ;; + ia64*) ARCH=ia64 ;; + mips*) ARCH=mips ;; + m68k*) ARCH=m68k ;; + powerpc*) ARCH=ppc ;; + s390*) ARCH=s390 ;; + sh*) ARCH=sh ;; + sparc64*) ARCH=sparc64 ;; + sparc*) ARCH=sparc ;; + x86_64*) ARCH=x86_64 ;; + esac + if test ! -e include/asm-$ARCH; then + oefatal unable to create asm symlink in kernel headers + fi +...</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>base_conditional (python)</term> + + <listitem> + <para>The base conditional python function is used to set a variable + to one of two values based on the definition of a third variable. + The general usage is:<screen>${@base_conditional('<variable-name>', '<value>', '<true-result>', <false-result>', d)}"</screen>where:</para> + + <variablelist> + <varlistentry> + <term>variable-name</term> + + <listitem> + <para>This is the name of a variable to check.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>value</term> + + <listitem> + <para>This is the value to compare the variable + against.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>true-result</term> + + <listitem> + <para>If the variable equals the value then this is what is + returned by the function.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>false-result</term> + + <listitem> + <para>If the variable does not equal the value then this is + what is returned by the function.</para> + </listitem> + </varlistentry> + </variablelist> + + <note> + <para>The ${@...} syntax is used to call python functions from + within a recipe or class. This is described in more detail in the + <xref linkend="recipes_advanced_python" /> section.</para> + </note> + + <para>The following example from the openssl recipe shows the + addition of either <emphasis role="bold">-DL_ENDING</emphasis> or + <emphasis role="bold">-DB_ENDIAN</emphasis> depending on the value + of <emphasis role="bold">SITEINFO_ENDIANESS</emphasis> which is set + to le for little endian targets and to be for big endian + targets:<screen>do_compile () { + ... + # Additional flag based on target endiness (see siteinfo.bbclass) + CFLAG="${CFLAG} ${@base_conditional('SITEINFO_ENDIANESS', 'le', '-DL_ENDIAN', '-DB_ENDIAN', d)}" + ...</screen></para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section id="recipes_packages" xreflabel="packages"> + <title>Packaging: Defining packages and their contents</title> + + <para>A bitbake recipe is a set of instructions from creating one, or + more, packages for installation on the target device. Typically these are + .ipkg or .deb packages (although bitbake itself isn't associated with any + particular packaging format).</para> + + <para>By default several packages are produced automatically without any + special action required on the part of the recipe author. The following + example of the packaging output from the helloworld example above shows + this packaging in action:<screen>[NOTE: package helloworld-0.1-r0: task do_package_write: started +NOTE: Not creating empty archive for helloworld-dbg-0.1-r0 +Packaged contents of helloworld into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/helloworld_0.1-r0_sh4.ipk +Packaged contents of helloworld-doc into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/helloworld-doc_0.1-r0_sh4.ipk +NOTE: Not creating empty archive for helloworld-dev-0.1-r0 +NOTE: Not creating empty archive for helloworld-locale-0.1-r0 +NOTE: package helloworld-0.1-r0: task do_package_write: completed</screen>We + can see from above that the packaging did the following:</para> + + <itemizedlist> + <listitem> + <para>Created a main package, <emphasis + role="bold">helloworld_0.1-r0_sh4.ipk</emphasis>. This package + contains the helloworld binary <emphasis + role="bold">/usr/bin/helloworld</emphasis>.</para> + </listitem> + + <listitem> + <para>Created a documentation package, <emphasis + role="bold">helloworld-doc_0.1-r0_sh4.ipk</emphasis>. This package + contains the readme file <emphasis + role="bold">/usr/share/doc/helloworld/README.txt</emphasis>.</para> + </listitem> + + <listitem> + <para>Considered creating a debug package, <emphasis + role="bold">helloworld-dbg-0.1-r0_sh4.ipk</emphasis>, a development + package <emphasis role="bold">helloworld-dev-0.1-r0_sh4.ipk</emphasis> + and a locale package <emphasis + role="bold">helloworld-locale-0.1-r0_sh4.ipk</emphasis>. It didn't + create the package due to the fact that it couldn't find any files + that would actually go in the package.</para> + </listitem> + </itemizedlist> + + <para>There are several things happening here which are important to + understand:</para> + + <orderedlist> + <listitem> + <para>There is a default set of packages that are considered for + creation. This set of packages is controlled via the <emphasis + role="bold">PACKAGES</emphasis> variable.</para> + </listitem> + + <listitem> + <para>For each package there is a default set of files and/or + directories that are considered to belong to those packages. The + documentation packages for example include anything found <emphasis + role="bold">/usr/share/doc</emphasis>. The set of files and + directories is controlled via the <emphasis + role="bold">FILES_<package-name></emphasis> variables.</para> + </listitem> + + <listitem> + <para>By default packages that contain no files are not created and no + error is generated. The decision to create empty packages or not is + controlled via the <emphasis role="bold">ALLOW_EMPTY</emphasis> + variable.</para> + </listitem> + </orderedlist> + + <section> + <title>Philosophy</title> + + <para>Separate packaging, where possible, is of high importance in + OpenEmbedded. Many of the target devices have limited storage space and + RAM and giving distributions and users the option of not installing a + part of the package they don't need allows them to reduce the amount of + storage space required.</para> + + <para>As an example almost no distributions will include documentation + or development libraries since they are not required for the day to day + operation of the device. In particular if your package provides multiple + binaries, and it would be common to only use one or the other, then you + should consider separating them into separate packages.</para> + + <para>By default several groups of files are automatically separate out, + including:</para> + + <variablelist> + <varlistentry> + <term>dev</term> + + <listitem> + <para>Any files required for development. This includes header + files, static libraries, the shared library symlinks required only + for linking etc. These would only ever need to be installed by + someone attempt to compile applications on the target device. + While this does happen it is very uncommon and so these files are + automatically moved into a separate package</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>doc</term> + + <listitem> + <para>Any documentation related files, including man pages. These + are files which are of informational purposes only. For many + embedded devices there is no way for the user to see any of the + documentation anyway, and documentation can consume a lot of + space. By separating these out they don't take any space by + default but distributions and/or users may choose to install them + if they need some documentation on a specific package.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>locale</term> + + <listitem> + <para>Locale information provides translation information for + packages. Many users do not require these translations, and many + devices will only want to provide them for user visible + components, such as UI related items, and not for system binaries. + By separating these out it is left up to the distribution or users + to decide if they are required or not.</para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section> + <title>Default packages and files</title> + + <para>The defaults package settings are defined in <emphasis + role="bold">conf/bitbake.conf</emphasis> and are suitable for a lot of + recipes without any changes. The following list shows the default values + for the packaging related variables:</para> + + <para><variablelist> + <varlistentry> + <term>PACKAGES</term> + + <listitem> + <para>This variable lists the names of each of the packages that + are to be generated.<screen>PACKAGES = "${PN}-dbg ${PN} ${PN}-doc ${PN}-dev ${PN}-locale"</screen>Note + that the order of packages is important: the packages are + processed in the listed order. So if two packages specify the + same file then the first package listed in packages will get the + file. This is important when packages use wildcards to specify + their contents.</para> + + <para>For example if the main package, <emphasis + role="bold">${PN}</emphasis>, contains <emphasis + role="bold">/usr/bin/*</emphasis> (i.e. all files in <emphasis + role="bold">/usr/bin</emphasis>), but you want <emphasis + role="bold">/usr/bin/tprogram</emphasis> in a separate package, + <emphasis role="bold">${PN}-tpackage</emphasis>, you would need + to either ensure that <emphasis + role="bold">${PN}-tpackage</emphasis> is listed prior to + <emphasis role="bold">${PN}</emphasis> in <emphasis + role="bold">PACKAGES</emphasis> or that <emphasis + role="bold">FILES_${PN}</emphasis> was modified to not contain + the wildcard that matches <emphasis + role="bold">/usr/bin/tprogram</emphasis>.</para> + + <para>Note that the -dbg package contains the debugging + information that has been extracted from binaries and libraries + prior to them being stripped. This package should always be the + first package in the package list to ensure that the debugging + information is correctly extracted and moved to the package + prior to any other packaging decisions being made.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FILES_${PN}</term> + + <listitem> + <para>The base package, this includes everything needed to + actually run the application on the target system.<screen>FILES_${PN} = "\ + ${bindir}/* \ + ${sbindir}/* \ + ${libexecdir}/* \ + ${libdir}/lib*.so.* \ + ${sysconfdir} \ + ${sharedstatedir} \ + ${localstatedir} \ + /bin/* \ + /sbin/* \ + /lib/*.so* \ + ${datadir}/${PN} \ + ${libdir}/${PN}/* \ + ${datadir}/pixmaps \ + ${datadir}/applications \ + ${datadir}/idl \ + ${datadir}/omf \ + ${datadir}/sounds \ + ${libdir}/bonobo/servers"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FILES_${PN}-dbg</term> + + <listitem> + <para>The debugging information extracted from non-stripped + versions of libraries and executable's. OpenEmbedded + automatically extracts the debugging information into files in + .debug directories and then strips the original files.<screen>FILES_${PN}-dbg = "\ + ${bindir}/.debug \ + ${sbindir}/.debug \ + ${libexecdir}/.debug \ + ${libdir}/.debug \ + /bin/.debug \ + /sbin/.debug \ + /lib/.debug \ + ${libdir}/${PN}/.debug"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FILES_${PN}-doc</term> + + <listitem> + <para>Documentation related files. All documentation is + separated into it's own package so that it does not need to be + installed unless explicitly required.<screen>FILES_${PN}-doc = "\ + ${docdir} \ + ${mandir} \ + ${infodir} \ + ${datadir}/gtk-doc \ + ${datadir}/gnome/help"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FILES_${PN}-dev</term> + + <listitem> + <para>Development related files. Any headers, libraries and + support files needed for development work on the target.<screen>FILES_${PN}-dev = "\ + ${includedir} \ + ${libdir}/lib*.so \ + ${libdir}/*.la \ + ${libdir}/*.a \ + ${libdir}/*.o \ + ${libdir}/pkgconfig \ + /lib/*.a \ + /lib/*.o \ + ${datadir}/aclocal"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FILES_${PN}-locale</term> + + <listitem> + <para>Locale related files.<screen>FILES_${PN}-locale = "${datadir}/locale"</screen></para> + </listitem> + </varlistentry> + </variablelist></para> + </section> + + <section> + <title>Wildcards</title> + + <para>Wildcards used in the <emphasis role="bold">FILES</emphasis> + variables are processed via the python function <emphasis + role="bold">fnmatch</emphasis>. The following items are of note about + this function:</para> + + <itemizedlist> + <listitem> + <para><emphasis role="bold">/<dir>/*</emphasis>: This will + match all files and directories in the <emphasis + role="bold">dir</emphasis> - it will not match other + directories.</para> + </listitem> + + <listitem> + <para><emphasis role="bold">/<dir>/a*</emphasis>: This will + only match files, and not directories.</para> + </listitem> + + <listitem> + <para><emphasis role="bold">/dir</emphasis>: will include the + directory <emphasis role="bold">dir</emphasis> in the package, which + in turn will include all files in the directory and all + subdirectories.</para> + </listitem> + </itemizedlist> + + <para>Note that the order of packages effects the files that will be + matched via wildcards. Consider the case where we have three binaries in + the <command>/usr/bin</command> directory and we want the test program + in a separate package:<screen>/usr/bin/programa /usr/bin/programb /usr/bin/test</screen>So + we define a new package and instruct bitbake to include /usr/bin/test in + it.</para> + + <screen>FILES-${PN}-test = "${bindir}/test" +PACKAGES += "FILES-${PN}-test"</screen> + + <para>When the package is regenerated no <emphasis + role="bold">${PN}-test</emphasis> package will be created. The reason + for this is that the <emphasis role="bold">PACKAGES</emphasis> line now + looks like this:<screen>{PN}-dbg ${PN} ${PN}-doc ${PN}-dev ${PN}-locale ${PN}-test</screen>Note + how <emphasis role="bold">${PN}</emphasis> is listed prior to <emphasis + role="bold">${PN}-test</emphasis>, and if we look at the definition of + <emphasis role="bold">FILES-${PN}</emphasis> it contains the <emphasis + role="bold">${bindir}/*</emphasis> wildcard. Since <emphasis + role="bold">${PN}</emphasis> is first it'll match that wildcard are be + moved into the <emphasis role="bold">${PN}</emphasis> package prior to + processing of the <emphasis role="bold">${PN}-test</emphasis> + package.</para> + + <para>To achieve what we are trying to accomplish we have two + options:</para> + + <orderedlist> + <listitem> + <para>Modify the definition of <emphasis + role="bold">${PN}</emphasis> so that the wildcard does not match the + test program.</para> + + <para>We could do this for example:<screen>FILES-${PN} = "${bindir}/p*"</screen>So + now this will only match things in the bindir that start with p, and + therefore not match our test program. Note that <emphasis + role="bold">FILES-${PN}</emphasis> contains a lot more entries and + we'd need to add any of the other that refer to files that are to be + included in the package. In this case we have no other files, so + it's safe to do this simple declaration.</para> + </listitem> + + <listitem> + <para>Modify the order of packages so that the <emphasis + role="bold">${PN}-test</emphasis> package is listed first.</para> + + <para>The most obvious way to do this would be to prepend our new + package name to the packages list instead of appending it:<screen>PACKAGES =+ "FILES-${PN}-test"</screen>In + some cases this would work fine, however there is a problem with + this for packages that include binaries. The package will now be + listed before the -dbg package and often this will result in the + .debug directories being included in the package. In this case we + are explicitly listing only a single file (and not using wildcards) + and therefore it would be ok.</para> + + <para>In general it's more common to have to redefine the entire + package list to include your new package plus any of the default + packages that you require:<screen>PACKAGES = "${PN}-dbg ${PN}-test ${PN} ${PN}-doc ${PN}-dev ${PN}-locale"</screen></para> + </listitem> + </orderedlist> + </section> + + <section> + <title>Checking the packages</title> + + <para>During recipe development it's useful to be able to check on + exactly what files went into each package, which files were not packaged + and which packages contain no files.</para> + + <para>One of easiest method is to run find on the install directory. In + the install directory there is one subdirectory created per package, and + the files are moved into the install directory as they are matched to a + specific package. The following shows the packages and files for the + helloworld example:<screen>~/oe%> find tmp/work/helloworld-0.1-r0/install +tmp/work/helloworld-0.1-r0/install +tmp/work/helloworld-0.1-r0/install/helloworld-locale +tmp/work/helloworld-0.1-r0/install/helloworld-dbg +tmp/work/helloworld-0.1-r0/install/helloworld-dev +tmp/work/helloworld-0.1-r0/install/helloworld-doc +tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr +tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share +tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share/doc +tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share/doc/helloworld +tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share/doc/helloworld/README.txt +tmp/work/helloworld-0.1-r0/install/helloworld +tmp/work/helloworld-0.1-r0/install/helloworld/usr +tmp/work/helloworld-0.1-r0/install/helloworld/usr/bin +tmp/work/helloworld-0.1-r0/install/helloworld/usr/bin/helloworld +~/oe%></screen>The above shows that the -local, -dbg and -dev packages are + all empty, and the -doc and base package contain a single file each. + Uses "<emphasis role="bold">-type f</emphasis>" option to find to show + just files will make this clearer as well.</para> + + <para>In addition to the install directory the image directory (which + corresponds to the destination directory, <emphasis + role="bold">D</emphasis>) will contain any files that were not + packaged:<screen>~/oe%> find tmp/work/helloworld-0.1-r0/image +tmp/work/helloworld-0.1-r0/image +tmp/work/helloworld-0.1-r0/image/usr +tmp/work/helloworld-0.1-r0/image/usr/bin +tmp/work/helloworld-0.1-r0/image/usr/share +tmp/work/helloworld-0.1-r0/image/usr/share/doc +tmp/work/helloworld-0.1-r0/image/usr/share/doc/helloworld +~/oe%></screen>In this case all files were packaged and so there are no + left over files. Using find with "<emphasis role="bold">-type + f</emphasis>" makes this much clearer:<screen>~/oe%> find tmp/work/helloworld-0.1-r0/image -type f +~/oe%></screen></para> + + <para>Messages reading missing files are also display by bitbake during + the package task:<screen>NOTE: package helloworld-0.1-r0: task do_package: started +NOTE: the following files were installed but not shipped in any package: +NOTE: /usualdir/README.txt +NOTE: package helloworld-0.1-r0: task do_package: completed</screen>Except in + very unusual circumstances there should be no unpackaged files left + behind by a recipe.</para> + </section> + + <section> + <title>Excluding files</title> + + <para>There's no actual support for explicitly excluding files from + packaging. You could just leave them out of any package, but then you'll + get warnings (or errors if requesting full package checking) during + packaging which is not desirable. It also doesn't let other people know + that you've deliberately avoided packaging the file or files.</para> + + <para>In order to exclude a file totally you should avoid installing it + in the first place during the install task.</para> + + <para>In some cases it may be easier to let the package install the file + and then explicitly remove the file and the end of the install task. The + following example from the samba recipe shows the removal of several + files that get installed via the default install task generated by the + <xref linkend="autotools_class" />. By using + <emphasis>do_install_append</emphasis> these commands and run after the + autotools generated install task:</para> + + <screen>do_install_append() { + ... + rm -f ${D}${bindir}/*.old + rm -f ${D}${sbindir}/*.old + ... +}</screen> + </section> + + <section> + <title>Debian naming</title> + + <para>A special <emphasis>debian library name</emphasis> policy can be + applied for packages that contain a single shared library. When enabled + packages will be renamed to match the debian policy for such + packages.</para> + + <para>Debian naming is enabled by including the debian class via either + <command>local.conf</command> or your distributions configuration + file:<screen>INHERIT += "debian"</screen></para> + + <para>The policy works by looking at the shared library name and version + and will automatically rename the package to + <emphasis><libname><lib-major-version></emphasis>. For + example if the package name (PN) is <command>foo</command> and the + package ships a file named <command>libfoo.so.1.2.3</command> then the + package will be renamed to <command>libfoo1</command> to follow the + debian policy.</para> + + <para>If we look at the <emphasis>lzo_1.08.bb</emphasis> recipe, + currently at release 14, it generates a package containing a single + shared library :<screen>~oe/build/titan-glibc-25%> find tmp/work/lzo-1.08-r14/install/ +tmp/work/lzo-1.08-r14/install/lzo +tmp/work/lzo-1.08-r14/install/lzo/usr +tmp/work/lzo-1.08-r14/install/lzo/usr/lib +tmp/work/lzo-1.08-r14/install/lzo/usr/lib/liblzo.so.1 +tmp/work/lzo-1.08-r14/install/lzo/usr/lib/liblzo.so.1.0.0</screen>Without + debian naming this package would have been called + <command>lzo_1.08-r14_sh4.ipk</command> (and the corresponding dev and + dbg packages would have been called + <command>lzo-dbg_1.08-r14_sh4.ipk</command> and + <command>lzo-dev_1.08-r14_sh4.ipk</command>). However with debian naming + enabled the package is renamed based on the name of the shared library, + which is <command>liblzo.so.1.0.0</command> in this case. So the name + <command>lzo</command> is replaced with + <command>liblzo1</command>:<screen>~oe/build/titan-glibc-25%> find tmp/deploy/ipk/ -name '*lzo*' +tmp/deploy/ipk/sh4/liblzo1_1.08-r14_sh4.ipk +tmp/deploy/ipk/sh4/liblzo-dev_1.08-r14_sh4.ipk +tmp/deploy/ipk/sh4/liblzo-dbg_1.08-r14_sh4.ipk</screen></para> + + <para>Some variables are available which effect the operation of the + debian renaming class:</para> + + <variablelist> + <varlistentry> + <term>LEAD_SONAME</term> + + <listitem> + <para>If the package actually contains multiple shared libraries + then one will be selected automatically and a warning will be + generated. This variable is a regular expression which is used to + select which shared library from those available is to be used for + debian renaming.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>DEBIAN_NOAUTONAME_<pkgname></term> + + <listitem> + <para>If this variable is set to 1 for a package then debian + renaming will not be applied for the package.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>AUTO_LIBNAME_PKGS</term> + + <listitem> + <para>If set this variable specifies the prefix of packages which + will be subject to debian renaming. This can be used to prevent + all of the packages being renamed via the renaming policy.</para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section> + <title>Empty packages</title> + + <para>By default empty packages are ignored. Occasionally you may wish + to actually created empty packages, typically done when you want a + virtual package which will install other packages via dependencies + without actually installing anything itself. The <emphasis + role="bold">ALLOW_EMPTY</emphasis> variable is used to control the + creation of empty packages:</para> + + <variablelist> + <varlistentry> + <term>ALLOW_EMPTY</term> + + <listitem> + <para>Controls if empty packages will be created or not. By + default this is <emphasis role="bold">"0"</emphasis> and empty + packages are not created. Setting this to <emphasis + role="bold">"1"</emphasis> will permit the creation of empty + packages (packages containing no files).</para> + </listitem> + </varlistentry> + </variablelist> + </section> + </section> + + <section id="recipes_tasks" xreflabel="tasks"> + <title>Tasks: Playing with tasks</title> + + <para>Bitbake steps through a series of tasks when building a recipe. + Sometimes you need to explicitly define what a class does, such as + providing a <emphasis role="bold">do_install</emphasis> function to + implement the <emphasis>install</emphasis> task in a recipe and sometimes + they are provided for you by common classes, such as the autotools class + providing the default implementations of <emphasis>configure</emphasis>, + <emphasis>compile</emphasis> and <emphasis>install</emphasis> + tasks.</para> + + <para>There are several methods available to modify the tasks that are + being run:</para> + + <variablelist> + <varlistentry> + <term>Overriding the default task implementation</term> + + <listitem> + <para>By defining your own implementation of task you'll override + any default or class provided implementations.</para> + + <para>For example, you can define you own implementation of the + compile task to override any default implementation:<screen>do_compile() { + oe_runmake DESTDIR=${D} +}</screen></para> + + <para>If you with to totally prevent the task from running you need + to define your own empty implementation. This is typically done via + the definition of the task using a single colon:<screen>do_configure() { + : +}</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Appending or prepending to the task</term> + + <listitem> + <para>Sometime you want the default implementation, but you require + addition functionality. This can done by appending or pre-pending + additional functionality onto the task.</para> + + <para>The following example from units shows an example of + installing an addition file which for some reason was not installed + via the autotools normal <emphasis>install</emphasis> task:<screen>do_install_append() { + install -d ${D}${datadir} + install -m 0655 units.dat ${D}${datadir} +}</screen></para> + + <para>The following example from the cherokee recipe show an example + of adding functionality prior to the default + <emphasis>install</emphasis> task. In this case it compiles a + program that is used during installation natively so that it will + work on the host. Without this the autotools default + <emphasis>install</emphasis> task would fail since it'd try to run + the program on the host which was compiled for the target:<screen>do_install_prepend () { + # It only needs this app during the install, so compile it natively + $BUILD_CC -DHAVE_SYS_STAT_H -o cherokee_replace cherokee_replace.c +}</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Defining a new task</term> + + <listitem> + <para>Another option is define a totally new task, and then register + that with bitbake so that it runs in between two of the existing + tasks.</para> + + <para>The following example shows a situation in which a cvs tree + needs to be copied over the top of an extracted tar.gz archive, and + this needs to be done before any local patches are applied. So a new + task is defined to perform this action, and then that task is + registered to run between the existing <emphasis>unpack</emphasis> + and <emphasis>patch</emphasis> tasks:<screen>do_unpack_extra(){ + cp -pPR ${WORKDIR}/linux/* ${S} +} +addtask unpack_extra after do_unpack before do_patch</screen></para> + + <note> + <para>The task to add does not have the do_ prepended to it, + however the tasks to insert it after and before do have the _do + prepended. No errors will be generated if this is wrong, the + additional task simple won't be executed.</para> + </note> + </listitem> + </varlistentry> + + <varlistentry> + <term>Using overrides</term> + + <listitem> + <para>Overrides (described fully elsewhere) allow for various + functionality to be performed conditionally based on the target + machine, distribution, architecture etc.</para> + + <para>While not commonly used it is possible to use overrides when + defining tasks. The following example from udev shows an additional + file being installed for the specified machine only by performing an + append to the <emphasis>install</emphasis> task for the h2200 + machine only:<screen>do_install_append_h2200() { + install -m 0644 ${WORKDIR}/50-hostap_cs.rules ${D}${sysconfdir}/udev/rules.d/50-hostap_cs.rules +}</screen></para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section id="recipes_classes" xreflabel="classes"> + <title>Classes: The separation of common functionality</title> + + <para>Often a certain pattern is followed in more than one recipe, or + maybe some complex python based functionality is required to achieve the + desired end result. This is achieved through the use of classes, which can + be found in the classes subdirectory at the top-level of on OE + checkout.</para> + + <para>Being aware of the available classes and understanding their + functionality is important because classes:</para> + + <itemizedlist> + <listitem> + <para>Save developers time being performing actions that they would + otherwise need to perform themselves;</para> + </listitem> + + <listitem> + <para>Perform a lot of actions in the background making a lot of + recipes difficult to understand unless you are aware of classes and + how they work;</para> + </listitem> + + <listitem> + <para>A lot of detail on how things work can be learnt for looking at + how classes are implement.</para> + </listitem> + </itemizedlist> + + <para>A class is used via the inherit method. The following is an example + for the <emphasis>curl</emphasis> recipe showing that it uses three + classes:<screen>inherit autotools pkgconfig binconfig</screen>In this case + it is utilising the services of three separate classes:</para> + + <variablelist> + <varlistentry> + <term>autotools</term> + + <listitem> + <para>The <xref linkend="autotools_class" /> is used by programs + that use the GNU configuration tools and takes care of the + configuration and compilation of the software;</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>pkgconfig</term> + + <listitem> + <para>The <xref linkend="pkgconfig_class" /> is used to stage the + <emphasis>.pc</emphasis> files which are used by the <emphasis + role="bold">pkg-config</emphasis> program to provide information + about the package to other software that wants to link to this + software;</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>binconfig</term> + + <listitem> + <para>The <xref linkend="binconfig_class" /> is used to stage the + <emphasis><name>-config</emphasis> files which are used to + provide information about the package to other software that wants + to link to this software;</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Each class is implemented via the file in the <emphasis + role="bold">classes</emphasis> subdirectory named <emphasis + role="bold"><classname>.bbclass</emphasis> and these can be examined + for further details on a particular class, although sometimes it's not + easy to understand everything that's happening. Many of the classes are + covered in detail in various sections in this user manual.</para> + </section> + + <section id="recipes_staging" xreflabel="staging"> + <title>Staging: Making includes and libraries available for + building</title> + + <para>Staging is the process of making files, such as include files and + libraries, available for use by other recipes. This is different to + installing because installing is about making things available for + packaging and then eventually for use on the target device. Staging on the + other hand is about making things available on the host system for use by + building later applications.</para> + + <para>Taking bzip2 as an example you can see that it stages a header file + and it's library files:<screen>do_stage () { + install -m 0644 bzlib.h ${STAGING_INCDIR}/ + oe_libinstall -a -so libbz2 ${STAGING_LIBDIR} +}</screen></para> + + <para>The <emphasis>oe_libinstall</emphasis> method used in the bzip2 + recipe is described in the <xref linkend="recipes_methods" /> section, and + it takes care of installing libraries (into the staging area in this + case). The staging variables are automatically defined to the correct + staging location, in this case the main staging variables are used:</para> + + <variablelist> + <varlistentry> + <term>STAGING_INCDIR</term> + + <listitem> + <para>The directory into which staged headers files should be + installed. This is the equivalent of the standard <emphasis + role="bold">/usr/include</emphasis> directory.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>STAGING_LIBDIR</term> + + <listitem> + <para>The directory into which staged library files should be + installed. This is the equivalent of the standard <emphasis + role="bold">/usr/lib</emphasis> directory.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Additional staging related variables are covered in the <xref + linkend="directories_staging" /> section in <xref + linkend="chapter_reference" />.</para> + + <para>Looking in the staging area under tmp you can see the result of the + bzip2 recipes staging task:<screen>%> find tmp/staging -name '*bzlib*' +tmp/staging/sh4-linux/include/bzlib.h +%> find tmp/staging -name '*libbz*' +tmp/staging/sh4-linux/lib/libbz2.so +tmp/staging/sh4-linux/lib/libbz2.so.1.0 +tmp/staging/sh4-linux/lib/libbz2.so.1 +tmp/staging/sh4-linux/lib/libbz2.so.1.0.2 +tmp/staging/sh4-linux/lib/libbz2.a</screen></para> + + <para>As well as being used during the stage task the staging related + variables are used when building other packages. Looking at the gnupg + recipe we see two bzip2 related items:<screen>DEPENDS = "zlib <emphasis + role="bold">bzip2</emphasis>" +... +EXTRA_OECONF = "--disable-ldap \ + --with-zlib=${STAGING_LIBDIR}/.. \ + <emphasis role="bold">--with-bzip2=${STAGING_LIBDIR}/..</emphasis> \ + --disable-selinux-support" +</screen></para> + + <para>Bzip2 is referred to in two places in the recipe:</para> + + <variablelist> + <varlistentry> + <term>DEPENDS</term> + + <listitem> + <para>Remember that <emphasis role="bold">DEPENDS</emphasis> defines + the list of build time dependencies. In this case the staged headers + and libraries from bzip2 are required to build gnupg, and therefore + we need to make sure the bzip2 recipe has run and staging the + headers and libraries. By adding the <emphasis + role="bold">DEPENDS</emphasis> on bzip2 this ensures that this + happens.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><emphasis role="bold">EXTRA_OECONF</emphasis></term> + + <listitem> + <para>This variable is used by the <xref + linkend="autotools_class" /> to provide options to the configure + script of the package. In the gnupg case it needs to be told where + the bzip2 headers and libraries files are, and this is done via the + <emphasis>--with-bzip2</emphasis> option. In this case it needs to + the directory which include the lib and include subdirectories. + Since OE doesn't define a variable for one level above the include + and lib directories <emphasis role="bold">..</emphasis> is used to + indicate one directory up. Without this gnupg would search the host + system headers and libraries instead of those we have provided in + the staging area for the target.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Remember that staging is used to make things, such as headers and + libraries, available to used by other recipes later on. While header and + libraries are the most common item requiring staging other items such as + the pkgconfig files need to be staged as well, while for native packages + the binaries also need to be staged.</para> + </section> + + <section id="recipes_autoconf" xreflabel="about autoconf"> + <title>Autoconf: All about autotools</title> + + <para>This section is to be completed:</para> + + <itemizedlist> + <listitem> + <para>About building autoconf packages</para> + </listitem> + + <listitem> + <para>EXTRA_OECONF</para> + </listitem> + + <listitem> + <para>Problems with /usr/include, /usr/lib</para> + </listitem> + + <listitem> + <para>Configuring to search in the staging area</para> + </listitem> + + <listitem> + <para>-L${STAGING_LIBDIR} vs ${TARGET_LDFLAGS}</para> + </listitem> + + <listitem> + <para>Site files</para> + </listitem> + </itemizedlist> + </section> + + <section id="recipes_installation_scripts" xreflabel="installation scripts"> + <title>Installation scripts: Running scripts during package install and/or + removal</title> + + <para>Packaging system such as .ipkg and .deb support pre and post + installation and pre and post removal scripts which are run during package + install and/or package removal on the target system.</para> + + <para>These scripts can be defined in your recipes to enable actions to be + performed at the appropriate time. Common uses include starting new + daemons on installation, stopping daemons during uninstall, creating new + user and/or group entries during install, registering and unregistering + alternative implementations of commands and registering the need for + volatiles.</para> + + <para>The following scripts are supported:</para> + + <variablelist> + <varlistentry> + <term>preinst</term> + + <listitem> + <para>The preinst script is run prior to installing the contents of + the package. During preinst the contents of the package are not + available to be used as part of the script. The preinst scripts are + not commonly used.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>postinst</term> + + <listitem> + <para>The postinst script is run after the installation of the + package has completed. During postinst the contents of the package + are available to be used. This is often used for the creation of + volatile directories, registration of daemons, starting of daemons + and fixing up of SUID binaries.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>prerm</term> + + <listitem> + <para>The prerm is run prior to the removal of the contents of a + package. During prerm the contents of the package are still + available for use by the script. The prerm scripts</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>postrm</term> + + <listitem> + <para>The postrm script is run after the completion of the removal + of the contents of a package. During postrm the contents of the + package no longer exist and therefore are not available for use by + the script. Postrm is most commonly used for update alternatives (to + tell the alternatives system that this alternative is not available + and another should be selected).</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Scripts are registered by defining a function for:</para> + + <itemizedlist> + <listitem> + <para>pkg_<scriptname>_<packagename></para> + </listitem> + </itemizedlist> + + <para>The following example from ndisc6 shows postinst scripts being + registered for three of the packages that ndisc6 creates:<screen># Enable SUID bit for applications that need it +pkg_postinst_${PN}-rltraceroute6 () { + chmod 4555 ${bindir}/rltraceroute6 +} +pkg_postinst_${PN}-ndisc6 () { + chmod 4555 ${bindir}/ndisc6 +} +pkg_postinst_${PN}-rdisc6 () { + chmod 4555 ${bindir}/rdisc6 +}</screen></para> + + <note> + <para>These scripts will be run via <emphasis + role="bold">/bin/sh</emphasis> on the target device, which is typically + the busybox sh but could also be bash or some other sh compatible shell. + As always you should not use any bash extensions in your scripts and + stick to basic sh syntax.</para> + </note> + + <para>Note that several classes will also register scripts, and that any + script you declare will have the script for the classes append to by these + classes. The following classes all generate additional script + contents:</para> + + <variablelist> + <varlistentry> + <term>update-rc.d</term> + + <listitem> + <para>This class is used by daemons to register there init scripts + with the init code.</para> + + <para>Details are provided in the <xref + linkend="recipes_initscripts" /> section.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>module</term> + + <listitem> + <para>This class is used by linux kernel modules. It's responsible + for calling depmod and update-modules during kernel module + installation and removal.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>kernel</term> + + <listitem> + <para>This class is used by the linux kernel itself. There is a lot + of housekeeping required both when installing and removing a kernel + and this class is responsible for generating the required + scripts.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>qpf</term> + + <listitem> + <para>This class is used when installing and/or removing qpf fonts. + It register scripts to update the font paths and font cache + information to ensure that the font information is kept up to date + as fonts and installed and removed.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>update-alternatives</term> + + <listitem> + <para>This class is used by packages that contain binaries which may + also be available for other packages. It tells that system that + another alternative is available for consideration. The alternatives + system will create a symlink to the correct alternative from one or + more available on the system.</para> + + <para>Details are provided in the <xref + linkend="recipes_alternatives" /> section.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>gtk-icon-cache</term> + + <listitem> + <para>This class is used by packages that add new gtk icons. It's + responsible for updating the icon cache when packages are installed + and removed.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>gconf</term> + + <listitem> + <para></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>package</term> + + <listitem> + <para>The base class used by packaging classes such as those for + .ipkg and .deb. The package class may create scripts used to update + the dynamic linkers ld cache.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>The following example from p3scan shows and postinst script which + ensure that the required user and group entries exist, and registers the + need for volatiles (directories and/or files under <emphasis + role="bold">/var</emphasis>). In addition to explicitly declaring a + postinst script it uses the update-rc.d class which will result in an + additional entry being added to the postinst script to register the init + scripts and start the daemon (via call to update-rc.d as describes in the + <xref linkend="recipes_alternatives" /> section).<screen>inherit autotools update-rc.d + +... + +# Add havp's user and groups +pkg_postinst_${PN} () { + grep -q mail: /etc/group || addgroup --system havp + grep -q mail: /etc/passwd || \ + adduser --disabled-password --home=${localstatedir}/mail --system \ + --ingroup mail --no-create-home -g "Mail" mail + /etc/init.d/populate-volatile.sh update +}</screen></para> + + <para>Several scripts in existing recipes will be of the following + form:<screen>if [ x"$D" = "x" ]; then + ... +fi</screen></para> + + <para>This is testing if the installation directory, <emphasis + role="bold">D</emphasis>, is defined and if it is no actions are + performed. The installation directory will not be defined under normal + circumstances. The primary use of this test is to permit the application + to be installed during root filesystem generation. In that situation the + scripts cannot be run since the root filesystem is generated on the host + system and not on the target. Any required script actions would need to be + performed via an alternative method if the package is to be installed in + the initial root filesystem (such as including any required users and + groups in the default <emphasis role="bold">passwd</emphasis> and + <emphasis role="bold">group</emphasis> files for example.)</para> + </section> + + <section id="recipes_conffiles" xreflabel="conf files"> + <title>Configuration files</title> + + <para>Configuration files that are installed as part of a package require + special handling. Without special handling as soon as the user upgrades to + a new version of the package then changes they have made to the + configuration files will be lost.</para> + + <para>In order to prevent this from happening you need to tell the + packaging system which files are configuration files. Such files will + result in the user being asked how the user wants to handle any + configuration file changes (if any), as shown in this example:<screen>Downloading http://nynaeve.twibble.org/ipkg-titan-glibc//./p3scan_2.9.05d-r1_sh4.ipk + Configuration file '/etc/p3scan/p3scan.conf' + ==> File on system created by you or by a script. + ==> File also in package provided by package maintainer. + What would you like to do about it ? Your options are: + Y or I : install the package maintainer's version + N or O : keep your currently-installed version + D : show the differences between the versions (if diff is installed) + The default action is to keep your current version. + *** p3scan.conf (Y/I/N/O/D) [default=N] ?</screen>To declare a file as a + configuration file you need to define the + <command>CONFFILES_<pkgname></command> variable as a whitespace + separated list of configuration files. The following example from clamav + shows two files being marked as configuration files:<screen>CONFFILES_${PN}-daemon = "${sysconfdir}/clamd.conf \ + ${sysconfdir}/default/clamav-daemon"</screen>Note + the user of <command>${PN}-daemon</command> as the package name. The + <command>${PN}</command> variable will expand to <command>clamav</command> + and therefore these conf files are declared as being in the clamav-daemon + package.</para> + </section> + + <section id="recipes_package_relationships" + xreflabel="package relationships files"> + <title>Package relationships</title> + + <para>Explicit relationships between packages are support by packaging + formats such as ipkg and deb. These relationships include describing + conflicting packages and recommended packages.</para> + + <para>The following variables control the package relationships in the + recipes:</para> + + <variablelist> + <varlistentry> + <term>RRECOMMENDS</term> + + <listitem> + <para>Used to specify other packages that are recommended to be + installed when this package is installed. Generally this means while + the recommended packages are not required they provide some sort of + functionality which users would usually want.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>RCONFLICTS</term> + + <listitem> + <para>Used to specify other packages that conflict with this + package. Two packages that conflict cannot be installed at the same + time.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>RREPLACES</term> + + <listitem> + <para>Used to specify that the current package replaces an older + package with a different name. During package installing the package + that is being replaced will be removed since it is no longer needed + when this package is installed.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>RSUGGESTS</term> + + <listitem> + <para>Used to provide a list of suggested packages to install. These + are packages that are related to and useful for the current package + but which are not actually required to use the package.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>RPROVIDES</term> + + <listitem> + <para>Used to explicitly specify what a package provides at runtime. + For example hotplug support is provided by several packages, such as + udev and linux-hotplug. Both declare that they runtime provide + "hotplug". So any packages that require "hotplug" to work simply + declare that it RDEPENDS on "hotplug". It's up to the distribution + to specify which actual implementation of "virtual/xserver" is + used.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>PROVIDES</term> + + <listitem> + <para>Used to explicitly specify what a package provides at build + time. This is typically used when two or more packages can provide + the same functionality. For example there are several different X + servers in OpenEmbedded, and each as declared as providing + "virtual/xserver". Therefore a package that depends on an X server + to build can simply declare that it DEPENDS on "virtual/xserver". + It's up to the distribution to specify which actual implementation + of "virtual/xserver" is used.</para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section id="recipes_fakeroot" xreflabel="fakeroot"> + <title>Fakeroot: Dealing with the need for "root"</title> + + <para>Sometimes packages requires root permissions in order to perform + some action, such as changing user or group owners or creating device + nodes. Since OpenEmbedded will not keep the user and group information + it's usually preferably to remove that from the makefiles. For device + nodes it's usually preferably to create them from the initial device node + lists or via udev configuration.</para> + + <para>However if you can't get by without root permissions then you can + use <xref linkend="fakeroot" /> to simulate a root environment, without + the need to really give root access.</para> + + <para>Using <xref linkend="fakeroot" /> is done by prefixing the + task:<screen>fakeroot do_install() {</screen>Since this requires fakeroot + you also need to add a dependency on + <command>fakeroot-native</command>:<screen>DEPENDS = "fakeroot-native"</screen>See + the fuse recipe for an example. Further information on <xref + linkend="fakeroot" />, including a description of it works, is provided in + the reference section: <xref linkend="fakeroot" />.</para> + </section> + + <section id="recipes_native" xreflabel="native"> + <title>Native: Packages for the build host</title> + + <para>This section is to be completed.</para> + + <itemizedlist> + <listitem> + <para>What native packages are</para> + </listitem> + + <listitem> + <para>Using require with the non-native package</para> + </listitem> + </itemizedlist> + </section> + + <section id="recipes_development" xreflabel="development"> + <title>Development: Strategies for developing recipes</title> + + <para>This section is to be completed.</para> + + <itemizedlist> + <listitem> + <para>How to go about developing recipes</para> + </listitem> + + <listitem> + <para>How do handle incrementally creating patches</para> + </listitem> + + <listitem> + <para>How to deal with site file issues</para> + </listitem> + + <listitem> + <para>Strategies for autotools issues</para> + </listitem> + </itemizedlist> + </section> + + <section id="recipes_advanced_versioning" xreflabel="advanced versioning"> + <title>Advanced versioning: How to deal with rc and pre versions</title> + + <para>Special care needs to be taken when specify the version number for + rc and pre versions of packages.</para> + + <para>Consider the case where we have an existing 1.5 version and there's + a new 1.6-rc1 release that you want to add.</para> + + <itemizedlist> + <listitem> + <para>1.5: Existing version;</para> + </listitem> + + <listitem> + <para>1.6-rc1: New version.</para> + </listitem> + </itemizedlist> + + <para>If the new package is given the version number 1.6-rc1 then + everything will work fine initially. However when the final release + happens it will be called 1.6. If you now create a 1.6 version of the + package you'll find that the packages are sorted into the following + order:</para> + + <orderedlist> + <listitem> + <para>1.5</para> + </listitem> + + <listitem> + <para>1.6</para> + </listitem> + + <listitem> + <para>1.6-rc1</para> + </listitem> + </orderedlist> + + <para>This in turn result in packaging system, such as ipkg, considering + the released version to be older then the rc version.</para> + + <para>In OpenEmbedded the correct naming of pre and rc versions is to use + the previous version number followed by a + followed by the new version + number. So the 1.6-rc1 release would be given the version number:</para> + + <itemizedlist> + <listitem> + <para>1.5+1.6-rc1</para> + </listitem> + </itemizedlist> + + <para>These would result in the eventually ordering being:</para> + + <orderedlist> + <listitem> + <para>1.5</para> + </listitem> + + <listitem> + <para>1.5+1.6-rc1</para> + </listitem> + + <listitem> + <para>1.6</para> + </listitem> + </orderedlist> + + <para>This is the correct order and the packaging system will now work as + expected.</para> + </section> + + <section id="recipes_require" xreflabel="require"> + <title>Require/include: Reusing recipe contents</title> + + <para>In many packages where you are maintaining multiple versions you'll + often end up with several recipes which are either identical, or have only + minor differences between them.</para> + + <para>The require and/or include directive can be used to include common + content from one file into other. You should always look for a way to + factor out common functionality into an include file when adding new + versions of a recipe.</para> + + <note> + <para>Both require and include perform the same function - including the + contents of another file into this recipe. The difference is that + require will generate an error if the file is not found while include + will not. For this reason include should not be used in new + recipes.</para> + </note> + + <para>For example the clamav recipe looks like this:<screen>require clamav.inc + +PR = "r0"</screen>Note that all of the functionality of the recipe is provided + in the clamav.inc file, only the release number is defined in the recipe. + Each of the recipes includes the same <emphasis + role="bold">clamav.inc</emphasis> file to save having to duplicate any + functionality. This also means that as new versions are released it's a + simple matter of copying the recipe and resetting the release number back + to zero.</para> + + <para>The following example from iproute2 shows the recipe adding + additional patches that are not specified by the common included file. + These are patches only needed for newer release and by only adding them in + this recipe it permits the common code to be used for both old and new + recipes:<screen>PR = "r1" + +SRC_URI += "file://iproute2-2.6.15_no_strip.diff;patch=1;pnum=0 \ + file://new-flex-fix.patch;patch=1" + +require iproute2.inc + +DATE = "060323"</screen></para> + + <para>The following example from cherokee shows a similar method of + including additional patches for this version only. However it also show + another technique in which the configure task is defined in the recipe for + this version, thus replacing the <emphasis>configure</emphasis> task that + is provided by the common include:<screen>PR = "r7" + +SRC_URI_append = "file://configure.patch;patch=1 \ + file://Makefile.in.patch;patch=1 \ + file://Makefile.cget.patch;patch=1 \ + file://util.patch;patch=1" + +require cherokee.inc + +do_configure() { + gnu-configize + oe_runconf + sed -i 's:-L\$:-L${STAGING_LIBDIR} -L\$:' ${S}/*libtool +}</screen></para> + </section> + + <section id="recipes_advanced_python" xreflabel="advanced python"> + <title>Python: Advanced functionality with python</title> + + <para>Recipes permit the use of python code in order to perform complex + operations which are not possible with the normal recipe syntax and + variables. Python can be used in both variable assignments and in the + implementation of tasks.</para> + + <para>For variable assignments python code is indicated via the use of + <emphasis>${@...}</emphasis>, as shown in the following example:<screen>TAG = ${@bb.data.getVar('PV',d,1).replace('.', '_')}</screen></para> + + <para>The above example retrieves the PV variable from the bitbake data + object, the replaces any dots with underscores. Therefore if the <emphasis + role="bold">PV</emphasis> was <emphasis role="bold">0.9.0</emphasis> then + <emphasis role="bold">TAG</emphasis> will be set to <emphasis + role="bold">0-9-0</emphasis>.</para> + + <para>Some of the more common python code in use in existing recipes is + shown in the following table:</para> + + <variablelist> + <varlistentry> + <term>bb.data.getVar(<var>,d,1)</term> + + <listitem> + <para>Retrieve the data for the specified variable from the bitbake + database for the current recipe.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><variable>.replace(<key>, + <replacement>)</term> + + <listitem> + <para>Find each instance of the key and replace it with the + replacement value. This can also be used to remove part of a string + by specifying <emphasis role="bold">''</emphasis> (two single + quotes) as the replacement.</para> + + <para>The following example would remove the <emphasis + role="bold">'-frename-registers'</emphasis> option from the + <emphasis role="bold">CFLAGS</emphasis> variable:<screen>CFLAGS := "${@'${CFLAGS}'.replace('-frename-registers', '')}"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>os.path.dirname(<filename>)</term> + + <listitem> + <para>Return the directory only part of a filename.</para> + + <para>This is most commonly seen in existing recipes when settings + the <emphasis role="bold">FILESDIR</emphasis> variable (as described + in the <xref linkend="recipes_filespath_dir" /> section). By + obtaining name of the recipe file itself, <emphasis + role="bold">FILE</emphasis>, and then using os.path.dirname to strip + the filename part:<screen>FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/make-${PV}"</screen>Note + however that this is no longer required as <emphasis + role="bold">FILE_DIRNAME</emphasis> is automatically set to the + dirname of the <emphasis role="bold">FILE</emphasis> variable and + therefore this would be written in new recipes as:<screen>FILESDIR = "$FILE_DIRNAME/make-${PV}"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term><variable>.split(<key>)[<index>]</term> + + <listitem> + <para>Splits are variable around the specified key. Use <emphasis + role="bold">[<index>]</emphasis> to select one of the matching + items from the array generated by the split command.</para> + + <para>The following example from the recipe g<emphasis + role="bold">enext2fs_1.3+1.4rc1.bb</emphasis> would take the + <emphasis role="bold">PV</emphasis> of <emphasis + role="bold">1.3+1.4rc1</emphasis> and split it around the <emphasis + role="bold">+</emphasis> sign, resulting in an array containing + <emphasis role="bold">1.3</emphasis> and <emphasis + role="bold">1.4rc1</emphasis>. It then uses the index of <emphasis + role="bold">[1]</emphasis> to select the second item from the list + (the first item is at index <emphasis role="bold">0</emphasis>). + Therefore <emphasis role="bold">TRIMMEDV</emphasis> would be set to + <emphasis role="bold">1.4rc1</emphasis> for this recipe:</para> + + <screen>TRIMMEDV = "${@bb.data.getVar('PV', d, 1).split('+')[1]}"</screen> + </listitem> + </varlistentry> + </variablelist> + + <para>As well as directly calling built-in python functions, those + functions defined by the existing classes may also be called. A set of + common functions is provided by the base class in <emphasis + role="bold">classes/base.bbclass</emphasis>:</para> + + <variablelist> + <varlistentry> + <term>base_conditional</term> + + <listitem> + <para>This functions is used to set a variable to one of two values + based on the definition of a third variable. The general usage + is:<screen>${@base_conditional('<variable-name>', '<value>', '<true-result>', <false-result>', d)}"</screen>where:</para> + + <variablelist> + <varlistentry> + <term>variable-name</term> + + <listitem> + <para>This is the name of a variable to check.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>value</term> + + <listitem> + <para>This is the value to compare the variable + against.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>true-result</term> + + <listitem> + <para>If the variable equals the value then this is what is + returned by the function.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>false-result</term> + + <listitem> + <para>If the variable does not equal the value then this is + what is returned by the function.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>The following example from the openssl recipe shows the + addition of either <emphasis role="bold">-DL_ENDING</emphasis> or + <emphasis role="bold">-DB_ENDIAN</emphasis> depending on the value + of <emphasis role="bold">SITEINFO_ENDIANESS</emphasis> which is set + to le for little endian targets and to be for big endian + targets:<screen>do_compile () { + ... + # Additional flag based on target endiness (see siteinfo.bbclass) + CFLAG="${CFLAG} ${@base_conditional('SITEINFO_ENDIANESS', 'le', '-DL_ENDIAN', '-DB_ENDIAN', d)}" + ...</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>base_contains</term> + + <listitem> + <para>Similar to base_conditional expect that it is checking for the + value being an element of an array. The general usage is:<screen>${@base_contains('<array-name>', '<value>', '<true-result>', <false-result>', d)}"</screen></para> + + <para>where:<variablelist> + <varlistentry> + <term>array-name</term> + + <listitem> + <para>This is the name of the array to search.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>value</term> + + <listitem> + <para>This is the value to check for in the array.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>true-result</term> + + <listitem> + <para>If the value is found in the array then this is what + is returned by the function.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>false-result</term> + + <listitem> + <para>If the value is not found in the array then this is + what is returned by the function.</para> + </listitem> + </varlistentry> + </variablelist>The following example from the task-angstrom-x11 + recipe shows base_contains being used to add a recipe to the runtime + dependency list but only for machines which have a + touchscreen:</para> + + <screen>RDEPENDS_angstrom-gpe-task-base := "\ + ... + ${@base_contains("MACHINE_FEATURES", "touchscreen", "libgtkstylus", "",d)} \ + ...</screen> + </listitem> + </varlistentry> + </variablelist> + + <para>Tasks may be implemented in python by prefixing the task function + with "python ". In general this should not be needed and should be avoided + where possible. The following example from the devshell recipe shows how + the compile task is implemented python:<screen>python do_compile() { + import os + import os.path + + workdir = bb.data.getVar('WORKDIR', d, 1) + shellfile = os.path.join(workdir, bb.data.expand("${TARGET_PREFIX}${DISTRO}-${MACHINE}-devshell", d)) + + f = open(shellfile, "w") + + # emit variables and shell functions + devshell_emit_env(f, d, False, ["die", "oe", "autotools_do_configure"]) + + f.close() +}</screen></para> + </section> + + <section id="recipes_defaultpreference" xreflabel="default preference"> + <title>Preferences: How to disable packages</title> + + <para>When bitbake is asked to build a package and multiple versions of + that package are available then bitbake will normally select the version + that has the highest version number (where the version number is defined + via the <command>PV</command> variable).</para> + + <para>For example if we were to ask bitbake to build procps and the + following packages are available:<screen>~/oe%> ls packages/procps +procps-3.1.15/ procps-3.2.1/ procps-3.2.5/ procps-3.2.7/ procps.inc +procps_3.1.15.bb procps_3.2.1.bb procps_3.2.5.bb procps_3.2.7.bb +~/oe%></screen>then we would expect it to select version + <command>3.2.7</command> (the highest version number) to build.</para> + + <para>Sometimes this is not actually what you want to happen though. + Perhaps you have added a new version of the package that does not yet work + or maybe the new version has no support for your target yet. Help is at + hand since bitbake is not only looking at the version numbers to decided + which version to build but it is also looking at the preference for each + of those version. The preference is defined via the + <command>DEFAULT_PREFERENCE</command> variable contained within the + recipe.</para> + + <para>The default preference (when no + <command>DEFAULT_PREFERENCE</command> is specified) is zero. Bitbake will + find the highest preference that is available and then for all the + packages at the preference level it will select the package with the + highest version. In general this means that adding a positive + <command>DEFAULT_PREFERENCE</command> will cause the package to be + preferred over other versions and a negative + <command>DEFAULT_PREFERENCE</command> will cause all other packages to be + preferred.</para> + + <para>Imagine that you are adding procps version 4.0.0, but that it does + not yet work. You could delete or rename your new recipe so you can build + a working image, but what you really to do is just ignore the new 4.0.0 + version until it works. By adding:<screen>DEFAULT_PREFERENCE = "-1"</screen>to + the recipe this is what will happen. Bitbake will now ignore this version + (since all of the existing versions have a preference of 0). Note that you + can still call bitbake directly on the recipe:<screen>bitbake -b packages/procps/procps_4.0.0.bb</screen>This + enables you to test, and fix the package manually without having bitbake + automatically select normally.</para> + + <para>By using this feature in conjunction with overrides you can also + disable (or select) specific versions based on the override. The following + example from glibc shows that this version has been disabled for the sh3 + architecture because it doesn't support sh3. This will force bitbake to + try and select one of the other available versions of glibc + instead:<screen>packages/glibc/glibc_2.3.2+cvs20040726.bb:DEFAULT_PREFERENCE_sh3 = "-99"</screen></para> + </section> + + <section id="recipes_initscripts" xreflabel="initscripts"> + <title>Initscripts: How to handle daemons</title> + + <para>This section is to be completed.</para> + + <itemizedlist> + <listitem> + <para>update-rc.d class</para> + </listitem> + + <listitem> + <para>sh syntax</para> + </listitem> + + <listitem> + <para>stop/stop/restart params</para> + </listitem> + + <listitem> + <para>samlpe/standard script?</para> + </listitem> + + <listitem> + <para>volatiles</para> + </listitem> + </itemizedlist> + </section> + + <section id="recipes_alternatives" xreflabel="alternatives"> + <title>Alternatives: How to handle the same command in multiple + packages</title> + + <para>Alternatives are used when the same command is provided by multiple + packages. A classic example is busybox, which provides a whole set of + commands such as <emphasis role="bold">/bin/ls</emphasis> and <emphasis + role="bold">/bin/find</emphasis>, which are also provided by other + packages such as coreutils (<emphasis role="bold">/bin/ls</emphasis>) and + findutils (<emphasis role="bold">/bin/find</emphasis>).</para> + + <para>A system for handling alternatives is required to allow the user to + choose which version of the command they wish to have installed. It should + be possible to install either one, or both, or remove one when both are + installed etc, and to have no issues with the packages overwriting files + from other packages.</para> + + <para>The most common reason for alternatives is to reduce the size of the + binaries. But cutting down on features, built in help and error messages + and combining multiple binaries into one large binary it's possible to + save considerable space. Often users are not expected to use the commands + interactively in embedded appliances and therefore these changes have no + visible effect to the user. In some situations users may have interactive + access, or they may be more advanced users who want shell access on + appliances that normal don't provide it, and in these cases they should be + able to install the full functional version if they desire.</para> + + <section> + <title>Example of alternative commands</title> + + <para>Most distributions include busybox in place of the full featured + version of the commands. The following example shows a typical install + in which the find command, which we'll use as an example here, is the + busybox version:<screen>root@titan:~$ find --version +find --version +BusyBox v1.2.1 (2006.12.17-05:10+0000) multi-call binary + +Usage: find [PATH...] [EXPRESSION] + +root@titan:~$ which find +which find +/usr/bin/find</screen>If we now install the full version of find:<screen>root@titan:~$ ipkg install findutils +ipkg install findutils +Installing findutils (4.2.29-r0) to root... +Downloading http://nynaeve.twibble.org/ipkg-titan-glibc//./findutils_4.2.29-r0_sh4.ipk +Configuring findutils + +update-alternatives: Linking //usr/bin/find to find.findutils +update-alternatives: Linking //usr/bin/xargs to xargs.findutils</screen></para> + + <para>Then we see that the standard version of find changes to the full + featured implement ion:<screen>root@titan:~$ find --version +find --version +GNU find version 4.2.29 +Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION +root@titan:~$ which find +which find +/usr/bin/find</screen></para> + </section> + + <section> + <title>Using update-alternatives</title> + + <para>Two methods of using the alternatives system are available:</para> + + <orderedlist> + <listitem> + <para>Via the <xref linkend="update-alternatives_class" />. This is + the simplest method, but is not usable in all situations.</para> + </listitem> + + <listitem> + <para>Via directly calling the update-alternatives command.</para> + </listitem> + </orderedlist> + + <para>The <xref linkend="update-alternatives_class" /> is the provides + the simplest method of using alternatives but it only works for a single + alternative. For multiple alternatives they need to be manually + registered during post install.</para> + + <para>Full details on both methods is provided in the <xref + linkend="update-alternatives_class" /> section of the reference + manual.</para> + </section> + </section> + + <section id="recipes_volatiles" xreflabel="volatiles"> + <title>Volatiles: How to handle the /var directory</title> + + <para>The <emphasis role="bold">/var</emphasis> directory is for storing + volatile information, that is information which is constantly changing and + which in general may be easily recreated. In embedded applications it is + often desirable that such files are not stored on disk or flash for + various reasons including:</para> + + <itemizedlist> + <listitem> + <para>The possibility of a reduced lifetime of the flash;</para> + </listitem> + + <listitem> + <para>The limited amount of storage space available;</para> + </listitem> + + <listitem> + <para>To ensure filesystem corruption cannot occur due to a sudden + power loss.</para> + </listitem> + </itemizedlist> + + <para>For these reasons many of the OpenEmbedded distributions use a tmpfs + based memory filesystem for <emphasis role="bold">/var</emphasis> instead + of using a disk or flash based filesystem. The consequence of this is that + all contents of the <emphasis role="bold">/var</emphasis> directory is + lost when the device is powered off or restarted. Therefore special + handling of <emphasis role="bold">/var</emphasis> is required in all + packages. Even if your distrubution does not use a tmpfs based <emphasis + role="bold">/var</emphasis> you need to assume it does when creating + packages to ensure the package can be used on those distributions that do + use a tmpfs based <emphasis role="bold">/var</emphasis>. This special + handling is provided via the <emphasis + role="bold">populate-volatiles.sh</emphasis> script.</para> + + <note> + <para>If your package requires any files, directories or symlinks in + <emphasis role="bold">/var</emphasis> then it should be using the + populate-volatiles facilities.</para> + </note> + + <section> + <title>Declaring volatiles</title> + + <para>This section is to be completed.</para> + + <itemizedlist> + <listitem> + <para>how volatiles work</para> + </listitem> + + <listitem> + <para>default volatiles</para> + </listitem> + + <listitem> + <para>don't include any /var stuff in packages</para> + </listitem> + + <listitem> + <para>even if your distro don't use /var in tmpfs, others do</para> + </listitem> + + <listitem> + <para>updating the volatiles cache during install</para> + </listitem> + </itemizedlist> + </section> + + <section> + <title>Logging and log files</title> + + <para>As a consequence of the non-volatile and/or small capacity of the + <emphasis role="bold">/var</emphasis> file system some distributions + choose methods of logging other than writing to a file. The most typical + is the use of an in-memory circular log buffer which can be read using + the <emphasis role="bold">logread</emphasis> command.</para> + + <para>To ensure that each distribution is able to implement logging in a + method that is suitable for its goals all packages should be configured + by default to log via syslog, and not log directly to a file, if + possible. If the distribution and/or end-user requires logging to a file + then they can configured syslog and/or your application to implement + this.</para> + </section> + + <section> + <title>Summary</title> + + <para>In summary the following are required when dealing with + <command>/var</command>:</para> + + <itemizedlist> + <listitem> + <para>Configure all logging to use syslog whenever possible. This + leaves the decision on where to log upto the individual + distributions.</para> + </listitem> + + <listitem> + <para>Don't include any <command>/var</command> directories, file or + symlinks in packages. They would be lost on a reboot and so should + not be included in packages.</para> + </listitem> + + <listitem> + <para>The only directories that you can assume exist are those + listed in the default volatiles file: + <command>packages/initscripts/initscripts-1.0/volatiles</command>.</para> + </listitem> + + <listitem> + <para>For any other directories, files or links that are required in + <command>/var</command> you should install your own volatiles list + as part of the package.</para> + </listitem> + </itemizedlist> + </section> + </section> + + <section id="recipes_misc"> + <title>Miscellaneous</title> + + <para>This section is to be completed.</para> + + <itemizedlist> + <listitem> + <para>about optimisation</para> + </listitem> + + <listitem> + <para>about download directories</para> + </listitem> + + <listitem> + <para>about parallel builds</para> + </listitem> + + <listitem> + <para>about determining endianess (aka net-snmp, openssl, hping etc + style)</para> + </listitem> + + <listitem> + <para>about PACKAGES_DYNAMIC</para> + </listitem> + + <listitem> + <para>about LEAD_SONAME</para> + </listitem> + + <listitem> + <para>about "python () {" - looks like it is always run when a recipe + is parsed? see pam/libpam</para> + </listitem> + + <listitem> + <para>about SRCDATE with svn/cvs?</para> + </listitem> + + <listitem> + <para>about INHIBIT_DEFAULT_DEPS?</para> + </listitem> + + <listitem> + <para>about COMPATIBLE_MACHINE and COMPATIBLE_HOST</para> + </listitem> + + <listitem> + <para>about SUID binaries, and the need for postinst to fix them + up</para> + </listitem> + + <listitem> + <para>about passwd and group (some comment in install scripts section + already).</para> + </listitem> + </itemizedlist> + + <para></para> + </section> +</chapter>
\ No newline at end of file diff --git a/docs/usermanual/chapters/usage.xml b/docs/usermanual/chapters/usage.xml new file mode 100644 index 0000000000..9fe20faf8c --- /dev/null +++ b/docs/usermanual/chapters/usage.xml @@ -0,0 +1,1193 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter id="chapter_using_bitbake_and_oe"> + <title>Using bitbake and OpenEmbedded</title> + + <section id="usage_introduction" xreflabel="introduction"> + <title>Introduction</title> + + <para>If your reading this manual you probably already have some idea of + what OpenEmbedded is all about, which is taking a lot of software and + creating something that you can run on another device. This involves + downloading some source code, compiling it, creating packages (like .deb + or .rpm) and/or creating boot images that can written to flash on the + device. The difficulties of cross-compiling and the variety of devices + which can be supported lead to a lot more complexity in an OpenEmbedded + based distribution than you'd find in a typical desktop distribution + (which cross-compiling isn't needed).</para> + + <para>A major part of OpenEmbedded deals with compiling source code for + various projects. For each project this generally requires the same basic + set of tasks:</para> + + <orderedlist> + <listitem> + <para>Download the source code, and any supporting files (such as + initscripts);</para> + </listitem> + + <listitem> + <para>Extract the source code and apply any patches that might be + wanted;</para> + </listitem> + + <listitem> + <para>Configure the software if needed (such as is done by running the + configure script);</para> + </listitem> + + <listitem> + <para>Compile everything;</para> + </listitem> + + <listitem> + <para>Package up all the files into some package format, like .deb or + .rpm or .ipk, ready for installation.</para> + </listitem> + </orderedlist> + + <para>There's nothing particular unusual about this process when building + on the machine the package is to be installed on. What makes this + difficult is:</para> + + <orderedlist> + <listitem> + <para>Cross-compiling: cross-compiling is difficult, and lots of + software has no support for cross-compiling - all packages included in + OE are cross-compiled;</para> + </listitem> + + <listitem> + <para>Target and host are different: This means you can't compile up a + program and then run it - it's compiled to run on the target system, + not on the system compiling it. Lots of software tries to build and + run little helper and/or test applications and this won't work when + cross-compiling.</para> + </listitem> + + <listitem> + <para>Tool chains (compiler, linker etc) are often difficult to + compile. Cross tool chains are even more difficult. Typically you'd go + out and download a tool chain made by someone else - but not when your + using OE. In OE the entire toolchain is built as part of the process. + This may make things take longer initially and may make it more + difficult to get started but makes it easier to apply patches and test + out changes to the tool chain.</para> + </listitem> + </orderedlist> + + <para>Of course there's a lot more to OE then just compiling packages + though. Some of the features that OE supports includes:</para> + + <itemizedlist> + <listitem> + <para>Support for both glibc and uclibc;</para> + </listitem> + + <listitem> + <para>Support for building for multiple target devices from the one + code base;</para> + </listitem> + + <listitem> + <para>Automatically building anything that is required for the package + to compile and/or run (build and run time dependencies);</para> + </listitem> + + <listitem> + <para>Creation of flash and disk images of any one of a number of + types (jffs2, ext2.gz, squashfs etc) for booting directly on the + target device;</para> + </listitem> + + <listitem> + <para>Support for various packaging formats;</para> + </listitem> + + <listitem> + <para>Automatic building all of the cross-compiling tools you'll + need;</para> + </listitem> + + <listitem> + <para>Support for "native" packages that are built for the host + computer and not for the target and used to help during the build + process;</para> + </listitem> + </itemizedlist> + + <para>The rest of this chapter assumes you have mastered the Getting Start + guides to OpenEmbedded (see the OpenEmbedded web site for details), and + therefore have an appropriately configured setup and that you have managed + to actually build the cross-compilers for your target. This section talks + you through some of the background on what is happening with the aim of + helping you understand how to debug and develop within + OpenEmbedded.</para> + + <para>You'll also not a lot of reference to variables that define specific + directories or change the behaviour of some part of the build process. You + should refer to <xref linkend="chapter_recipes" /> for full details on + these variables.</para> + </section> + + <section id="usage_configuration" xreflabel="configuration"> + <title>Configuration</title> + + <para>Configuration covers basic items such as where the various files can + be found and where output should be placed to more specific items such as + which hardware is being targeted and what features you want to have + included in the final image. The main configuration areas in OE + are:</para> + + <variablelist> + <varlistentry> + <term>conf/machine</term> + + <listitem> + <para>This directory contains machine configuration information. For + each physical device a configuration file is required in this + directory that describes various aspects of the device, such as + architecture of the device, hardware features of the device (does it + have usb? a keyboard? etc), the type of flash or disk images needed + for the device, the serial console settings (if any) etc. If you are + adding support for a new device you would need to create a machine + configuration in this directory for the device.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>conf/distro</term> + + <listitem> + <para>This directory contains distribution related files. A + distribution decides how various activities are handled in the final + image, such as how networking configured, if usb devices will be + supported, what packaging system is used, which libc is used + etc.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>conf/bitbake.conf</term> + + <listitem> + <para>This is the main bitbake configuration file. This file is not + to be edited but it is useful to look at it since it declares a + larger number of the predefined variables used by OE and controls a + lot of the base functionality provided by OE.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>conf/local.conf</term> + + <listitem> + <para>This is the end-user specific configuration. This file needs + to be copied and edited and is used to specify the various working + directories, the machine to build for and the distribution to + use.</para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section id="usage_workspace" xreflabel="workspace"> + <title>Work space</title> + + <para>Let's start out by taking a look at a typically working area. Note + that this may not be exactly what see - there are a lot of options that + can effect exactly how things are done, but it gives us a pretty good idea + of whats going on. What we are looking at here is the tmp directory (as + specified by TMPDIR in your local.conf):<screen>~%> find tmp -maxdepth 2 -type d +tmp +tmp/stamps +tmp/cross +tmp/cross/bin +tmp/cross/libexec +tmp/cross/lib +tmp/cross/share +tmp/cross/sh4-linux +tmp/cache +tmp/cache/titan +tmp/work +tmp/work/busybox-1.2.1-r13 +tmp/work/libice-1_1.0.3-r0 +tmp/work/arpwatch-2.1a15-r2 +... +tmp/rootfs +tmp/rootfs/bin +tmp/rootfs/usr +tmp/rootfs/media +tmp/rootfs/dev +tmp/rootfs/var +tmp/rootfs/lib +tmp/rootfs/sbin +tmp/rootfs/mnt +tmp/rootfs/boot +tmp/rootfs/sys +tmp/rootfs/proc +tmp/rootfs/etc +tmp/rootfs/home +tmp/rootfs/tmp +tmp/staging +tmp/staging/man +tmp/staging/x86_64-linux +tmp/staging/pkgdata +tmp/staging/pkgmaps +tmp/staging/var +tmp/staging/sh4-linux +tmp/staging/local +tmp/staging/etc +tmp/deploy +tmp/deploy/addons +tmp/deploy/ipk +tmp/deploy/sources +tmp/deploy/images</screen></para> + + <para>The various top level directories under tmp include:</para> + + <variablelist> + <varlistentry> + <term>stamps</term> + + <listitem> + <para>Nothing of interest to users in here. These time stamps are + used by bitbake to keep track of what tasks it has completed and + what tasks it still has outstanding. This is how it knows that + certain actions have been completed and it doesn't need to do them + again.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>cross</term> + + <listitem> + <para>Contains the cross-compiler toolchain. That is the gcc and + binutils that run on the host system but produce output for the + target system.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>cache</term> + + <listitem> + <para>Nothing of interest to users in here. This contains the + bitbake parse cache and is used to avoid the need to parse all of + the recipes each time bitbake is run. This makes bitbake a lot + faster on the 2nd and subsequent runs.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>work</term> + + <listitem> + <para>The work directory. This is the directory in which all + packages are built - this is where the source code is extract, + patches applied, software configure, compiled, installed and + package. This is where you'll spend most of you time looking when + working in OE.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>rootfs</term> + + <listitem> + <para>The generated root filesystem image for your target device. + This is the contents of the root filesystem (NOTE: fakeroot means it + doesn't have the correct device special nodes and permissions to use + directly).</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>staging</term> + + <listitem> + <para>Contains the staging area, which is used to stored natively + compiled tools and and libraries and headers for the target that are + required for building other software.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>deploy</term> + + <listitem> + <para>Contains the final output from OE. This includes the + installation packages (typically .ipkg packages) and flash and/or + disk images. This is where you go to get the final product.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>When people refer to the <emphasis>"tmp directory"</emphasis> this + is the directory them are talking about.</para> + + <para>To perform a complete rebuild from script you would usually rename + or delete tmp and then restart your build. I recommend keeping one old + version of tmp around to use for comparison if something goes wrong with + your new build. For example:<screen>%> rm -fr tmp.OLD +$> mv tmp tmp.OLD +%> bitbake bootstrap-image</screen></para> + + <section id="usage_workdir" xreflabel="work directory"> + <title>work directory (tmp/work)</title> + + <para>The work directory is where all source code is unpacked into, + where source is configured, compiled and packaged. In other words this + is where all the action happens. Each bitbake recipe will produce a + corresponding sub directory in the work directory. The sub directory + name will contain the recipe name, version and the release number (as + defined by the PR variable within the recipe).</para> + + <para>Here's an example of a few of the subdirectories under the work + directory:<screen>~%> find tmp/work -maxdepth 1 -type d | head -4 +tmp/work +tmp/work/busybox-1.2.1-r13 +tmp/work/libice-1_1.0.3-r0 +tmp/work/arpwatch-2.1a15-r2</screen>You can see that the first three (of + several hundred) recipes here and they are for release 13 of busybox + 1.2.1, release 0 or libice 1.1.0.3 and release 2 of arpwatch 2.1a15. + It's also possible that you may just have a sub directory for your + targets architecture and operating system in which case these + directories will be in that additional subdirectory, as shown + here:<screen>~%> find tmp/work -maxdepth 2 -type d | head -4 +tmp/work +tmp/work/sh4-linux +tmp/work/sh4-linux/busybox-1.2.1-r13 +tmp/work/sh4-linux/libice-1_1.0.3-r0 +tmp/work/sh4-linux/arpwatch-2.1a15-r2</screen></para> + + <para>The <emphasis role="bold">sh4-linux</emphasis> directory in the + above example is a combination of the target architecture (sh4) and + operating system (linux). This subdirectory has been added by the use of + one of OpenEmbedded's many features. In this case it's the + <emphasis>multimachine</emphasis> feature which is used to allow builds + for multiple targets within the one work directory and can be enabled on + a per distribution basis. This feature enables the sharing of native and + architecture neutral packages and building for multiple targets that + support the same architecture but require different linux kernels (for + example). We'll assume multimachine isn't being used for the rest of + this chapter, just remember to add the extra directory if your + distribution is using it.</para> + + <para>Using lzo 1.08 as an example we'll examine the contents of the + working directory for a typical recipe:<screen>~%> find tmp/work/lzo-1.08-r14 -maxdepth 1 +tmp/work/lzo-1.08-r14 +tmp/work/lzo-1.08-r14/temp +tmp/work/lzo-1.08-r14/lzo-1.08 +tmp/work/lzo-1.08-r14/install +tmp/work/lzo-1.08-r14/image</screen></para> + + <para>The directory, <emphasis + role="bold">tmp/work/lzo-1.08-r14</emphasis>, is know as the + <emphasis>"working directory"</emphasis> for the recipe and is specified + via the <emphasis role="bold">WORKDIR</emphasis> variable in bitbake. + You'll sometimes see recipes refer directly to <emphasis + role="bold">WORKDIR</emphasis> and this is the directory they are + referencing. The <emphasis role="bold">1.08</emphasis> is the version of + lzo and <emphasis role="bold">r14</emphasis> is the release number, as + defined by the <emphasis role="bold">PR</emphasis> variable within the + recipe.</para> + + <para>Under the working directory (<emphasis + role="bold">WORKDIR</emphasis>) there are four subdirectories:</para> + + <variablelist> + <varlistentry> + <term>temp</term> + + <listitem> + <para>The temp directories contains logs and in some cases scripts + that actually implement specific tasks (such as a script to + configure or compile the source).</para> + + <para>You can look at the logs in this directory to get more + information into what happened (or didn't happen). This is usually + the first thing to look at when things are going wrong and these + usually need to be included when reporting bugs.</para> + + <para>The scripts can be used to see what a particular task, such + as configure or compile, is trying to do.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>lzo-1.08</term> + + <listitem> + <para>This is the unpacked source code directory, which was + created when the lzo source code was extracted in this directory. + The name and format of this directory is therefore dependent on + the actual source code packaging. Within recipes this directory is + referred to as <emphasis role="bold">S</emphasis> and is usually + expected to be named like this, that is + <emphasis>"<name>-<version>"</emphasis>. If the source + code extracts to somewhere else then that would need to be + declared in the recipe by explicitly setting the value of the + variable <emphasis role="bold">S</emphasis> to the appropriate + directory.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>image</term> + + <listitem> + <para>The image directory (or destination directory) is where the + software needs to be installed into in order to be packaged. This + directory is referred to as <emphasis role="bold">D</emphasis> in + recipes. So instead of installing binaries into <emphasis + role="bold">/usr/bin</emphasis> and libraries into <emphasis + role="bold">/usr/lib</emphasis> for example you would need to + install into <emphasis role="bold">${D}/usr/bin</emphasis> and + <emphasis role="bold">${D}/usr/lib</emphasis> instead. When + installed on the target the ${D} will be not be included so + they'll end up in the correct place. You definitely don't wont + files on your host system being replaced by cross-compiled + binaries for your target!</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>install</term> + + <listitem> + <para>The install directory is used to split the installed files + into separate packages. One subdirectory is created per package to + be generated and the files are moved from the image directory + (<emphasis role="bold">D</emphasis>) over to this directory, and + into the appropriate package subdirectory, as each packaging + instruction is processed. Typically there will be separate + documentation (<emphasis>-doc</emphasis>), debugging + (<emphasis>-dbg</emphasis>) and development + (<emphasis>-dev</emphasis>) packages automatically created. There + are variables such as <emphasis role="bold">FILES_</emphasis> and + <emphasis role="bold">PACKAGES</emphasis> used in recipes which + control the separation of various files into individual + packages.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>So lets show some examples of the useful information you now have + access to.</para> + + <para>How about checking out what happened during the configuration of + lzo? Well that requires checking the log file for configure that is + generated in the temp directory:<screen>~%> less tmp/work/lzo-1.08-r14/temp/log.do_configure.* +... +checking whether ccache sh4-linux-gcc -ml -m4 suffers the -fschedule-insns bug... unknown +checking whether ccache sh4-linux-gcc -ml -m4 suffers the -fstrength-reduce bug... unknown +checking whether ccache sh4-linux-gcc -ml -m4 accepts -fstrict-aliasing... yes +checking the alignment of the assembler... 0 +checking whether to build assembler versions... no +configure: creating ./config.status +config.status: creating Makefile +config.status: creating examples/Makefile +config.status: creating include/Makefile +config.status: creating ltest/Makefile +config.status: creating minilzo/Makefile +config.status: creating src/Makefile +config.status: creating tests/Makefile +config.status: creating config.h +config.status: executing depfiles commands</screen></para> + + <para>Or perhaps you want to see how the files were distributed into + individual packages prior to packaging? The install directory is where + the files are split into separate packages and so that shows us which + files end up where:<screen>~%> find tmp/work/lzo-1.08-r14/install +tmp/work/lzo-1.08-r14/install +tmp/work/lzo-1.08-r14/install/lzo-doc +tmp/work/lzo-1.08-r14/install/lzo-dbg +tmp/work/lzo-1.08-r14/install/lzo-dbg/usr +tmp/work/lzo-1.08-r14/install/lzo-dbg/usr/lib +tmp/work/lzo-1.08-r14/install/lzo-dbg/usr/lib/.debug +tmp/work/lzo-1.08-r14/install/lzo-dbg/usr/lib/.debug/liblzo.so.1.0.0 +tmp/work/lzo-1.08-r14/install/lzo-dev +tmp/work/lzo-1.08-r14/install/lzo-dev/usr +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo2a.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo1y.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo1.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo1b.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo1f.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzoconf.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo1x.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo16bit.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo1a.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo1z.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzoutil.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/include/lzo1c.h +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/lib +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/lib/liblzo.a +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/lib/liblzo.so +tmp/work/lzo-1.08-r14/install/lzo-dev/usr/lib/liblzo.la +tmp/work/lzo-1.08-r14/install/lzo.shlibdeps +tmp/work/lzo-1.08-r14/install/lzo-locale +tmp/work/lzo-1.08-r14/install/lzo +tmp/work/lzo-1.08-r14/install/lzo/usr +tmp/work/lzo-1.08-r14/install/lzo/usr/lib +tmp/work/lzo-1.08-r14/install/lzo/usr/lib/liblzo.so.1 +tmp/work/lzo-1.08-r14/install/lzo/usr/lib/liblzo.so.1.0.0</screen></para> + </section> + </section> + + <section id="usage_tasks" xreflabel="tasks"> + <title>Tasks</title> + + <para>When you go about building and installing a software package there + are a number of tasks that you generally follow with most software + packages. You probably need to start out by downloading the source code, + then unpacking the source code. Maye you need to apply some patches for + some reason. Then you might run the configure script of the package, + perhaps passing it some options to configure it to your liking. The you + might run "make install" to install the software. If your actually going + to make some packages, such as .deb or .rpm, then you'd have additional + tasks you'd perform to make them.</para> + + <para>You find that building things in OpenEmbedded works in a similar way + - there are a number of tasks that are executed in a predefined order for + each recipe. Any many of the tasks correspond to those listed above like + <emphasis>"download the source"</emphasis>. In fact you've probably + already seen some of the names of these tasks - bitbake displays them as + they are processed:<screen>~%> bitbake lzo +NOTE: Psyco JIT Compiler (http://psyco.sf.net) not available. Install it to increase performance. +NOTE: Handling BitBake files: \ (4541/4541) [100 %] +NOTE: Parsing finished. 4325 cached, 0 parsed, 216 skipped, 0 masked. +NOTE: build 200705041709: started + +OE Build Configuration: +BB_VERSION = "1.8.2" +OE_REVISION = "<unknown>" +TARGET_ARCH = "sh4" +TARGET_OS = "linux" +MACHINE = "titan" +DISTRO = "erouter" +DISTRO_VERSION = "0.1-20070504" +TARGET_FPU = "" + +NOTE: Resolving missing task queue dependencies +NOTE: preferred version 2.5 of glibc not available (for item virtual/sh4-linux-libc-for-gcc) +NOTE: Preparing Runqueue +NOTE: Executing runqueue +NOTE: Running task 208 of 226 (ID: 11, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, <emphasis + role="bold">do_fetch</emphasis>) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_fetch</emphasis>: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_fetch</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 209 of 226 (ID: 2, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, <emphasis + role="bold">do_unpack</emphasis>) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_unpack</emphasis>: started +NOTE: Unpacking /home/lenehan/devel/oe/sources/lzo-1.08.tar.gz to /home/lenehan/devel/oe/build/titan-glibc-25/tmp/work/lzo-1.08-r14/ +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_unpack</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 216 of 226 (ID: 3, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, <emphasis + role="bold">do_patch</emphasis>) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_patch</emphasis>: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_patch</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 217 of 226 (ID: 4, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, <emphasis + role="bold">do_configure</emphasis>) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_configure</emphasis>: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_configure</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 218 of 226 (ID: 12, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, <emphasis + role="bold">do_qa_configure</emphasis>) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_qa_configure</emphasis>: started +NOTE: Checking sanity of the config.log file +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_qa_configure</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 219 of 226 (ID: 0, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, <emphasis + role="bold">do_compile</emphasis>) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_compile</emphasis>: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_compile</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 220 of 226 (ID: 1, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, <emphasis + role="bold">do_install</emphasis>) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_install</emphasis>: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_install</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 221 of 226 (ID: 5, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, <emphasis + role="bold">do_package</emphasis>) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_package</emphasis>: started +NOTE: DO PACKAGE QA +NOTE: Checking Package: lzo-dbg +NOTE: Checking Package: lzo +NOTE: Checking Package: lzo-doc +NOTE: Checking Package: lzo-dev +NOTE: Checking Package: lzo-locale +NOTE: DONE with PACKAGE QA +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_package</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 222 of 226 (ID: 8, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, <emphasis + role="bold">do_package_write</emphasis>) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_package_write</emphasis>: started +Packaged contents of lzo-dbg into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/liblzo-dbg_1.08-r14_sh4.ipk +Packaged contents of lzo into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/liblzo1_1.08-r14_sh4.ipk +NOTE: Not creating empty archive for lzo-doc-1.08-r14 +Packaged contents of lzo-dev into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/liblzo-dev_1.08-r14_sh4.ipk +NOTE: Not creating empty archive for lzo-locale-1.08-r14 +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_package_write</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 223 of 226 (ID: 6, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, do_populate_staging) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_populate_staging</emphasis>: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_populate_staging</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 224 of 226 (ID: 9, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, do_qa_staging) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_qa_staging</emphasis>: started +NOTE: QA checking staging +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_qa_staging</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 225 of 226 (ID: 7, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, do_distribute_sources) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_distribute_sources</emphasis>: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_distribute_sources</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Running task 226 of 226 (ID: 10, /home/lenehan/devel/oe/build/titan-glibc-25/packages/lzo/lzo_1.08.bb, do_build) +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_build</emphasis>: started +NOTE: package lzo-1.08-r14: task <emphasis role="bold">do_build</emphasis>: completed +NOTE: package lzo-1.08: completed +NOTE: Tasks Summary: Attempted 226 tasks of which 213 didn't need to be rerun and 0 failed. +NOTE: build 200705041709: completed</screen><note> + <para>The output may look different depending on the version of + bitbake being used, and some tasks are only run when specific options + are enabled in your distribution. The important point to note is that + the various tasks are being run and bitbake shows you each time it + starts and completes a task.</para> + </note></para> + + <para>So there's a set of tasks here which are being run to generate the + final packages. And if you'll notice that every recipe runs through the + same set of tasks (ok I'll admit that it is possible that some additional + tasks could be run for some recipes, but we'll talk about that later). The + tasks that you'll need to be most familiar with are:</para> + + <variablelist> + <varlistentry> + <term>fetch</term> + + <listitem> + <para>The <emphasis>fetch</emphasis> task is responsible for + fetching any source code that is required. This means things such as + downloading files and checking out from source control repositories + such as git or svn.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>unpack</term> + + <listitem> + <para>The <emphasis>unpack</emphasis> task is responsible for + extracting files from archives, such as <emphasis + role="bold">.tar.gz</emphasis>, into the working area and copying + any additional files, such as init scripts, into the working + area.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>patch</term> + + <listitem> + <para>The <emphasis>patch</emphasis> task is responsible for + applying any patches to the unpacked source code</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>configure</term> + + <listitem> + <para>The <emphasis>configure</emphasis> task takes care of the + configuration of the package. Running a configure script + (<emphasis>"./configure <options>"</emphasis>) is probably the + form of configuration that is most recognised but it's not the only + configuration system that exists.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>compile</term> + + <listitem> + <para>The <emphasis>compile</emphasis> task actually compiles the + software. This could be as simple as running <emphasis + role="bold">make</emphasis>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>populate_staging (stage)</term> + + <listitem> + <para>The <emphasis>populate_staging</emphasis> task (stage is an + alternate, easier to type name, that can be used to refer to this + task) is responsible for making available libraries and headers (if + any) that may be required by other packages to build. For example if + you compile zlib then it's headers and the library need to be made + available for other applications to include and link against.</para> + + <note> + <para>This is different to the <emphasis>install</emphasis> task + in that this is responsible for making available libraries and + headers for use during build on the development host. Therefore + it's libraries which normal have to stage things while + applications normally don't need to. The + <emphasis>install</emphasis> task on the other hand is making + files available for packaging and ultimately installation on the + target.</para> + </note> + </listitem> + </varlistentry> + + <varlistentry> + <term>install</term> + + <listitem> + <para>The <emphasis>install</emphasis> task is responsible for + actually installing everything. Now this needs to install the + software into the destination directory, <emphasis + role="bold">D</emphasis>. This directory won't actually be a part of + the final package though. In other words if you install something + into <emphasis role="bold">${D}/bin</emphasis> then it will end up + in the <emphasis role="bold">/bin</emphasis> directory in the + package and therefore on the target.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>package</term> + + <listitem> + <para>The <emphasis>package</emphasis> task takes the installed + files and splits them into separate directories under the <emphasis + role="bold">${WORKDIR}/install</emphasis> directory, one per + package. It moves the files for the destination directory, <emphasis + role="bold">${D}</emphasis>, that they were installed in into the + appropriate packages subdirectory. Usually there will be a main + package a separate documentation (-doc), development (-dev) and + debugging packages (-dbg) for example.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>package_write</term> + + <listitem> + <para>The <emphasis>package_write</emphasis> task is responsible for + taking each packages subdirectory and creating any actual + installation package, such as .ipk, .deb or .rpm. Currently .ipk is + the only fully supported packing format although .deb packages are + being actively worked on. It should be reasonably easy for an + experienced OpenEmbedded developer to add support for any other + packaging formats they might required.</para> + </listitem> + </varlistentry> + </variablelist> + + <note> + <para>You'll notice that the bitbake output had tasks prefixed with + <emphasis>do_</emphasis>, as in <emphasis>do_install</emphasis> vs + <emphasis>install</emphasis>. This is slightly confusing but any task + <emphasis>x</emphasis> is implemented via a function called + <emphasis>do_x</emphasis> in the class or recipe where it is defined. + See places refer to the tasks via their name only and some with the + <emphasis>do</emphasis> prefix.</para> + </note> + + <para>You will almost certainly notice tasks beyond these ones - there are + various methods available to insert additional tasks into the tasks + sequence. As an example the <emphasis + role="bold">insane.bbclass</emphasis>, which performs various QA checks, + does these checks by inserting a new task called + <emphasis>qa_configure</emphasis> between the + <emphasis>configure</emphasis> and <emphasis>compile</emphasis> tasks and + another new task called <emphasis>qa_staging</emphasis> between + <emphasis>populate_staging</emphasis> and <emphasis>build</emphasis> + tasks. The former validates the result of the + <emphasis>configure</emphasis> task and the late the results of the + <emphasis>populate_staging</emphasis> task.</para> + + <para>To determine the full list of tasks available for a specific recipe + you can run bitbake on the recipe and asking it for the full list of + available tasks:<screen>~%> bitbake -b packages/perl/perl_5.8.8.bb -c listtasks +NOTE: package perl-5.8.8: started +NOTE: package perl-5.8.8-r11: task do_listtasks: started +do_fetchall +do_listtasks +do_rebuild +do_compile +do_build +do_populate_staging +do_mrproper +do_fetch +do_configure +do_clean +do_package +do_unpack +do_install +do_package_write +do_distribute_sources +do_showdata +do_qa_configure +do_qa_staging +do_patch +NOTE: package perl-5.8.8-r11: task do_listtasks: completed +NOTE: package perl-5.8.8: completed +~%> </screen></para> + + <para>If your being observant you'll note that + <emphasis>listtasks</emphasis> is in fact a task itself, and that the + <emphasis role="bold">-c</emphasis> option to bitbake allows you to + explicitly run specific tasks. We'll make use of this in the next section + when we discuss working with a recipe.</para> + </section> + + <section id="usage_workwithsinglerecipe" + xreflabel="working with a single recipe"> + <title>Working with a single recipe</title> + + <para>During development you're likely to often find yourself working on a + single bitbake recipe - maybe trying to fix something or add a new version + or perhaps working on a totally new recipe. Now that you know all about + tasks you can use that knowledge to help speed up the development and + debugging process.</para> + + <para>Bitbake can be instructed to deal directly with a single recipe file + by passing it via the <emphasis role="bold">-b</emphasis> parameter. This + option takes the recipe as a parameter and instructs bitbake to process + the named recipe only. Note that this ignores any dependencies that are in + the recipe, so these must have already been built previously.</para> + + <para>Here's a typically example that cleans up the package (using the + <emphasis>clean</emphasis> task) and the rebuilds it with debugging output + from bitbake enabled:<screen>~%> bitbake -b <bb-file> -c clean +~%> bitbake -b <bb-file> -D</screen></para> + + <para>The options to bitbake that are most useful here are:</para> + + <variablelist> + <varlistentry> + <term>-b <bb-file></term> + + <listitem> + <para>The recipe to process;</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>-c <action></term> + + <listitem> + <para>The action to perform, typically the name of one of the tasks + supported by the recipe;</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>-D</term> + + <listitem> + <para>Display debugging information, use two <emphasis + role="bold">-D</emphasis>'s for additional debugging;</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>-f</term> + + <listitem> + <para>Force an operation. This is useful in getting bitbake to + perform some operation it normally wouldn't do. For example, if you + try and call the <emphasis>compile</emphasis> task twice in a row + then bitbake will not do anything on the second attempt since it has + already performed the task. By adding <emphasis + role="bold">-f</emphasis> it will force it to perform the action + regardless of if it thinks it's been done previously.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>The most common actions (used with -c) are:</para> + + <variablelist> + <varlistentry> + <term>fetch</term> + + <listitem> + <para>Try to download all of the required source files, but don't do + anything else with them.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>unpack</term> + + <listitem> + <para>Unpack the source file but don't apply the patches yet. + Sometimes you may want to look at the extracted, but not patched + source code and that's what just unpacking will give you (some + time's handy to get diffs generated against the original + source).</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>patch</term> + + <listitem> + <para>Apply any patches.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>configure</term> + + <listitem> + <para>Performs and configuration that is required for the + software.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>compile</term> + + <listitem> + <para>Perform the actual compilation steps of the software.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>stage</term> + + <listitem> + <para>If any files, such as header and libraries, will be required + by other packages then they need to be installed into the staging + area and that's what this task takes care of.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>install</term> + + <listitem> + <para>Install the software in preparation for packaging.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>package</term> + + <listitem> + <para>Package the software. Remember that this moves the files from + the installation directory, D, into the packing install area. So to + re-package you also need to re-install first.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>clean</term> + + <listitem> + <para>Delete the entire directory for this version of the software. + Usually done to allow a test build with no chance of old files or + changes being left behind.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Note that each of the actions that corresponds to task's will run + any preceding tasks that have not yet been performed. So starting with + compile will also perform the fetch, unpack, patch and configure + actions.</para> + + <para>A typically development session might involve editing files in the + working directory and then recompiling until it all works:<screen>[<emphasis>... test ...</emphasis>] +~%> bitbake -b packages/testapp/testapp_4.3.bb -c compile -D + +[<emphasis>... save a copy of main.c and make some changes ...</emphasis>] +~%> vi tmp/work/testapp-4.3-r0/main.c +~%> bitbake -b packages/testapp/testapp_4.3.bb -c compile -D -f + +[<emphasis>... create a patch and add it to the recipe ...</emphasis>] +~%> vi packages/testapp/testapp_4.3.bb + +[<emphasis>... test from clean ...</emphasis>] +~%> bitbake -b packages/testapp/testapp_4.3.bb -c clean +~%> bitbake -b packages/testapp/testapp_4.3.bb + +[<emphasis>... NOTE: How to create the patch is not covered at this point ...</emphasis>]</screen></para> + + <para>Here's another example showing how you might go about fixing up the + packaging in your recipe:<screen>~%> bitbake -b packages/testapp/testapp_4.3.bb -c install -f +~%> bitbake -b packages/testapp/testapp_4.3.bb -c stage -f +~%> find tmp/work/testapp_4.3/install +... +~%> vi packages/testapp/testapp_4.3.bb</screen>At this stage you play with + the <emphasis role="bold">PACKAGE_</emphasis> and <emphasis + role="bold">FILES_</emphasis> variables and then repeat the above + sequence.</para> + + <para>Note how we install and then stage. This is one of those things + where understanding the tasks helps a lot! Remember that stage moves the + files from where they were installed into the various subdirectories + (under <emphasis role="bold">${WORKDIR}/instal</emphasis>l) for each + package. So if you try and run a stage task without a prior install there + won't be any files there to stage! Note also that the stage tasks clears + all the subdirectories in <emphasis + role="bold">${WORKDIR}/install</emphasis> so you won't get any left over + files. But beware, the install task doesn't clear <emphasis + role="bold">${D}</emphasis> directory, so any left over files from a + previous packing attempt will be left behind (which is ok if all you care + about it staging).</para> + </section> + + <section id="usage_interactive_bitbake" xreflabel="interactive bitbake"> + <title>Interactive bitbake</title> + + <para>To interactively test things use:<screen>~%> bitbake -i</screen>this + will open the bitbake shell. From here there are a lot of commands + available (try help).</para> + + <para>First thing you will want to do is parse all of the recipes (recent + bitbake version do this automatically when needed, so you don't need to + manually do this anymore):<screen>BB>> parse</screen>You can now + build a specific recipe:<screen>BB>> build net-snmp</screen>If it + fails you may want to clean the build before trying again:<screen>BB>> clean net-snmp</screen>If + you update the recipe by editing the .bb file (to fix some issues) then + you will want to clean the package, reparse the modified recipe, and the + build again:<screen>BB>> clean net-snmp +BB>> reparse net-snmp +BB>> build net-snmp</screen>Note that you can use wildcards in the + bitbake shell as well:<screen>BB>> build t*</screen></para> + + <para></para> + </section> + + <section id="usage_devshell" xreflabel="devshell"> + <title>Devshell</title> + + <para>One of the areas in which OpenEmbedded helps you out is by setting + various environment variables, such as <emphasis role="bold">CC</emphasis> + and <emphasis role="bold">PATH</emphasis> etc, to values suitable for + cross-compiling. If you wish to manually run configure scripts and compile + file during development it would be nice to have all those values set for + you. This is what devshell does - it provides you with an interactive + shell with all the appropriate variables set for cross-compiling.</para> + + <section> + <title>devshell via inherit</title> + + <para>This is the newer method of obtaining a devshell and is the + recommended way for most users now. The newer method requires that the + devshell class be added to you configuration by inheriting it. This is + usually done in your <emphasis role="bold">local.conf</emphasis> or your + distributions conf file:<screen><emphasis role="bold">INHERIT +=</emphasis> "src_distribute_local insane multimachine <emphasis + role="bold">devshell</emphasis>"</screen></para> + + <para>With the inclusion of this class you'll find that devshell is + added as a new task that you can use on recipes:<screen>~%> bitbake -b packages/lzo/lzo_1.08.bb -c listtasks +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task do_listtasks: started +<emphasis role="bold">do_devshell</emphasis> +do_fetchall +do_listtasks +do_rebuild +do_compile +do_build +do_mrproper +do_fetch +do_configure +do_clean +do_populate_staging +do_package +do_unpack +do_install +do_package_write +do_distribute_sources +do_showdata +do_qa_staging +do_qa_configure +do_patch +NOTE: package lzo-1.08-r14: task do_listtasks: completed +NOTE: package lzo-1.08: completed</screen></para> + + <para>To bring up the devshell you call bitbake on a recipe and ask it + for the devshell task:<screen>~%> ./bb -b packages/lzo/lzo_1.08.bb -c devshell +NOTE: package lzo-1.08: started +NOTE: package lzo-1.08-r14: task do_devshell: started +[<emphasis>... devshell will appear here ...</emphasis>] +NOTE: package lzo-1.08-r14: task do_devshell: completed +NOTE: package lzo-1.08: completed</screen></para> + + <para>How the devshell appears depends on the settings of the <emphasis + role="bold">TERMCMD</emphasis> variable - you can see the default + settings and other possible values in <emphasis + role="bold">conf/bitbake.conf</emphasis>. Feel free to try settings this + to something else in your local.conf. Usually you will see a new + terminal window open which is the devshell window.</para> + + <para>The devshell task is inserted after the patch task, so if you have + not already run bitbake on the recipe it will download the source and + apply any patches prior to opening the shell.</para> + + <note> + <para>This method of obtaining a devshell works if you using <emphasis + role="bold">bash</emphasis> as your shell, it does not work if you are + using <emphasis role="bold">zsh</emphasis> as your shell. Other shells + may or may not work.</para> + </note> + </section> + + <section> + <title>devshell addon</title> + + <para>The devshell addon was the original method that was used to create + a devshell.</para> + + <para>It requires no changes to your configuration, instead you simply + build the devshell recipe:<screen>bitabike devshell</screen></para> + + <para>and then manually startup the shell. Once in the shell you'll + usually want to change into the working directory for the recipe you are + working on:<screen>~%> ./tmp/deploy/addons/sh4-linux-erouter-titan-devshell +bash: alias: `./configure': invalid alias name +[OE::sh4-linux-erouter-titan]:~$ cd tmp/work/lzo-1.08-r14/lzo-1.08 +[OE::sh4-linux-erouter-titan]:~tmp/work/lzo-1.08-r14/lzo-1.08$</screen><note> + <para>The name of the devshell addon depends on the target + architecture, operating system and machine name. So you name will be + different - just check for the appropriate name ending in + -devshell.</para> + </note></para> + </section> + + <section> + <title>Working in the devshell</title> + + <para>[To be done]</para> + </section> + </section> + + <section id="usage_patches" xreflabel="patching"> + <title>Patching and patch management</title> + + <para>[To be done]</para> + </section> +</chapter>
\ No newline at end of file diff --git a/docs/usermanual/docbook-utf8.xsl b/docs/usermanual/docbook-utf8.xsl new file mode 100644 index 0000000000..20612834fc --- /dev/null +++ b/docs/usermanual/docbook-utf8.xsl @@ -0,0 +1,10 @@ +<?xml version='1.0'?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + +<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"/> +<xsl:output method="html" + encoding="UTF-8" + indent="no"/> + +</xsl:stylesheet> diff --git a/docs/usermanual/embworld-oe.dbk b/docs/usermanual/embworld-oe.dbk new file mode 100644 index 0000000000..c75d32fa1c --- /dev/null +++ b/docs/usermanual/embworld-oe.dbk @@ -0,0 +1,888 @@ +<BASE HREF="/home/vollmann/winuser/conferences/embworld/embworld-oe.dbk"> + +<?xml version="1.0"?> +<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> + +<!-- $Id$ --> + +<article lang="en"> + <articleinfo> + <date>First version January 3, 2006</date> + <title>OpenEmbedded for Deep Embedded Systems</title> + + <author> + <firstname>Detlef</firstname> + <surname>Vollmann</surname> + <affiliation> + <orgname>vollmann engineering gmbh</orgname> + <address> +<pob>P.O. Box 5423</pob> +<city>6000 Luzern 5</city> +<country>Switzerland</country> +<email>dv@vollmann.ch</email> + </address> + </affiliation> + </author> + + <copyright> + <year>2006</year> + <holder>Detlef Vollmann</holder> + </copyright> + </articleinfo> + +<abstract> +<title>Abstract</title> + <para> +OpenEmbedded has won the TuxMobil GNU/Linux +Award 2005 that honors Free Software projects, which improve Linux +for mobile computers. OpenEmbedded is a Linux distribution similar +to Debian that has its roots in the PDA domain. It is today pretty +popular among Linux fans who own Zaurus', iPAQs or similar PDAs. +But OpenEmbedded is targeted at all kinds of embedded Linux systems. +It features a unique cross build environment that generally allows +pretty easy adaption of OpenSource software for cross compilation even +if the original software authors didn't think about cross builds. +That build environment also allows for easy definition and builds of +complete distributions for embedded systems. + </para> + + <para> +OpenEmbedded also provides a lightweight and fine-grained package +system that enables easy installation of new software packages into +a running system as well as updates of existing software. +These features makes OpenEmbedded a first choice for the creation +of embedded Linux systems. + </para> +</abstract> + + +<sect1 label="1" id="introduction"> +<title>Introduction</title> + <para> +When Sharp launched its Zaurus PDA, it came with a Linux based PDA system. +But not all users were happy with the original Sharp configuration and +so the OpenZaurus project was created to share the modifications. +Later, OpenZaurus moved from modifications to the original Sharp image +to a complete distribution based on Debian. + </para> + + <para> +But the build system for Debian was not really suited for small embedded +systems and so OpenEmbedded was founded with a build system inspired +from Gentoo's <command>portage</command>. As package system iPKG was used, which is +closely related to Debian's <command>dpkg</command>, but more tuned for small embedded +devices. +Later, distributions for other PDAs like Compaq's iPAQs or the Siemens +SimPad moved to the OpenEmbedded build and package system. +A very interesting distribution based on OpenEmbedded is OpenSLUG +for LinkSys' NSLU device. The NSLU is not a PDA but originally +an NAS storage system. + </para> + + <para> +Today, OpenEmbedded describes itself as a "set of recipes and metadata +to build Linux distributions for embedded devices with the BitBake +build system". + </para> + + <para> +OpenEmbedded provides three major benefits for building a distribution +for an embedded system: + <itemizedlist mark='bullet'> +<listitem> + <para> + a build system that builds everything + </para> +</listitem> +<listitem> + <para> + recipes and metadata to build more that 1000 different programs + and libraries + </para> +</listitem> +<listitem> + <para> + a binary package system that provides simple configuration and update + mechanisms + </para> +</listitem> + </itemizedlist> + </para> + + <para> +The remainder of this article focuses on the use of OpenEmbedded +for deep embedded systems like the NSLU opposed to PDA like systems +like the SimPad. + </para> + +</sect1> + +<sect1 id="overview"> +<title>Overview</title> + <sect2> + <title>Build System</title> + <para> +Like any build tool (make, ant, jam), the OpenEmbedded build tool +BitBake controls how to build things and the build dependencies. +But unlike single project tools like <command>make</command> it is not based on one makefile +or a closed set of inter-dependent makefiles, but collects and manages +an open set of largely independent build descriptions (package recipes) and +builds them in proper order. + </para> + + <para> +The OpenEmbedded set of package recipes include not only recipes for +target packages, but also recipes for tools on the host required to build +those target packages. So, OpenEmbedded builds a complete toolchain +for cross-building before building the target packages and image. + </para> + </sect2> + + <sect2> + <title>Metadata</title> + <para> +The metadata from which an OpenEmbedded distribution is built comes in +three different forms: + <itemizedlist mark='bullet'> + <listitem> + <para> + configuration files + </para> + </listitem> + <listitem> + <para> + class descriptions + </para> + </listitem> + <listitem> + <para> + package recipes + </para> + </listitem> + </itemizedlist> + </para> + + <para> +The configuration files provide general variable definitions to control +the behaviour of BitBake and how things are generally built in +OpenEmbedded. This includes the build system's directory structure, +version preferences, source code mirror sites as well as specific build +options (e.g. the default optimizing level). + </para> + + <para> +The class descriptions define common procedures to build things, like +applying the auto-tools for configuration, collecting runtime library +dependencies or building native build tools for the host. +These class descriptions are sometimes quite specific, e.g. there exists a +class to remove NLS parts of a package if NLS support is not wanted. + </para> + + <para> +The package recipes provide the information how to build a specific +piece of software ‐ a build tool for the host, a library or a +target application. Such recipes provide the information how to get +and how to build a package and dependencies on other packages. + </para> + + <para> +Meta package recipes don't build a specific package, but mainly consist +of dependency descriptions to build a complete set of packages, often +a base image for a specific distribution. + </para> + </sect2> + + <sect2> + <title>Package System</title> + <para> +The iPKG package system is (deliberately) very similar to Debian's <command>dpkg</command>, +but is tuned for small systems. It contains the package data that is +simply copied to the target system, metadata and optionally +installation scripts. The metadata includes the (run-time) dependencies +of the package. + </para> + + <para> +Package systems are mainly for the benefit of users of computer-like +devices who want to install their own specific set of software. +Such package systems provide two major benefits: + <itemizedlist mark='bullet'> + <listitem> + <para> + easy definition of an initial image, often called 'base system' + </para> + </listitem> + <listitem> + <para> + controlled installation, upgrade and de-installation of packages + on the running system + </para> + </listitem> + </itemizedlist> + </para> + + <para> +These benefits also apply to (deep) embedded systems. +Different configurations are just different sets of packages. They can +even share the already built packages from existing configurations. + </para> + + <para> +In traditional embedded systems for an update first a new +complete image is built that then requires on the target a shutdown, +a complete re-flash of the image and finally a restart of the system. +Contrasting to that image-based process, a package system allows easy +updates on a live, running system that +even allows to have some processes running the old version (though it +is already de-installed) while other processes already run the new version. + </para> + </sect2> +</sect1> + +<sect1> + <title>Working with OpenEmbedded</title> + <para> +To build a system based on OpenEmbedded, normally a small set of +configuration files is needed: + <itemizedlist mark='bullet'> + <listitem> + <para> + <filename>local.conf</filename> to define what to build and where to get and put it + </para> + </listitem> + <listitem> + <para> + a machine configuration to describe the hardware + </para> + </listitem> + <listitem> + <para> + a distribution configuration to define global properties of the system + </para> + </listitem> + </itemizedlist> + </para> + + + <para> +Apart from that, typically a meta package for the base image is required. +And then of course the recipes for specific packages, e.g. a kernel +package, packages for additional Open Source applications and +packages for project specific software. + </para> + + <sect2> + <title><filename>local.conf</filename></title> + <para> +The local configuration file <filename>local.conf</filename> defines the local directory +structure, the local build environment, some project specific preferences +and other properties specific to the build system. + </para> + <para> +A very simple and short <filename>local.conf</filename> could look like this: +<programlisting> +# DL_DIR specifies the download target directory +DL_DIR = "${PROJECT}/oesrc" + +# BBFILES specifies the full set of package recipes to be parsed by BitBake +BBFILES = "${PROJECT}/org.openembedded.dev/packages/*/*.bb" + +# BBMASK specifies which package recipes to ignore from the full set above +BBMASK = "" + +# ASSUME_PROVIDED defines what local host build tools should +# not be built by BitBake but should be used from the local +# build host's installation +ASSUME_PROVIDED = "flex-native" + +# For some tools exist different alternative implementations, +# e.g. for the C runtime library there exist glibc and uClibc. +# PREFERRED_PROVIDERS defines which specific package to build +PREFERRED_PROVIDERS = "virtual/kernel:mymach24" +PREFERRED_PROVIDERS += " virtual/libc:glibc" + +# For many packages exist several different recipes. +# PREFERRED_VERSION defines which specific recipe to use +PREFERRED_VERSION_gcc-cross = "3.3.2" + +# MACHINE defines for which hardware to build +MACHINE = "mymach" + +# DISTRO defines which distribution to build +DISTRO = "mymini" + +# IMAGE_FSTYPES defines which kind of images to create +IMAGE_FSTYPES = "jffs2 tar" + +# For a number of package recipe versions the source code is fetched directly +# from the original CVS repository head. To make sure that for separate +# builds this fetches the same source, use CVSDATE. +CVSDATE = "20051122" + +# For some packages specific CVS versions are provided as tarballs. +# CVS_TARBALL_STASH defines where to find them. +CVS_TARBALL_STASH = "http://www.oesources.org/source/current/" + +# For a number of software sets it is possible to specify local +# mirror sites where to get the software. +export GNU_MIRROR = "http://mirror.switch.ch/ftp/mirror/gnu" + +# URL for own stuff +MY_URL = "http://myserver/projects/oe" + +</programlisting> + + </para> + </sect2> + + <sect2> + <title>Machine Configuration</title> + <para> +The machine configuration file <filename>conf/machine/mymach.conf</filename> specifies +the hardware for which a distribution is built. This includes mainly +the CPU architecture, specific hardware kernel modules and some size +specifications. + </para> + <para> +A simple example could look like this: +<programlisting> +#@TYPE: Machine +#@NAME: My own hardware +#@DESCRIPTION: Machine configuration for my system XYZ + +# the target CPU architecture +TARGET_ARCH = "arm" + +# all compatible binary architectures +IPKG_ARCHS = "all arm armv4 armv4t armv5e armv5te ipaqpxa mymach" + +# some packages for which we know they work best for our hardware +PREFERRED_PROVIDER_xserver ?= "xserver-kdrive" +PREFERRED_PROVIDER_virtual/kernel ?= "mykernel24" + +# some packages we always need for this hardware +BOOTSTRAP_EXTRA_DEPENDS = "virtual/kernel sdmmc-support altboot" +BOOTSTRAP_EXTRA_RDEPENDS = "kernel sdmmc-support altboot" +BOOTSTRAP_EXTRA_RDEPENDS += " kernel-module-usbdcore kernel-module-usbdmonitor" + +# autoload on boot +module_autoload_mydriver = "mydriver" + +# compile with XScale optimization +include conf/machine/tune-xscale.conf + +# some specific settings +SERIAL_CONSOLE = "115200 ttyS0" +ROOT_FLASH_SIZE = "16" +GUI_MACHINE_CLASS = "smallscreen" + +</programlisting> + + </para> + </sect2> + + <sect2> + <title>Distribution Configuration</title> + <para> +The distribution configuration file <filename>conf/distro/mymini.conf</filename> specifies +global configuration parameters for the whole software system on the +target. The main definition here is the OS setting, but included here are +also internationalization settings or a specific target filesystem layout. + </para> + <para> +A simple example could look like this: +<programlisting> +#@TYPE: Distribution +#@NAME: MyMini +#@DESCRIPTION: A minimal base system for my system + +# some general descriptions +DISTRO = "MyMini" +DISTRO_NAME = "My Minimal Embedded Linux" +DISTRO_VERSION = "1.0" +DISTRO_TYPE = "release" + +# feed definitions for ipkg +FEED_URIS += " \ + base##${MY_URL}/${DISTRO_VERSION}/feed/base \ + updates##${MY_URL}/${DISTRO_VERSION}/feed/updates" + +# base system +TARGET_FPU = "soft" +TARGET_OS = "linux-uclibc" + +# specific software versions +PREFERRED_PROVIDER_xserver ?= "xserver-kdrive" +PREFERRED_VERSION_xserver-kdrive ?= "20050207" + +# i18n +USE_NLS = "yes" + +# distro is based on udev +UDEV_DEVFS_RULES = "1" + +# distro is ipkg based +INHERIT += " package_ipk" + +</programlisting> +<!-- note MY_URL here --> + + </para> + </sect2> + + <sect2> + <title>An Image Package</title> + <para> +The image package recipe <filename>packages/meta/my-image.bb</filename> +builds the base system +for the root filesystem image. It mainly defines the packages that +are included in the base image. + </para> + <para> +A simple example could look like this: +<programlisting> +# general description data +DESCRIPTION = "Core packages for a minimal installation for My" +MAINTAINER = "Me <me@myname.org>" +LICENSE = "GPL" +PR = "r0" + +MY_PACKAGES = "base-files-my \ + busybox-my initscripts-colibri netbase \ + sysvinit usbutils modutils-initscripts \ + my-modules24 e2fsprogs-mke2fs diffutils ipkg" + +# binary architecture for ipkg +PACKAGE_ARCH = "${MACHINE_ARCH}" + +# name +export IMAGE_BASENAME = "my" + +# which languages to include +export IMAGE_LINGUAS = "" + +# which packages to include +export IPKG_INSTALL = ${MY_PACKAGES} + +# give the packages again so the build systems knows they must be built +DEPENDS = ${MY_PACKAGES} + +# inherit the class that finally builds the image +inherit image_ipk + +</programlisting> + + </para> + </sect2> + + <sect2> + <title>A Kernel Package</title> + <para> +The kernel is typically specific to a hardware, so usually an own kernel +package is required. + </para> + <para> +A simple example <filename>packages/linux/mymach24_2.4.29-mymach</filename> +could look like this: +<programlisting> +DESCRIPTION = "Linux kernel 2.4 for My hardware" +MAINTAINER = "Me <me@myname.org>" +SECTION = "kernel" +LICENSE = "GPL" +PR = "r0" + +# compute the kernel version strings +KV = "${@bb.data.getVar('PV',d,True).split('-')[0]}" +MYV = "${@bb.data.getVar('PV',d,True).split('-')[1]}" + +# object suffix dependent on kernel version +KERNEL_OBJECT_SUFFIX = ".o" + +# where to get the base kernel +SRC_URI = "${KERNEL_MIRROR}/v2./linux-${KV}.tar.bz2" + +# where to get my specific patches +SRC_URI_append = " ${MY_URL}/patches/linux-${KV}-${MYV}.patch.gz;patch=1" + +# specify the source directory +# (only necessary where it differs from the package name) +S = "${WORKDIR}/linux-${KV}" + +# inherit the class that actually does the work building kernels +inherit kernel + +# this not only builds the kernel itself but also the modules +PROVIDES += " my-modules24" +PACKAGES += " my-modules24" + +# tell the packager where the files for the modules package are found +FILES_my-modules24 = "/lib/modules" + +# which machines are supported by this kernel +COMPATIBLE_HOST = "arm.*-linux" + +# nothing special is required to build the kernel, as it comes with +# full support for cross compilation +EXTRA_OEMAKE = "" + +# the actual configure command +# oe_runmake just runs make +do_configure() { + oe_runmake mymach_defconfig +} + +# clean up after module installation +do_install_append() { + rm -f ${D}/lib/modules/*/build + rm -f ${D}/lib/modules/*/source +} + +</programlisting> +Some details for this package recipe are explained in the next section. + </para> + </sect2> + + <sect2> + <title>A Package for an Open Source Project</title> + <para> +Though OpenEmbedded comes with recipes for many Open Source projects, +sometimes a package is required for which no recipe exists yet. +But providing a recipe for that project is generally quite easy. + +Most Open Source projects are based on the configure mechanism to build. +<command>configure</command> is a script to collect information about +the build environment +and creates makefiles based on that information. + </para> + <para> +But the configure script itself is normally generated through the auto-tools. +The normal OpenEmbedded build process for such a project is to rebuild the +configure script based on the ultimate source <filename>Makefile.am</filename> +and <filename>configure.ac</filename>. + </para> + <para> +So, a simple package file for the <command>at</command> tool looks like this: +<programlisting> +DESCRIPTION = "Delayed job execution and batch processing." +SECTION = "base" +LICENSE="BSD" + +PR = "r1" + +DEPENDS = "flex-native" + +SRC_URI = "${DEBIAN_MIRROR}/main/a/at/at_${PV}-11.tar.gz \ + file://configure.patch;patch=1 \ + file://nonrootinstall.patch;patch=1" + +inherit autotools + +</programlisting> + </para> + <para> +That's all. Here a walkthrough for this recipe: +The first three lines in this package file are just general information +(that are included into the resulting binary package). + </para> + <para> +<varname>PR</varname> defines the revision and should be incremented +on each change to the package recipe. + </para> + <para> +The <varname>DEPENDS</varname> definition states that the building of +this package depends +on an existing flex installation on the host (therefore the +<filename>-native</filename>). + </para> + <para> +The <varname>SRC_URI</varname> defines the place of the source files +to be downloaded: +the main distribution tarball with the URL where to find it, and two +specific patches to build this package with OpenEmbedded. +These patches are located together with the package file. +The <varname>patch=1</varname> specifies that this file is to be +applied as patch with <option>-p1</option>. +The <varname>${PV}</varname> in the tarball URL is expanded from the +recipe version +number. And the recipe version number is taken from the file name +of the recipe. So, if this recipe is provided as +<filename>packages/at/at_3.1.8.bb</filename>, +<varname>${PV}</varname> is expanded to <varname>3.1.8</varname>. + </para> + <para> +The next line essentially does all the work: it inherits the +<classname>autotools</classname> +class that adds the necessary step (task) to rebuild the configure script. + </para> + <para> +And that's all. The <classname>base</classname> class that is inherited +by all packages +defines all the other tasks to build the binary package: + <itemizedlist mark='bullet'> + <listitem> + <para> + <function>do_fetch()</function>, which does the download + </para> + </listitem> + <listitem> + <para> + <function>do_unpack()</function>, which builds the working directory + and unpacks all files + </para> + </listitem> + <listitem> + <para> + <function>do_patch()</function>, which applies the patches + </para> + </listitem> + <listitem> + <para> + <function>do_configure()</function>, which runs the configure script + </para> + </listitem> + <listitem> + <para> + <function>do_compile()</function>, which basically calls make + </para> + </listitem> + <listitem> + <para> + <function>do_stage()</function>, which installs library and header + files in the cross build environment for subsequent builds + </para> + </listitem> + <listitem> + <para> + <function>do_install()</function>, which installs the built files + into a special packaging area + </para> + </listitem> + <listitem> + <para> + <function>do_package()</function>, which collects the files from + the packaging area and creates (possibly several) packages + </para> + </listitem> + </itemizedlist> + </para> + <para> +All these tasks can be overwritten: in the kernel package example above +the <function>do_configure()</function> is redefined to run make with +a special target, and in the inherited <classname>autotools</classname> class +for this example the <function>do_configure()</function> is redefined to +add a <command>autoreconfig</command> +run to rebuild the configure script before the actual configure. + </para> + </sect2> + + <sect2> + <title>Own Software</title> + <para> +For own software projects it is possible also to use the +<command>auto</command>-tools and <command>configure</command> to create +the makefiles. But this requires some familiarity +with those tools and is not really necessary. A standard makefile will +suffice, if some simple rules are observed: + <itemizedlist mark='bullet'> + <listitem> + <para> + don't use fix pathnames for include, library and install directories, + use variables for those directories. + </para> + </listitem> + <listitem> + <para> + use variables for all building commands (including <command>ar</command> +and <command>nm</command>, if used). + </para> + </listitem> + <listitem> + <para> + provide an <varname>install</varname> target. + </para> + </listitem> + </itemizedlist> + </para> + <para> +So, a makefile for the standard "Hello, World" example would look like this: +<programlisting> +CC = arm-linux-gcc +LD = arm-linux-ld +CXX = arm-linux-g++ +INSTALL = install + +prefix = "" +bindir = $(prefix)/usr/bin + +TARGETS = hello + +all: $(TARGETS) + +hello: hello.cxx + $(CXX) $(CXXFLAGS) -o $@ $< + +clean: + rm -f *.o $(TARGETS) *~ + +install: + $(INSTALL) hello $(bindir) + +</programlisting> + </para> + <para> +The next decision to make is how to provide the source code: +it might either be available through some download mechanism, possibly +from a local CVS server, or it might be added as a local tarball to the +package file. + </para> + <para> +Based on that, the actual package recipe file is pretty simple: +<programlisting> +DESCRIPTION = "Hello world example" +SECTION = "base" +LICENSE="BSD" +MAINTAINER = "Me <me@myname.org>" + +PR = "r0" + +SRC_URI = "file://hello-${PV}.tar.gz" + +# just don't do any configuring +do_configure() { +} +</programlisting> + </para> + <para> +The recipes shown here are all pretty simple. But actually 90% of +the recipes in OpenEmbedded are not much more complex. And for +more complex packages normally some recipes already exist, if not +for exactly the wanted package then for a similar one. + </para> + <para> +And for the really complicated cases the OpenEmbedded developers +on the mailing list are always helpful. + </para> + </sect2> +</sect1> + + +<sect1 id="conclusion"> +<title>Conclusion</title> + <para> +Most embedded Linux systems currently follow the full image approach: +if something changes, the complete image is rebuilt and deployed. + </para> + + <para> +An embedded Linux distribution that provides a package system +follows a different approach: the original image provides only +a base system that is augmented incrementally by separate packages. + </para> + + <para> +OpenEmbedded provides not only such a package system, but also the +tools to build these packages, i.e. the BitBake build tools +and all the metadata in form of predefined classes for most +common tasks for building an embedded Linux distribution. + </para> + + <para> +And OpenEmbedded comes with lots of ready-to-use package recipes +for Open Source tools, libraries and applications. + </para> + + <para> +But OpenEmbedded has also drawbacks: +It is quite complex and though this complexity is often hidden +in the provided classes, it is sometimes necessary to understand +that complexity. And though most package recipes are quite simple, +even these simple things must be learned, and documentation is a bit scarce. +But the OpenEmbedded developers on the mailing list are generally +friendly and willingly provide some pointers to solve simple +and complex tasks. + </para> + + <para> +Another drawback is the amounts of resources required to build +OpenEmbedded: to build a basic distribution including a GUI +takes several hours; to build everything takes nearly two +days on a Pentium M @ 2GHz. And it takes about 30GHz disk space. + </para> + + <para> +A last drawback is the SCM monotone used by OpenEmbedded: +pulling and updating is quite slow. + </para> + + <para> +Some of these drawbacks are just due to the fact that OpenEmbedded +now provides a huge repository of recipes: to build one package +and its dependencies, OpenEmbedded must parse all recipes to know +which recipe provides what, and with more than 3000 recipes this +takes some time. But the OpenEmbedded developers are aware especially +of the performance problems (they are bitten themselves most by them) +and try to solve at least some of them. + </para> +</sect1> + + <bibliography> + <title>References</title> + <biblioentry id="OpenEmbeddedBib"> + <title>OpenEmbedded Homepage</title> + <bibliomisc> + <ulink url="http://www.openembedded.org/"> +http://www.openembedded.org/ + </ulink> + </bibliomisc> + </biblioentry> + + <biblioentry> + <title>Developer Documentation</title> + <bibliomisc> + <ulink url="http://oe.handhelds.org/cgi-bin/moin.cgi"> +http://oe.handhelds.org/cgi-bin/moin.cgi + </ulink> + </bibliomisc> + </biblioentry> + + <biblioentry> + <title>OpenEmbedded recipe hints</title> + <bibliomisc> + <ulink url="http://oe.handhelds.org/cgi-bin/moin.cgi/bb_20file"> +http://oe.handhelds.org/cgi-bin/moin.cgi/bb_20file + </ulink> + </bibliomisc> + </biblioentry> + + <biblioentry> + <title>BitBake manual</title> + <bibliomisc> + <ulink url="http://bitbake.berlios.de/manual/"> +http://bitbake.berlios.de/manual/ + </ulink> + </bibliomisc> + </biblioentry> + + <biblioentry> + <title>iPKG</title> + <bibliomisc> + <ulink url="http://www.handhelds.org/moin/moin.cgi/Ipkg"> +http://www.handhelds.org/moin/moin.cgi/Ipkg + </ulink> + </bibliomisc> + </biblioentry> + + <biblioentry> + <title>OpenEmbedded monotone hints</title> + <bibliomisc> + <ulink url="http://oe.handhelds.org/cgi-bin/moin.cgi/MonotonePhraseBook"> +http://oe.handhelds.org/cgi-bin/moin.cgi/MonotonePhraseBook + </ulink> + </bibliomisc> + </biblioentry> + +</bibliography> + +</article> + diff --git a/docs/usermanual/html.css b/docs/usermanual/html.css new file mode 100644 index 0000000000..d2dbf80e01 --- /dev/null +++ b/docs/usermanual/html.css @@ -0,0 +1,282 @@ +/* Feuille de style DocBook du projet Traduc.org */ +/* DocBook CSS stylesheet of the Traduc.org project */ + +/* (c) Jean-Philippe Guérard - 14 août 2004 */ +/* (c) Jean-Philippe Guérard - 14 August 2004 */ + +/* Cette feuille de style est libre, vous pouvez la */ +/* redistribuer et la modifier selon les termes de la Licence */ +/* Art Libre. Vous trouverez un exemplaire de cette Licence sur */ +/* http://tigreraye.org/Petit-guide-du-traducteur.html#licence-art-libre */ + +/* This work of art is free, you can redistribute it and/or */ +/* modify it according to terms of the Free Art license. You */ +/* will find a specimen of this license on the Copyleft */ +/* Attitude web site: http://artlibre.org as well as on other */ +/* sites. */ +/* Please note that the French version of this licence as shown */ +/* on http://tigreraye.org/Petit-guide-du-traducteur.html#licence-art-libre */ +/* is only official licence of this document. The English */ +/* is only provided to help you understand this licence. */ + +/* La dernière version de cette feuille de style est toujours */ +/* disponible sur : http://tigreraye.org/style.css */ +/* Elle est également disponible sur : */ +/* http://www.traduc.org/docs/HOWTO/lecture/style.css */ + +/* The latest version of this stylesheet is available from: */ +/* http://tigreraye.org/style.css */ +/* It is also available on: */ +/* http://www.traduc.org/docs/HOWTO/lecture/style.css */ + +/* N'hésitez pas à envoyer vos commentaires et corrections à */ +/* Jean-Philippe Guérard <jean-philippe.guerard@tigreraye.org> */ + +/* Please send feedback and bug reports to */ +/* Jean-Philippe Guérard <jean-philippe.guerard@tigreraye.org> */ + +/* $Id: style.css,v 1.14 2004/09/10 20:12:09 fevrier Exp fevrier $ */ + +/* Présentation générale du document */ +/* Overall document presentation */ + +body { + /* + font-family: Apolline, "URW Palladio L", Garamond, jGaramond, + "Bitstream Cyberbit", "Palatino Linotype", serif; + */ + margin: 7%; + background-color: white; +} + +/* Taille du texte */ +/* Text size */ + +* { font-size: 100%; } + +/* Gestion des textes mis en relief imbriqués */ +/* Embedded emphasis */ + +em { font-style: italic; } +em em { font-style: normal; } +em em em { font-style: italic; } + +/* Titres */ +/* Titles */ + +h1 { font-size: 200%; font-weight: 900; } +h2 { font-size: 160%; font-weight: 900; } +h3 { font-size: 130%; font-weight: bold; } +h4 { font-size: 115%; font-weight: bold; } +h5 { font-size: 108%; font-weight: bold; } +h6 { font-weight: bold; } + +/* Nom de famille en petites majuscules (uniquement en français) */ +/* Last names in small caps (for French only) */ + +*[class~="surname"]:lang(fr) { font-variant: small-caps; } + +/* Blocs de citation */ +/* Quotation blocs */ + +div[class~="blockquote"] { + border: solid 2px #AAA; + padding: 5px; + margin: 5px; +} + +div[class~="blockquote"] > table { + border: none; +} + +/* Blocs litéraux : fond gris clair */ +/* Literal blocs: light gray background */ + +*[class~="literallayout"] { + background: #f0f0f0; + padding: 5px; + margin: 5px; +} + +/* Programmes et captures texte : fond bleu clair */ +/* Listing and text screen snapshots: light blue background */ + +*[class~="programlisting"], *[class~="screen"] { + background: #f0f0ff; + padding: 5px; + margin: 5px; + border: 1px solid #ddd; +} + +/* Les textes à remplacer sont surlignés en vert pâle */ +/* Replaceable text in highlighted in pale green */ + +*[class~="replaceable"] { + background-color: #98fb98; + font-style: normal; } + +/* Tables : fonds gris clair & bords simples */ +/* Tables: light gray background and solid borders */ + +*[class~="table"] *[class~="title"] { width:100%; border: 0px; } + +table { + border: 1px solid #aaa; + border-collapse: collapse; + padding: 2px; + margin: 5px; +} + +/* Listes simples en style table */ +/* Simples lists in table presentation */ + +table[class~="simplelist"] { + background-color: #F0F0F0; + margin: 5px; + border: solid 1px #AAA; +} + +table[class~="simplelist"] td { + border: solid 1px #AAA; +} + +/* Les tables */ +/* Tables */ + +*[class~="table"] table { + background-color: #F0F0F0; + border: solid 1px #AAA; +} +*[class~="informaltable"] table { background-color: #F0F0F0; } + +th,td { + vertical-align: baseline; + text-align: left; + padding: 0.1em 0.3em; + empty-cells: show; +} + +/* Alignement des colonnes */ +/* Colunms alignment */ + +td[align=center] , th[align=center] { text-align: center; } +td[align=right] , th[align=right] { text-align: right; } +td[align=left] , th[align=left] { text-align: left; } +td[align=justify] , th[align=justify] { text-align: justify; } + +/* Pas de marge autour des images */ +/* No inside margins for images */ + +img { border: 0; } + +/* Les liens ne sont pas soulignés */ +/* No underlines for links */ + +:link , :visited , :active { text-decoration: none; } + +/* Prudence : cadre jaune et fond jaune clair */ +/* Caution: yellow border and light yellow background */ + +*[class~="caution"] { + border: solid 2px yellow; + background-color: #ffffe0; + padding: 1em 6px 1em ; + margin: 5px; +} + +*[class~="caution"] th { + vertical-align: middle +} + +*[class~="caution"] table { + background-color: #ffffe0; + border: none; +} + +/* Note importante : cadre jaune et fond jaune clair */ +/* Important: yellow border and light yellow background */ + +*[class~="important"] { + border: solid 2px yellow; + background-color: #ffffe0; + padding: 1em 6px 1em; + margin: 5px; +} + +*[class~="important"] th { + vertical-align: middle +} + +*[class~="important"] table { + background-color: #ffffe0; + border: none; +} + +/* Mise en évidence : texte légèrement plus grand */ +/* Highlights: slightly larger texts */ + +*[class~="highlights"] { + font-size: 110%; +} + +/* Note : cadre bleu et fond bleu clair */ +/* Notes: blue border and light blue background */ + +*[class~="note"] { + border: solid 2px #7099C5; + background-color: #f0f0ff; + padding: 1em 6px 1em ; + margin: 5px; +} + +*[class~="note"] th { + vertical-align: middle +} + +*[class~="note"] table { + background-color: #f0f0ff; + border: none; +} + +/* Astuce : cadre vert et fond vert clair */ +/* Tip: green border and light green background */ + +*[class~="tip"] { + border: solid 2px #00ff00; + background-color: #f0ffff; + padding: 1em 6px 1em ; + margin: 5px; +} + +*[class~="tip"] th { + vertical-align: middle; +} + +*[class~="tip"] table { + background-color: #f0ffff; + border: none; +} + +/* Avertissement : cadre rouge et fond rouge clair */ +/* Warning: red border and light red background */ + +*[class~="warning"] { + border: solid 2px #ff0000; + background-color: #fff0f0; + padding: 1em 6px 1em ; + margin: 5px; +} + +*[class~="warning"] th { + vertical-align: middle; +} + + +*[class~="warning"] table { + background-color: #fff0f0; + border: none; +} + +/* Fin */ +/* The End */ + diff --git a/docs/usermanual/reference/.mtn2git_empty b/docs/usermanual/reference/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/docs/usermanual/reference/.mtn2git_empty diff --git a/docs/usermanual/reference/class_autotools.xml b/docs/usermanual/reference/class_autotools.xml new file mode 100644 index 0000000000..a9e1a5721a --- /dev/null +++ b/docs/usermanual/reference/class_autotools.xml @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="autotools_class" xreflabel="autotools class"> + <title>autotools class</title> + + <para>Autotools is one of the most commonly seen configuration methods for + applications. Anything that uses the standard <command>./configure; make; + make install</command> sequence is using autotools. Usually the configure + script will support a large number of options to specify various + installation directories, to disable and/or enable various features and + options to specify search paths for headers and libraries.</para> + + <para>The autotools class takes care of all of the details for you. It + defines appropriate tasks for <emphasis>configure</emphasis>, + <emphasis>compile</emphasis>, <emphasis>stage</emphasis> and + <emphasis>install</emphasis>. At it's simplest adding an inherit for the + autotools class is all that is required. The netcat recipe for example + is:<screen>DESCRIPTION = "GNU Netcat" +HOMEPAGE = "http://netcat.sourceforge.net" +LICENSE = "GPLv2" +MAINTAINER = "Your name <yname@example.com>" +SECTION = "console/networking" +PR = "r1" + +SRC_URI = "${SOURCEFORGE_MIRROR}/netcat/netcat-${PV}.tar.bz2" + +inherit autotools</screen>The header is defined, the location of the source + code and then the inherit. For the simplest cases this is all that is + required. If you need to pass additional parameters to the configure script, + such as for enabling and/or disabling options, then they can be specified + via the <command>EXTRA_OECONF</command> variable. This example from the lftp + recipe shows several extra options being passed to the configure + script:<screen>EXTRA_OECONF = "--disable-largefile --disable-rpath --with-included-readline=no"</screen>If + you define your own tasks for <emphasis>configure</emphasis>, + <emphasis>compile</emphasis>, <emphasis>stage</emphasis> or + <emphasis>install</emphasis> (via <command>do_<taskname></command>) + then they will override the methods generated by the autotools class. If you + need to perform additional operations (rather than replacing the generated + operations) you can use the <command>do_<task>_append</command> or + <command>do_<task>_prepend</command> methods. The following example + from the conserver recipe shows some additional items being + installed:<screen># Include the init script and default settings in the package +do_install_append () { + install -m 0755 -d ${D}${sysconfdir}/default ${D}${sysconfdir}/init.d + install -m 0644 ${WORKDIR}/conserver.default ${D}${sysconfdir}/default/conserver + install -m 0755 ${WORKDIR}/conserver.init ${D}${sysconfdir}/init.d/conserver +}</screen></para> + + <section> + <title>oe_runconf / autotools_do_configure</title> + + <para>Autotools generates a configuration method called + <command>oe_runconf</command> which runs the actual configure script, and + a method called <command>autotools_do_configure</command> which generates + the configure file (runs automake and autoconf) and then calls + <command>oe_runconf</command>. The generated method for the + <emphasis>configure</emphasis> task, <command>do_configure</command>, just + calls the <command>autotools_do_configure</command> method.</para> + + <para>It is sometimes desirable to implement your own + <command>do_configure</command> method, where additional configuration is + required or where you wish to inhibit the running of automake and + autoconf, and then manually call <command>oe_runconf</command>.</para> + + <para>The following example from the ipacct recipe shows an example of + avoiding the use of automake/autoconf:<screen>do_configure() { + oe_runconf +}</screen>Sometimes manual manipulations of the autotools files is required + prior to calling autoconf/automake. In this case you can defined your own + <command>do_configure</command> method which performs the required actions + and then calls <command>autotools_do_configure</command>.</para> + </section> + + <section> + <title>Presetting autoconf variables (the site file)</title> + + <para>The autotools configuration method has support for caching the + results of tests. In the cross-compilation case it is sometimes necessary + to prime the cache with per-calculated results (since tests designed to + run on the target cannot be run when cross-compiling). These are defined + via the site file(s) for the architecture you are using and may be + specific to the package you are building.</para> + + <para>Autoconf uses site files as definied in the + <command>CONFIG_SITE</command> variable, which is a space seperate list of + files to load in the specified order. Details on how this variable is set + is provided in the <xref linkend="siteinfo_class" /> (the class + responsbile for setting the variable) section.</para> + + <para>There are some things that you should keep in mind about the caching + of configure tests:</para> + + <orderedlist> + <listitem> + <para>Check the other site files to see if there any entries for the + application you are attempting to build.</para> + + <para>Sometimes entries are only updated for the target that the + developer has access to. If they exist for another target then it may + provide a good idea of what needs to be defined.</para> + </listitem> + + <listitem> + <para>Sometimes the same cache value is used by multiple + applications.</para> + + <para>This can have the side effect where a value added for one + application breaks the build of another. It is a very good idea to + empty the site file of all other values if you are having build + problems to ensure that none of the existing values are causing + problems.</para> + </listitem> + + <listitem> + <para>Not all values can be stored in the cache</para> + + <para>Caching of variables is defined by the author of the configure + script, so sometimes not all variables can be set via the cache. In + this case it often means resorting to patching the original configure + scripts to achieve the desired result.</para> + </listitem> + </orderedlist> + + <para>All site files are shell scripts which are run by autoconf and + therefore the syntax is the same as you would use in sh. There are two + current methods of settings variables that is used in the existing site + files. This include explicitly settings the value of the variable:<screen>ac_cv_sys_restartable_syscalls=yes</screen>and + conditionally setting the value of the variable:<screen>ac_cv_uchar=${ac_cv_uchar=no}</screen>The + conditional version is using shell syntax to say "<emphasis>only set this + to the specified value if it is not currently set</emphasis>". The + conditional version allows the variable to be set in the shell prior to + calling configure and it will then not be replaced by the value from the + site file.</para> + + <note> + <para>Site files are applied in order, so the application specific site + files will be applied prior to the top level site file entries. The use + of conditional assignment means that the first definition found will + apply, while when not using conditionals the last definition found will + apply.</para> + </note> + + <para>It is possible to disable the use of the cached values from the site + file by clearing the definition of <command>CONFIG_SITE</command> prior to + running the configure script. Doing this will disable the use of the site + file entirely. This however should be used as a last resort. The following + example from the db recipe shows an example of this:<screen># Cancel the site stuff - it's set for db3 and destroys the +# configure. +CONFIG_SITE = "" +do_configure() { + oe_runconf +}</screen></para> + </section> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/class_binconfig.xml b/docs/usermanual/reference/class_binconfig.xml new file mode 100644 index 0000000000..049f85e1f0 --- /dev/null +++ b/docs/usermanual/reference/class_binconfig.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="binconfig_class" xreflabel="binconfig class"> + <title>binconfig class</title> + + <para>The binconfig class is for packages that install + <command><pkg>-config</command> scripts that provide information about + the build settings for the package. It is usually provided by libraries and + then used by other packages to determine various compiler options.</para> + + <para>Since the script is used at build time it is required to be copied + into the staging area. All the actions performed by the class are appended + to the <emphasis>stage</emphasis> task.</para> + + <para>The actions performed by the binconfig class are:</para> + + <orderedlist> + <listitem> + <para>Copies the <command><x>-config</command> script from the + package into <command>${STAGING_BINDIR} </command>directory;</para> + </listitem> + + <listitem> + <para>If the package is not native then it modifies the contents of the + <command><x>-config</command> script in the staging area to ensure + that all the paths in the script refer to the staging area;</para> + </listitem> + + <listitem> + <para>If the package is native then + the<command><x>-config</command> script is renamed to + <command><x>-config-native</command> to ensure that the native and + non-native versions do not interfere with each other.</para> + </listitem> + </orderedlist> + + <para>A package is considered to be native if it also inherits the native + class.</para> + + <para>The class will search in source directory, <command>${S}</command>, + and all it's subdirectories, for files that end in + <command>-config</command> and process them as described above. All that is + required to use the class is the addition of binconfig in an inherit + statement:</para> + + <para><screen>inherit autotools binconfig</screen></para> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/class_distutils.xml b/docs/usermanual/reference/class_distutils.xml new file mode 100644 index 0000000000..ddc9c721ab --- /dev/null +++ b/docs/usermanual/reference/class_distutils.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="distutils_class" xreflabel="distutils class"> + <title>distutils class</title> + + <para>Distutils is a standard python system for building and installing + modules. The <emphasis>distutils</emphasis> class is used to automate the + building of python modules that use the distutils system.</para> + + <para>Any python package that requires the standard python commands to build + and install is using the distutils system and should be able to use this + class:<screen>python setup.py build +python setup.py install</screen></para> + + <para>The <emphasis>distutils</emphasis> class will perform the build and + install actions on the <command>setup.py</command> provided by the package, + as required for building distutils packages, including setting all the + required parameters for cross compiling. It willl also perform the following + actions:</para> + + <orderedlist> + <listitem> + <para>Adds python-native to <command>DEPENDS</command> to ensure that + python is built and installed on the build host. This also ensure that + the version of python that is used during package creation matches the + version of python that will be installed on the target.</para> + </listitem> + + <listitem> + <para>Adds python-core to <command>RDEPENDS</command> to ensure that the + python-core is installed when this module is installed. Note that you + need to manually add any other python module dependencies to + <command>RDEPENDS</command>.</para> + </listitem> + </orderedlist> + + <para>The following example from the <emphasis>moin</emphasis> recipe shows + how simple this can make a python package:<screen>DESCRIPTION = "A full fledged WikiWiki system written in Python" +LICENSE = "GPL" +SECTION = "base" +PRIORITY = "optional" +MAINTAINER = "Your name <yname@example.com>" +PR = "r1" + +SRC_URI = "${SOURCEFORGE_MIRROR}/moin/moin-${PV}.tar.gz" + +inherit distutils</screen>The header, source location and the inherit are all + that is required.</para> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/class_image.xml b/docs/usermanual/reference/class_image.xml new file mode 100644 index 0000000000..b591e9aae2 --- /dev/null +++ b/docs/usermanual/reference/class_image.xml @@ -0,0 +1,358 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="image_class" xreflabel="image class"> + <title>image class</title> + + <para>The image class is used to generate filesystem images containing a + root filesystem, as generated by the rootfs class for the package type, such + as <xref linkend="rootfs_ipkg_class" />, for use on the target device. This + could be a <emphasis>jffs2</emphasis> image which is to be written directly + into the flash on the target device for example. In addition this class also + configures the ipkg feeds (where to get updates from) and is able to + generate multiple different image types.</para> + + <para>Summary of the actions performed by the + <emphasis>image_ipkg</emphasis> class:</para> + + <orderedlist> + <listitem> + <para>Inherits the rootfs class for the appropriate package type, + typically <xref linkend="rootfs_ipkg_class" />, in order to bring in the + functionality required to generate a root filesystem image. The root + filesystem image is generate from a set of of packages (typically .ipkg + packages), and then the required images are generated using the contents + of the root filesystem;</para> + </listitem> + + <listitem> + <para>Sets <command>BUILD_ALL_DEPS = "1"</command> to force the + dependency system to build all packages that are listed in the + <command>RDEPENDS</command> and/or <command>RRECOMENDS</command> of the + packages to be installed;</para> + </listitem> + + <listitem> + <para>Determines the name of the image device tables or table + (<command>IMAGE_DEVICE_TABLES/IMAGE_DEVICE_TABLE</command>) which will + be used to describe the device nodes to create in + <command>/dev</command> directory in the root filesystem;</para> + </listitem> + + <listitem> + <para>Erases the contents of any existing root filesystem image, + <command>${IMAGE_ROOTFS}</command>;</para> + </listitem> + + <listitem> + <para>If devfs is not being used then the <command>/dev</command> + directory, <command>${IMAGE_ROOTFS}/dev</command>, will be created and + then populated with the device nodes described by the image device table + or tables (using "<command>makedevs -r ${IMAGE_ROOTFS} -D + <table></command>" for each device table);</para> + </listitem> + + <listitem> + <para>Calls into <xref linkend="rootfs_ipkg_class" /> to install all of + the required packages into the root filesystem;</para> + </listitem> + + <listitem> + <para>Configures the ipkg feed information in the root filesystem + (using <command>FEED_URIS</command> and <command>FEED_DEPLOYDIR_BASE_URI</command>);</para> + </listitem> + + <listitem> + <para>Runs any image pre-processing commands as specified via + <command>${IMAGE_PREPROCESS_COMMAND}</command>;</para> + </listitem> + + <listitem> + <para>Calls <command>bbimage</command> on the root filesystem for each + required image type, as specified via + <command>${IMAGE_FSTYPES}</command>, to generate the actual filesystem + images;</para> + </listitem> + + <listitem> + <para>Runs any image post-processing commands, as specified via + <command>${IMAGE_POSTPROCESS_COMMAND}</command>.</para> + </listitem> + </orderedlist> + + <para>The following variables may be used to control some of the behaviour + of this class (remember we use <xref linkend="rootfs_ipkg_class" /> to build + the filesystem image, so look at the variables defined by that class as + well):</para> + + <variablelist> + <varlistentry> + <term>USE_DEVFS</term> + + <listitem> + <para>Indicates if the image will be using devfs, the device + filesystem, or not. If devfs is being used then no + <command>/dev</command> directory will be required in the image. Set + to <command>"1"</command> to indicate that devfs is being used. Note + that devfs has been removed from the Linux kernel in the 2.6 series + and most platforms are moving towards the use of udev as a replacement + for devfs.</para> + + <para>Default: <command>"0"</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>IMAGE_DEVICE_TABLES</term> + + <listitem> + <para>Specifies one, or more, files containing a list of the device + nodes that should be created in the <command>/dev</command> directory + of the image. Each file is searched for via the + <command>${BBPATH}</command> and therefore can be specified as a file + relative to the top of the build. Device files are processed in the + specified order. NOTE: If <command>IMAGE_DEVICE_TABLE</command> is set + then this variable is ignored.</para> + + <para>Example: <command>IMAGE_DEVICE_TABLES = + "files/device_table-minimal.txt files/device_table_add-sci.txt + device_table_add-sm.txt"</command></para> + + <para>Default: + <command>"files/device_table-minimal.txt"</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>IMAGE_DEVICE_TABLE</term> + + <listitem> + <para>Specifies the file that lists the device nodes that should be + created in the <command>/dev </command>directory of the image. This + needs to be an absolute filename and so should be specified relative + to <command>${BBPATH}</command>. Only a single device table is + supported. Use <command>IMAGE_DEVICE_TABLES</command> instead if you + want to use multiple device tables.</para> + + <para>Default: <command>""</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>IMAGE_PREPROCESS_COMMAND</term> + + <listitem> + <para>Additional commands to run prior to processing the image. Note + that these command run within the same <xref linkend="fakeroot" /> + instance as the rest of this class.</para> + + <para>Default: <command>""</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>IMAGE_POSTPROCESS_COMMAND</term> + + <listitem> + <para>Additional commands to run after processing the image. Note that + these command run within the same <xref linkend="fakeroot" /> instance + as the rest of this class.</para> + + <para>Default: <command>""</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>IMAGE_FSTYPES</term> + + <listitem> + <para>Specifies the type of image files to create. The supported image + types, and details on modifying existing types and on creating new + types, are described in the <xref linkend="image_types" /> section. + This variable is set to a space seperated list of image types to + generate.</para> + + <para>Example: <command>"jffs2 tar.gz"</command></para> + + <para>Default: <command>"jffs2"</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FEED_URIS</term> + + <listitem> + <para>The name of the feeds to be configured in the image by default. + Each entry consists of the feed name, followed by two pound signs and + then followed by the actual feed URI.</para> + + <para>Example: <command>FEED_URIS = + "example##http://dist.example.com/ipkg-titan-glibc/"</command></para> + + <para>Default: <command>""</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FEED_DEPLOYDIR_BASE_URI</term> + + <listitem> + <para>If set, configures local testing feeds using OE package deploy dir + contents. The value is URL, corresponding to the ipk deploy dir.</para> + + <para>Example: <command>FEED_DEPLOYDIR_BASE_URI = + "http://192.168.2.200/bogofeed/"</command></para> + + <para>Default: <command>""</command></para> + </listitem> + </varlistentry> + </variablelist> + + <section> + <title>Special node handling (fakeroot)</title> + + <para>Special nodes, such as <command>/dev</command> nodes, and files with + special permissions, such as suid files, are handled via the <xref + linkend="fakeroot" /> system. This means that when you view the contents + of the root filesystem these device appear to be created + incorrectly:</para> + + <para>The <command>IMAGE_PREPROCESS_COMMAND</command> and + <command>IMAGE_POSTPROCESS_COMMAND</command> variables will be processed + within the same <xref linkend="fakeroot" /> instance as the rest of the + rest of this class.</para> + </section> + + <section> + <title>Device (/dev) nodes</title> + + <para>There are two variables that can be defined for creating device + nodes. The new method supports multiple device node tables and supports + searching for these tables via the <command>${BBPATH}</command> so that + relative file names may be used.</para> + + <para>The following example from <command>machine/titan.conf</command> + shows the use of multiple device tables:</para> + + <para><screen># Add the SCI devices to minimal /dev +IMAGE_DEVICE_TABLES = "files/device_table-minimal.txt files/device_table_add-sci.txt device_table_add-sm.txt" +</screen></para> + + <para>It uses the standard minimal device tables but adds some additional + items which are not normally needed:</para> + + <variablelist> + <varlistentry> + <term>files/device_table-minimal.txt</term> + + <listitem> + <para>This is the standard minimal set of device nodes.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>files/device_table_add-sci.txt</term> + + <listitem> + <para>This contains details for creating the + <command>/dev/SC{0,1,2}</command> nodes which are required for the + SH processors on board SCI and SCIF serial ports. On the titan + hardware the serial console is provided via one of these ports and + so we require the device node to be present.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>device_table_add-sm.txt</term> + + <listitem> + <para>This contains details for creating the + <command>/dev/sm0</command> and <command>/dev/sm0p{0,1,2}</command> + devices nodes for the block driver, and the associated partitions, + that are used to manage the on board flash on the titan + hardware.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Prior to support for multiple device tables this would have required + the creation of a titan specific device table.</para> + </section> + + <section> + <title>Image types</title> + + <para>The type of filesystem images to create are specified via the + <command>IMAGE_FSTYPES</command> variable. A full description of the + available image types, options of the images and details on creating new + image types is provided in the <xref linkend="image_types" /> + section.</para> + </section> + + <section> + <title>Package feeds</title> + + <para>"Package feed", or feed for short, is a term used by <command>ipkg</command> + package manager, commonly used in embedded systems, to name a package repository + holding packages. Structurally, a feed is a directory - local, or on HTTP of FTP server, - + holding packages and package descriptor file, named <command>Packages</command> or + <command>Packages.gz</command> if compressed. Multiple feeds are supported.</para> + + <para>OpenEmbedded has support to pre-configure feeds within generated images, + so once image is installed on a device, user can immediately install new software, + without the need to manually edit config files. There are several ways to pre-configure + feed support, described below.</para> + + <section> + <title>Method 1: Using existing feed</title> + <para>If you already have the feed(s) set up and available via specific URL, they + can be added to the image using FEED_URIS variable: +<screen>FEED_URIS = " \ + base##http://oe.example.com/releases/${DISTRO_VERSION}/feed/base \ + updates##http://oe.example.com/releases/${DISTRO_VERSION}/feed/updates"</screen> + + FEED_URIS contains list of feed descriptors, separated by spaces, per + OE conventions. Each descriptor consists of feed name and feed URL, + joined with "##". Feed name is an identifier used by ipkg to distinguish + among the feeds. It can be arbitrary, just useful to the users to understood + which feed is used for one or another action.</para> + </section> + + <section> + <title>Method 2: Using OE deploy directory as a feed (development only)</title> + <para>OE internally maintains a feed-like collection of directories to create + images from packages. This package deployment directory however has structure internal to OE + and subject to change without notice. Thus, using it as feed directly is not recommended + (distributions which ignored this recommendation are known to have their feeds broken when + OE upgraded its internal mechanisms).</para> + <para>However, using deploy directory as feed directly may be beneficial during + development and testing, as it allows developers to easily install newly built packages + without many manual actions. To facilitate this, OE offers a way to prepare feed configs + for using deploy dir as such. To start with this, you first need to configure local + HTTP server to export a package deployment directory via HTTP. + Suppose you will export it via URL "http://192.168.2.200/bogofeed" (where 192.168.2.200 is the address + which will be reachable from the device). Add the following to your local.conf: +<screen> +FEED_DEPLOYDIR_BASE_URI = "http://192.168.2.200/bogofeed" +</screen> + Now you need to setup local HTTP server to actually export that directory. For Apache it can be: +<screen> +<![CDATA[ +Alias /bogofeed ${DEPLOY_DIR} + +<Directory ${DEPLOY_DIR}> + Options Indexes FollowSymLinks + Order deny,allow + Allow from 192.168.2.0/24 +</Directory> +]]> +</screen> + Replace ${DEPLOY_DIR} with the full path of deploy directory (last components of its path will be + <command>deploy/ipk</command>).</para> + <para>Now, every image built will automatically contain feed configs + for the deploy directory (as of time of writing, deploy directory is internally structured with + per-arch subdirectories; so, there several feed configs are being generated, one for each subdirectory). + </para> + + </section> + + </section> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/class_pkgconfig.xml b/docs/usermanual/reference/class_pkgconfig.xml new file mode 100644 index 0000000000..3cb5002df5 --- /dev/null +++ b/docs/usermanual/reference/class_pkgconfig.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="pkgconfig_class" xreflabel="pkgconfig class"> + <title>pkgconfig class</title> + + <para>The pkgconfig class is for packages that install + <command><pkg>.pc</command> files. These files provide information + about the build settings for the package vwhich are then made available by + the <command>pkg-config</command> command.</para> + + <para>Since the contents of the <command>.pc</command> files are used at + build time they need to be installed into the staging area. All the actions + performed by this class are appended to the <emphasis>stage</emphasis> + task.</para> + + <para>The actions performed by the pkgconfig class are:</para> + + <orderedlist> + <listitem> + <para>Copies the <command><x>.pc</command> files into the + <command>${PKG_CONFIG_PATH}</command> directory;</para> + </listitem> + + <listitem> + <para>If the package is not native then it modifies the contents of the + <command><x>.pc</command> file in the + <command>${PKG_CONFIG_PATH}</command> area to ensure that all the paths + in the script refer to the staging area;</para> + </listitem> + </orderedlist> + + <para>A package is considered to be native if it also inherits the native + class.</para> + + <para>The class will search the source directory, <command>${S}</command>, + and all it's subdirectories, for files that end in <command>.pc</command> + (it will ignore those that end in <command>-uninstalled.pc)</command> and + process them as described above. All that is required to use the class is + the addition of pkgconfig in an inherit statement:<screen>inherit autotools pkgconfig</screen></para> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/class_rootfs_ipkg.xml b/docs/usermanual/reference/class_rootfs_ipkg.xml new file mode 100644 index 0000000000..b60adf8e70 --- /dev/null +++ b/docs/usermanual/reference/class_rootfs_ipkg.xml @@ -0,0 +1,215 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="rootfs_ipkg_class" xreflabel="rootfs_ipkg class"> + <title>rootfs_ipkg class</title> + + <para>The <emphasis>rootf_ipk</emphasis> class us used to create a root + filesystem for the target device from a set of .ipkg packages. The end + result is a directory containing all the files that need to be included in + the root filesystem of the target device.</para> + + <para>This class is normally not used directly, but instead used from the + <xref linkend="image_class" /> which creates images from a set of package + (typically <command>.ipkg</command>) files.</para> + + <para>Summary of actions performed by the <emphasis>rootfs_ipkg</emphasis> + class:</para> + + <orderedlist> + <listitem> + <para>Erase any existing root filesystem image by deleting the entire + contents of <command>${IMAGE_ROOTFS}</command>;</para> + </listitem> + + <listitem> + <para>Creates the device node directory, + <command>${IMAGE_ROOTFS}/dev</command>;</para> + </listitem> + + <listitem> + <para>Determines which packages to install in order to provide the + locales that have been requested;</para> + </listitem> + + <listitem> + <para>Configures ipkg to allow it to be used locally to install into the + root filesystem <command>${IMAGE_ROOTFS}</command>;</para> + </listitem> + + <listitem> + <para>Installs locale related .ipkg packages;</para> + </listitem> + + <listitem> + <para>Installs the list of requested <command>.ipkg</command> packages, + <command>${IPKG_INSTALL}</command>;</para> + </listitem> + + <listitem> + <para>Creates ipkg's arch.conf as + <command>${IMAGE_ROOTFS}/etc/ipkg/arch.conf</command>;</para> + </listitem> + + <listitem> + <para>Runs any preinst and postinst scripts that were specified by the + installed .ipkg packages;</para> + </listitem> + + <listitem> + <para>Creates the system configuration directory + <command>${IMAGE_ROOTFS}/${sysconfdir}</command> (that is the + <command>/etc</command> directory on the target);</para> + </listitem> + + <listitem> + <para>Runs and custom post-processing commands, as described by + <command>${ROOTFS_POSTPROCESS_COMMAND}</command>;</para> + </listitem> + + <listitem> + <para>Verifies that all the ipkg's were installed correctly and reports + an error if they were not;</para> + </listitem> + + <listitem> + <para>Makes available a set of functions which may be used by callers of + the class: <command>zap_root_password</command>, + <command>create_etc_timestamp</command> and + <command>remove_init_link</command>;</para> + </listitem> + + <listitem> + <para>Adds the rootfs task to run after the <emphasis>install</emphasis> + task <command>"addtask rootfs before do_build and + do_install"</command>.</para> + </listitem> + </orderedlist> + + <para>The following variables may be used to control some of the behaviour + of this class:</para> + + <variablelist> + <varlistentry> + <term>IPKG_INSTALL</term> + + <listitem> + <para>The list of packages which will be installed into the root + filesystem. This needs to be set in order for this class to perform + any useful work.</para> + + <para>Default: empty</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ROOTFS_POSTPROCESS_COMMAND</term> + + <listitem> + <para>Defines additional commands to run after processing of the root + filesystem. Could be used to change roots password, remove parts of + the install kernel such as the <command>zImage</command> kernel image + or to edit the ipkg configuration for example.</para> + + <para>Default: empty</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>PACKAGE_ARCH</term> + + <listitem> + <para>Defines the list of architectures that are support by the target + platform. This is used to configure the arch settings for ipkg on the + target system.</para> + + <para>Default: <command>"all any noarch ${TARGET_ARCH} + ${PACKAGE_EXTRA_ARCHS} ${MACHINE}"</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>IMAGE_LINGUAS</term> + + <listitem> + <para>Specifies which locales should be installed. This is often set + to <command>""</command> to indicate that no locales will be + installed.</para> + + <para>Default: <command>"de-de fr-fr en-gb"</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>EXTRA_IMAGEDEPENDS</term> + + <listitem> + <para>A list of dependencies, this is appended to + <command>DEPENDS</command>. This is typically used to ensure that any + commands that are called by + <command>ROOTFS_POSTPROCESS_COMMAND</command> are actually built by + the system prior to being called.</para> + + <para>Default: empty</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>BUILDNAME</term> + + <listitem> + <para>The name of the build. This is either set by the distro + configuration (for released versions) or set to a date stamp which is + autogenerated by bitbake.</para> + + <para>Default: <command>'date +%Y%m%d%H%M'</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>IMAGE_ROOTFS</term> + + <listitem> + <para>The path to the root of the filesystem image. You can use this + when you need to explicitly refer to the root filesystem + directory.</para> + + <para>Default: <command>IMAGE_ROOTFS = + "${TMPDIR}/rootfs"</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>DEPLOY_DIR</term> + + <listitem> + <para>The base deploy dir. Used to find the directory containing the + ipkg files.</para> + + <para>Default: <command>DEPLOY_DIR = + "${TMPDIR}/deploy"</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>DEPLOY_DIR_IPK</term> + + <listitem> + <para>The directory in which to search for the ipkg files that are to + be installed in the root filesystem.</para> + + <para>Default: <command>DEPLOY_DIR_IPK = + "${DEPLOY_DIR}/ipk"</command></para> + </listitem> + </varlistentry> + </variablelist> + + <para>Note that the entire process is run under the control of <xref + linkend="fakeroot" /> in order to handle device files, uids and gids. The + <command>ROOTFS_POSTPROCESS_COMMAND</command> is useful due to the fact that + it runs within the same <xref linkend="fakeroot" /> instance as the rest of + this class.</para> + + <para>The class also provides a function <command>real_do_rootfs</command> + which is executed without <xref linkend="fakeroot" /> and therefore can be + used from other classes, such as <xref linkend="image_class" />, that + are already running under the control of <xref linkend="fakeroot" />.</para> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/class_siteinfo.xml b/docs/usermanual/reference/class_siteinfo.xml new file mode 100644 index 0000000000..4d66e85e7c --- /dev/null +++ b/docs/usermanual/reference/class_siteinfo.xml @@ -0,0 +1,180 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="siteinfo_class" xreflabel="siteinfo class"> + <title>siteinfo class</title> + + <para>The siteinfo class provides information for a target with a particular + emphasis on determining the names of the site files to be passed to + autoconf, as described in the <xref linkend="autotools_class" />. Full site + information for your target can be determined by looking at the table in the + class implementation found in the + <command>classes/siteinfo.bbclass</command> file. A typical entry contains + the name of the target and a list of site information for the + target:<screen> "sh4-linux": "endian-little bit-32 common-glibc sh-common",</screen>In + the above example for sh4-linux target (that's a build for an sh4 processor + using glibc) we see that the endianess and bit-size of target are defined + and an additional set of site files that should be used are listed. These + include a common site file for glibc and a common site file for sh + processors (so sh3 and sh4 can share defines). A <command>"common"</command> + entry is automatically added to the end of each of the definitions during + processing.</para> + + <para>The class makes available three variables based on the information + provided for a target:</para> + + <variablelist> + <varlistentry> + <term>SITEINFO_ENDIANESS</term> + + <listitem> + <para>Defines the endianess of the target as either + <command>"le"</command> (little endian) or <command>"be"</command> + (big endian). The target must list either + <command>endian-little</command> or <command>endian-big</command> in + it's site information.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>SITEINFO_BITS</term> + + <listitem> + <para>Defines the bitsize of the target as either + <command>"32"</command> or <command>"64"</command>. The target must + list either <command>bit-32</command> or <command>bit-64</command> in + it's site information.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>CONFIG_SITE</term> + + <listitem> + <para>Defines the site files to be used by autoconf. This is a space + separated list of one or more site files for the target.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>A typical use for the <command>SITEINFO_ENDIANESS</command> and + <command>SITEINFO_BITS</command> variables is to provide configuration + within a recipe based on their values. The following example from the + <emphasis>openssl</emphasis> recipe showw the correct define for the + endiness of the target being passed to openssl via the compiler flags. The + define to add to the flags is set based on the value of the + <command>SITEINFO_ENDIANESS</command> variable. Note that use of the + <emphasis>base_conditional</emphasis> method (see the <xref + linkend="recipes_advanced_python" /> section) to select a value conditional + on the endianess setting:</para> + + <para><screen> # Additional flag based on target endiness (see siteinfo.bbclass) + CFLAG="${CFLAG} ${@base_conditional('SITEINFO_ENDIANESS', 'le', '-DL_ENDIAN', '-DB_ENDIAN', d)}"</screen></para> + + <section> + <title>CONFIG_SITE: The autoconf site files</title> + + <para>The autotools configuration method has support for caching the + results of tests. In the cross-compilation case it is sometimes necessary + to prime the cache with per-calculated results (since tests designed to + run on the target cannot be run when cross-compiling). These are defined + via the site file(s) for the architecture you are using and may be + specific to the package you are building.</para> + + <para>Which site files are used is determined via the + <command>CONFIG_SITE</command> definition which is calculated via the + siteinfo class. Typically the following site files will be checked for, + and used in the order found:</para> + + <variablelist> + <varlistentry> + <term>endian-(big|little)</term> + + <listitem> + <para>Either <command>endian-big</command> or + <command>endian-little</command> depending on the endianess of the + target. This site file would contain defines that only change based + on if the target is little endian or big endian.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>bit-(32|64)</term> + + <listitem> + <para>Either <command>bit-32</command> or <command>bit-64</command> + depending on the bitsize of the target. This site file would contain + defines that only change based on if the target is a 32-bit or + 64-bit cpu.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>common-(libc|uclibc)</term> + + <listitem> + <para>Either <command>common-libc</command> or + <command>common-uclibc</command> based on the C library being used + for the target. This site file would contain defines the are + specific to the C library being used.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><arch>-common</term> + + <listitem> + <para>A common site file for the target architecture. For i386, + i485, i586 and i686 this would be <command>x86-common</command>, for + sh3 and sh4 this would be <command>sh-common</command> and for + various arm targets this would be + <command>arm-common</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>common</term> + + <listitem> + <para>This is a site file which is common for all targets and + contains definitions which remain the same no matter what target is + being built.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Each of the supported site files for a target is will be checked for + in several different directories. Each time a file is found it as added to + the list of files in the <command>CONFIG_SITE</command> variable. The + following directories are checked:</para> + + <variablelist> + <varlistentry> + <term>org.openembedded.dev/packages/<packagename>/site-<version>/</term> + + <listitem> + <para>This directory is for site files which are specific to a + particular version (where version is the PV of the package) of a + package.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>org.openembedded.dev/packages/<packagename>/site/</term> + + <listitem> + <para>This directory is for site files which are specific to a + particular package, but apply to all versions of the package.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>org.openembedded.dev/site/</term> + + <listitem> + <para>This directory is for site files that are common to all + packages. Originally this was the only site file directory that was + supported.</para> + </listitem> + </varlistentry> + </variablelist> + </section> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/class_update-alternatives.xml b/docs/usermanual/reference/class_update-alternatives.xml new file mode 100644 index 0000000000..cd86e3e6ab --- /dev/null +++ b/docs/usermanual/reference/class_update-alternatives.xml @@ -0,0 +1,241 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="update-alternatives_class" xreflabel="update-alternatives class"> + <title>update-alternatives class</title> + + <para>Some commands are available from multiple sources. As an example we + have <command>/bin/sh</command> available from <emphasis>busybox</emphasis> + and from <emphasis>bash</emphasis>. The busybox version is better from a + size perspective, but limited in functionality, while the bash version is + much larger but also provides far more features. The alternatives system is + designed to handle the situation where two commands are provided by two, or + more, packages. It ensures that one of the alternatives is always the + currently selected one and ensures that there are no problems with + installing and/or removing the various alternatives.</para> + + <para>The update-alternatives class is used to register a command provided + by a package that may have an alternative implementation in a some other + package.</para> + + <para>In the following sections we'll use the <command>/bin/ping</command> + command as an example. This command is available as a basic version from + busybox and as a more advanced version from iputils.</para> + + <section> + <title>Naming of the alternative commands</title> + + <para>When supplying alternative commands the target command itself is not + installed directly by any of the available alternatives. This is to ensure + that no package will replace files that were installed by one of the other + available alternative packages. The alternatives system will create a + symlink for the target command that points to the required + alternative.</para> + + <para>For the <command>/bin/ping</command> case this means that neither + busybox nor iputils should actually install a command called + <command>/bin/ping</command>. Instead we see that the iputils recipe + installs it's version of ping as + <command>/bin/ping.iputils</command>:<screen>do_install () { + install -m 0755 -d ${D}${base_bindir} ${D}${bindir} ${D}${mandir}/man8 + # SUID root programs + install -m 4755 ping ${D}${base_bindir}/ping.${PN} + ... +}</screen></para> + + <para>If you were to look at the busybox recipe you would see that it also + doesn't install a command called <command>/bin/ping</command>, instead it + installs it's command as <command>/bin/busybox</command>.</para> + + <para>The important point to note is that neither package is installing an + actual <command>/bin/ping</command> target command.</para> + </section> + + <section> + <title>How alternatives work</title> + + <para>Before proceeding lets take a look at how alternatives are handled. + If we have a base image that includes only busybox then look at + <command>/bin/ping</command> we see that it is a symlink to + busybox:</para> + + <para><screen>root@titan:/etc# ls -l /bin/ping +lrwxrwxrwx 1 root root 7 May 3 2006 /bin/ping -> busybox</screen></para> + + <para>This is what is expected since the busybox version of ping is the + only one installed on the system. Note again that it is only a symlink and + not an actual command.</para> + + <para>If the iputils version of ping is now installed and we look at the + <command>/bin/ping</command> command again we see that it has been changed + to a symlink pointing at the iputils version of ping - + <command>/bin/ping.iptils</command>:</para> + + <para><screen>root@titan:/etc# ipkg install iputils-ping +Installing iputils-ping (20020927-r2) to root... +Downloading http://nynaeve/ipkg-titan-glibc//iputils-ping_20020927-r2_sh4.ipk +Configuring iputils-ping +update-alternatives: Linking //bin/ping to ping.iputils +root@titan:/etc# ls -l /bin/ping +lrwxrwxrwx 1 root root 12 May 13 2006 /bin/ping -> ping.iputils</screen></para> + + <para>The iputils version is considered to be the more fully featured + version of ping and is therefore the default when both versions are + installed.</para> + + <para>What happens if the iputils-ping package is removed now? The symlink + should be changed to point back at the busybox version:</para> + + <para><screen>root@titan:/etc# ipkg remove iputils-ping +Removing package iputils-ping from root... +update-alternatives: Linking //bin/ping to busybox +root@titan:/etc# ls -l /bin/ping +lrwxrwxrwx 1 root root 7 May 13 2006 /bin/ping -> busybox</screen></para> + + <para>This simple example shows that the alternatives system is taking + care of ensuring the symlink is pointing to the correct version of the + command without any special interaction from the end users.</para> + </section> + + <section> + <title>The update-alternatives command</title> + + <para>Available alternatives need to be registered with the alternatives + system. This is handled by the <command>update-alternatives</command> + command. The help from the command shows it's usage options:<screen>root@titan:/etc# update-alternatives --help +update-alternatives: help: + +Usage: update-alternatives --install <link> <name> <path> <priority> + update-alternatives --remove <name> <path> + update-alternatives --help +<link> is the link pointing to the provided path (ie. /usr/bin/foo). +<name> is the name in /usr/lib/ipkg/alternatives/alternatives (ie. foo) +<path> is the name referred to (ie. /usr/bin/foo-extra-spiffy) +<priority> is an integer; options with higher numbers are chosen. +</screen></para> + + <para>During postinst the update-alternatives command needs to be called + with the install option and during postrm it needs to be called with the + remove option.</para> + + <para>The iputils recipe actual codes this directly (rather than using the + class) so we can see an example of the command being called:<screen>pkg_postinst_${PN}-ping () { + update-alternatives --install ${base_bindir}/ping ping ping.${PN} 100 +} +pkg_prerm_${PN}-ping () { + update-alternatives --remove ping ping.${PN} +}</screen></para> + + <para>In both cases the name that the alternatives are registered against, + <command>"ping"</command>, is passed in and the path to the iputils + version of the command, <command>"ping.${PN}"</command>. For the install + case the actual command name (where the symlink will be made from) and a + priority value are also supplied.</para> + </section> + + <section> + <title>Priority of the alternatives</title> + + <para>So why did the alternatives system prefer the iputils version of + ping over the busybox version? It's because of the relative priorities of + the available alternatives. When iputils calls update-alternatives the + last parameter passed is a priority:<screen> update-alternatives --install ${base_bindir}/ping ping ping.${PN} 100</screen></para> + + <para>So iputils is specifying a priority of 100 and if you look at + busybox you'll see it specifies a priority of 50 for ping. The alternative + with the highest priority value is the one that update-alternatives will + select as the version to actual use. In this particular situation the + authors have selected a higher priority for iputils since it is the more + capable version of ping and would not normally be installed unless + explicitly requested.</para> + </section> + + <section> + <title>Tracking of the installed alternatives</title> + + <para>You can actually see which alternatives are available and what their + priority is on a target system. Here we have an example in which both + busybox and iptuils-ping packages are installed: <screen>root@titan:/etc# cat /usr/lib/ipkg/alternatives/ping +/bin/ping +busybox 50 +ping.iputils 100</screen>If we remove iputils-ping, then we see that + alternatives file is updated to reflect this: <screen>root@titan:/etc# cat /usr/lib/ipkg/alternatives/ping +/bin/ping +busybox 50 +root@titan:/etc#</screen></para> + + <para>The file lists the command first, and then each of the available + alternatives and their relative priorities.</para> + </section> + + <section> + <title>Using the update-alternatives class</title> + + <para>Neither busybox nor iputils actually use the update-alternatives + class - they call the update-alternatives functions directly. They need to + call the command directly since they need to register multiple + alternatives and the class does not support this. The class can only be + used when you have only a single alternative to register.</para> + + <para>To use the class you need to inherent update-alternatives and then + define the name, path, link and priority as show in the following example + from the jamvm recipe:</para> + + <para><screen>inherit autotools update-alternatives + +ALTERNATIVE_NAME = "java" +ALTERNATIVE_PATH = "${bindir}/jamvm" +ALTERNATIVE_LINK = "${bindir}/java" +ALTERNATIVE_PRIORITY = "10" +</screen></para> + + <para>where the variables to be specified are:</para> + + <variablelist> + <varlistentry> + <term>ALTERNATIVE_NAME [Required]</term> + + <listitem> + <para>The name that the alternative is registered against and needs + to be the same for all alternatives registering this command.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ALTERNATIVE_PATH [Required]</term> + + <listitem> + <para>The path of the installed alternative. (This was iputils.ping + in the example used previously).</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ALTERNATIVE_LINK [Optional]</term> + + <listitem> + <para>The name of the actual command. This is what the symlink will + be called and is the actual command that the use runs. The default + value is: <command>"${bindir}/${ALTERNATIVE_NAME}"</command></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ALTERNATIVE_PRIORITY [Optional]</term> + + <listitem> + <para>The priority of this alternative. The alternative with the + highest valued priority will be selected as the default. The default + value is: <command>"10"</command>.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>The actual postinst and postrm commands that are registered by the + class are:<screen>update_alternatives_postinst() { + update-alternatives --install ${ALTERNATIVE_LINK} ${ALTERNATIVE_NAME} ${ALTERNATIVE_PATH} ${ALTERNATIVE_PRIORITY} +} + +update_alternatives_postrm() { + update-alternatives --remove ${ALTERNATIVE_NAME} ${ALTERNATIVE_PATH} +}</screen></para> + </section> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/class_update-rc.d.xml b/docs/usermanual/reference/class_update-rc.d.xml new file mode 100644 index 0000000000..2da9b0bf86 --- /dev/null +++ b/docs/usermanual/reference/class_update-rc.d.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="update-rc-d_class" xreflabel="update-rc.d class"> + <title>update-rc.d class</title> + + <para>Services which need to be started during boot need to be registered + using the update-rc.d command. These services are required to have an init + script which is installed into <command>/etc/init.d</command> that can be + used to start and stop the service.</para> + + <para>The following examples show a service being manually stopped and + started using it's init script:<screen>root@titan:/etc# /etc/init.d/syslog stop +Stopping syslogd/klogd: stopped syslogd (pid 1551). +stopped klogd (pid 1553). +done +root@titan:/etc# /etc/init.d/syslog start +Starting syslogd/klogd: done +root@titan:/etc#</screen>The update-rc.d class takes care of the following + automatically:</para> + + <orderedlist> + <listitem> + <para>Registers the service with the system during postinst so it will + be automatically started on boot;</para> + </listitem> + + <listitem> + <para>Stops the service during prerm so it will no longer be running + after being removed;</para> + </listitem> + + <listitem> + <para>Unregisters the service during prerm so there will be no attempts + to start the removed service during boot;</para> + </listitem> + + <listitem> + <para>Adds a build and run time dependency on the update-rc.d package + which it uses to register and unregister the services.</para> + </listitem> + </orderedlist> + + <para>Usage is very simple, as shown by this example from dropbear:<screen>INITSCRIPT_NAME = "dropbear" +INITSCRIPT_PARAMS = "defaults 10" + +inherit autotools update-rc.d</screen></para> + + <para>where the variables are:</para> + + <variablelist> + <varlistentry> + <term>INITSCRIPT_NAME</term> + + <listitem> + <para>The name of the init script, which the package will have + installed into /etc/init.d</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>INITSCRIPT_PARAMS</term> + + <listitem> + <para>The parameters to pass to the update-rc.d call during + installation. Typically this will be the work default followed by + either single number or a pair of numbers representing the start/stop + sequence number (both are set to the same if only one number is + supplied.)</para> + </listitem> + </varlistentry> + </variablelist> + + <para>The help from update-rc.d shows show the required parameters:<screen>root@titan:/etc# update-rc.d -h +usage: update-rc.d [-n] [-f] [-r <root>] <basename> remove + update-rc.d [-n] [-r <root>] [-s] <basename> defaults [NN | sNN kNN] + update-rc.d [-n] [-r <root>] [-s] <basename> start|stop NN runlvl [runlvl] [...] . + -n: not really + -f: force + -r: alternate root path (default is /) + -s: invoke start methods if appropriate to current runlevel +root@titan:/etc#</screen>The start and stop sequence numbers need to ensure + that the the service is started at the appropriate time relative to other + services, such as waiting for any service that it depends on before starting + (networking for example). Unless the service is a system or security related + service it's better to be started as late as possible.</para> + + <section> + <title>Multiple update-rc.d packages</title> + + <para>Defining multiple init scripts within the one recipe is also + supported. Note that each init script must be in it's own package. The + following example is from the quagga recipe:<screen># Main init script starts all deamons +# Seperate init script for watchquagga +INITSCRIPT_PACKAGES = "${PN} ${PN}-watchquagga" +INITSCRIPT_NAME_${PN} = "quagga" +INITSCRIPT_PARAMS_${PN} = "defaults 15 85" +INITSCRIPT_NAME_${PN}-watchquagga = "watchquagga" +INITSCRIPT_PARAMS_${PN}-watchquagga = "defaults 90 10" + +inherit autotools update-rc.d</screen> The variables that need to be declared + are:</para> + + <variablelist> + <varlistentry> + <term>INITSCRIPT_PACKAGES</term> + + <listitem> + <para>The names of each package which includes an init + script.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>INITSCRIPT_NAME_x</term> + + <listitem> + <para>The same meaning as INITSCRIPT_NAME, but for the package x. + This would be repeated for each package that includes an init + script.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>INITSCRIPT_PARAMS_x</term> + + <listitem> + <para>The same meaning as INITSCRIPT_PARAMS, but for the package x. + This would be repeated for each package that includes an init + script.</para> + </listitem> + </varlistentry> + </variablelist> + </section> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/dirs_install.xml b/docs/usermanual/reference/dirs_install.xml new file mode 100644 index 0000000000..75f85ac930 --- /dev/null +++ b/docs/usermanual/reference/dirs_install.xml @@ -0,0 +1,198 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="directories_installation" xreflabel="Installation directories"> + <title>Directories: Installation variables</title> + + <para>The following table provides a list of the variables that are used to + control the directories into which files are installed.</para> + + <para>These variables can be used directly by the recipe to refer to paths + that will be used after the package is installed. For example, when specify + the location of configuration files you need to specify the location on the + target as show in the following example from quagga:<screen># Indicate that the default files are configuration files +CONFFILES_${PN} = "${sysconfdir}/default/quagga" +CONFFILES_${PN}-watchquagga = "${sysconfdir}/default/watchquagga"</screen></para> + + <para>When using these variables to actually install the components of a + package from within a bitbake recipe they should used relative to the + destination directory, <emphasis role="bold">D</emphasis>. The following + example from the quagga recipe shows some addition files being manually + installed from within the recipe itself:<screen>do_install () { + # Install init script and default settings + install -m 0755 -d ${D}${sysconfdir}/default ${D}${sysconfdir}/init.d ${D}${sysconfdir}/quagga + install -m 0644 ${WORKDIR}/quagga.default ${D}${sysconfdir}/default/quagga</screen></para> + + <informaltable> + <tgroup cols="3"> + <thead> + <row> + <entry>Variable name</entry> + + <entry>Definition</entry> + + <entry>Typical value</entry> + </row> + </thead> + + <tbody> + <row> + <entry>prefix</entry> + + <entry>/usr</entry> + + <entry>/usr</entry> + </row> + + <row> + <entry>base_prefix</entry> + + <entry align="right"><emphasis>(empty)</emphasis></entry> + + <entry align="right"><emphasis>(empty)</emphasis></entry> + </row> + + <row> + <entry>exec_prefix</entry> + + <entry>${base_prefix}</entry> + + <entry align="right"><emphasis>(empty)</emphasis></entry> + </row> + + <row> + <entry>base_bindir</entry> + + <entry>${base_prefix}/bin</entry> + + <entry>/bin</entry> + </row> + + <row> + <entry>base_sbindir</entry> + + <entry>${base_prefix}/sbin</entry> + + <entry>/sbin</entry> + </row> + + <row> + <entry>base_libdir</entry> + + <entry>${base_prefix}/lib</entry> + + <entry>/lib</entry> + </row> + + <row> + <entry>datadir</entry> + + <entry>${prefix}/share</entry> + + <entry>/usr/share</entry> + </row> + + <row> + <entry>sysconfdir</entry> + + <entry>/etc</entry> + + <entry>/etc</entry> + </row> + + <row> + <entry>localstatedir</entry> + + <entry>/var</entry> + + <entry>/var</entry> + </row> + + <row> + <entry>infodir</entry> + + <entry>${datadir}/info</entry> + + <entry>/usr/share/info</entry> + </row> + + <row> + <entry>mandir</entry> + + <entry>${datadir}/man</entry> + + <entry>/usr/share/man</entry> + </row> + + <row> + <entry>docdir</entry> + + <entry>${datadir}/doc</entry> + + <entry>/usr/share/doc</entry> + </row> + + <row> + <entry>servicedir</entry> + + <entry>/srv</entry> + + <entry>/srv</entry> + </row> + + <row> + <entry>bindir</entry> + + <entry>${exec_prefix}/bin</entry> + + <entry>/usr/bin</entry> + </row> + + <row> + <entry>sbindir</entry> + + <entry>${exec_prefix}/sbin</entry> + + <entry>/usr/sbin</entry> + </row> + + <row> + <entry>libexecdir</entry> + + <entry>${exec_prefix}/libexec</entry> + + <entry>/usr/libexec</entry> + </row> + + <row> + <entry>libdir</entry> + + <entry>${exec_prefix}/lib</entry> + + <entry>/usr/lib</entry> + </row> + + <row> + <entry>includedir</entry> + + <entry>${exec_prefix}/include</entry> + + <entry>/usr/include</entry> + </row> + + <row> + <entry>palmtopdir</entry> + <entry>${libdir}/opie</entry> + <entry>/usr/lib/opie</entry> + </row> + + <row> + <entry>palmqtdir</entry> + <entry>${palmtopdir}</entry> + <entry>/usr/lib/opie</entry> + </row> + + </tbody> + </tgroup> + </informaltable> + + <para></para> +</section> diff --git a/docs/usermanual/reference/dirs_staging.xml b/docs/usermanual/reference/dirs_staging.xml new file mode 100644 index 0000000000..25f3685aad --- /dev/null +++ b/docs/usermanual/reference/dirs_staging.xml @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="directories_staging" xreflabel="Staging directories"> + <title>Directories: Staging variables</title> + + <para>The following table provides a list of the variables that are used to + control the directories into which files are staged.</para> + + <para>Staging is used for headers, libraries and binaries that are generated + by packages and are to be used in the generation of other packages. For + example the libpcre recipe needs to make the include files and libraries for + the target available on the host for other applications that depend on + libpcre. So in addition to packaging these files up for use in the binary + package they are need to be installed in the staging are for use by other + packages.</para> + + <para>There are two common situations in which you will need to directly + refer to the staging directories:</para> + + <orderedlist> + <listitem> + <para>To specify where headers and libraries are to be found for + libraries that your package depends on. In some cases these will be + found automatically due to the default compiler settings used by OE, but + in other cases you will need to explicitly tell your package to look in + the staging area. This is more commonly needed with autoconf based + packages that check for the presence of a specific package during the + <emphasis>configure</emphasis> task.</para> + </listitem> + + <listitem> + <para>In the <emphasis>stage</emphasis> task for libraries to specify + where to install the headers and libraries.</para> + </listitem> + </orderedlist> + + <para>The following example from libpcre shows the installation of the + libraries and headers from the package into the staging area. Note the use + of the <emphasis>oe_libinstall</emphasis> helper function for installation + of the libraries:<screen>do_stage () { + oe_libinstall -a -so libpcre ${STAGING_LIBDIR} + oe_libinstall -a -so libpcreposix ${STAGING_LIBDIR} + install -m 0644 pcre.h ${STAGING_INCDIR}/ + install -m 0644 pcreposix.h ${STAGING_INCDIR}/ +}</screen></para> + + <para>The following example from the flac recipe shows the location of the + ogg libraries and included before explicitly passed to the configured script + via EXTRA_OECONF so that it will correctly find ogg and enable support for + it:<screen>EXTRA_OECONF = "--disable-oggtest --disable-id3libtest \ + --with-ogg-libraries=${STAGING_LIBDIR} \ + --with-ogg-includes=${STAGING_INCDIR} \ + --without-xmms-prefix \ + --without-xmms-exec-prefix \ + --without-libiconv-prefix \ + --without-id3lib"</screen>The following table lists the available + variables for referring to the staging area:</para> + + <informaltable> + <tgroup cols="2"> + <colspec colnum="0" colwidth="1*" /> + + <colspec colnum="1" colwidth="1*" /> + + <thead> + <row> + <entry>Directory</entry> + + <entry>Definition</entry> + </row> + </thead> + + <tbody> + <row> + <entry>STAGING_DIR</entry> + + <entry>${TMPDIR}/staging</entry> + </row> + + <row> + <entry>STAGING_BINDIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}/bin</entry> + </row> + + <row> + <entry>STAGING_BINDIR_CROSS</entry> + + <entry>${STAGING_DIR}/${BUILD_SYS}/bin/${HOST_SYS}</entry> + </row> + + <row> + <entry>STAGING_BINDIR_NATIVE</entry> + + <entry>${STAGING_DIR}/${BUILD_SYS}/bin</entry> + </row> + + <row> + <entry>STAGING_LIBDIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}/lib</entry> + </row> + + <row> + <entry>STAGING_INCDIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}/include</entry> + </row> + + <row> + <entry>STAGING_DATADIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}/share</entry> + </row> + + <row> + <entry>STAGING_LOADER_DIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}/loader</entry> + </row> + + <row> + <entry>STAGING_FIRMWARE_DIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}/firmware</entry> + </row> + + <row> + <entry>STAGING_PYDIR</entry> + + <entry>${STAGING_DIR}/lib/python2.4</entry> + </row> + + <row> + <entry>STAGING_KERNEL_DIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}/kernel</entry> + </row> + + <row> + <entry>PKG_CONFIG_PATH</entry> + + <entry>${STAGING_LIBDIR}/pkgconfig</entry> + </row> + + <row> + <entry>QTDIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}/qt2</entry> + </row> + + <row> + <entry>QPEDIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}</entry> + </row> + + <row> + <entry>OPIEDIR</entry> + + <entry>${STAGING_DIR}/${HOST_SYS}</entry> + </row> + </tbody> + </tgroup> + </informaltable> + + <para></para> + + <para></para> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/fakeroot.xml b/docs/usermanual/reference/fakeroot.xml new file mode 100644 index 0000000000..5eb6a48eb0 --- /dev/null +++ b/docs/usermanual/reference/fakeroot.xml @@ -0,0 +1,186 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="fakeroot" xreflabel="fakeroot"> + <title>fakeroot (device node handling)</title> + + <para>The fakeroot program is designed to allow non-root users to perform + actions that would normally require root privileges as part of the package + generation process. It is used by the <xref linkend="rootfs_ipkg_class" /> + for root filesystem creation and by the <xref linkend="image_class" /> + for the creation of filesystem images. Some recipes also use fakeroot to + assist with parts of the package installation (usually) or building where + root privligeses are expected by the package.</para> + + <para>In particular fakeroot deals with:</para> + + <itemizedlist> + <listitem> + <para>Device nodes; and</para> + </listitem> + + <listitem> + <para>Ownership and group (uid & gid) management.</para> + </listitem> + </itemizedlist> + + <section> + <title>How fakeroot works</title> + + <para>First of all we'll look at an example of how the fakeroot process + works when used manually.</para> + + <para>If we attempt to create a device node as a normal non-root user then + the command will fail, telling is that we do not have permission to create + device nodes:<screen>~%> mknod hdc b 22 0 +mknod: `hdc': Operation not permitted</screen>Yet the <xref + linkend="image_class" /> is able to create device nodes and include + them in the final images, all without the need to have root + privileges.</para> + + <para>Let's try and create that node again, this time we'll run the + commands from within a fakeroot process:<screen>~%> ./tmp/staging/x86_64-linux/bin/fakeroot +~#> mknod hdc b 22 0 +~#> ls -l hdc +brw------- 1 root root 22, 0 Aug 18 13:20 hdc +~#></screen>So it looks like we have successfully managed to create a + device node, even though we did not have to give a password for the root + user. In reality this device node still doesn't exist, it just looks like + it exits. Fakeroot is lying to the shell process and telling it that + <emphasis>"yes, this file exists and these are it's + properties"</emphasis>. We'll talk more about how fakeroot actually works + in a minute.</para> + + <para>In this case <command>hdc</command> is the cd-rom drive, so let's + try and actually mount the cd-rom:<screen>~#> mkdir disk +~#> mount hdc disk +ERROR: ld.so: object 'libfakeroot.so.0' from LD_PRELOAD cannot be preloaded: ignored. +mount: only root can do that +~#></screen>So even though it appears we have root permissions, and that we + created a device node, you see that the system gives an error about + libfakeroot and about not being able to run mount because we are not + root.</para> + + <para>If we exit the fakeroot process and then look at the device node + this is what we see:<screen>~#> exit +~%> ls -l hdc +brw------- 1 user user 22, 0 Aug 18 13:20 hdc +~#></screen></para> + + <para>Note that it isn't a device node at all, just an empty file owned by + the current user!</para> + + <para>So what exactly is fakeroot doing? It's using + <command>LD_PRELOAD</command> to load a shared library into program which + replaces calls into libc, such as open and stat, and then returns + information to make it look like certain commands succeeded without + actually performing those commands. So when creating a device node + fakeroot will:</para> + + <orderedlist> + <listitem> + <para>Intercept the mknod system call and instead of creating a device + node it'll just create an empty file, owned by the user who run + fakeroot;</para> + </listitem> + + <listitem> + <para>It remembers the fact that mknod was called by root and it + remembers the properties of the device node;</para> + </listitem> + + <listitem> + <para>When a program, such as ls, calls stat on the file fakeroot + remembers that it was device node, owned by root, and modifies that + stat information to return this to ls. So ls sees a device node even + though one doesn't exist.</para> + </listitem> + </orderedlist> + + <para>When we tried to run mount we received the error <command>"ERROR: + ld.so: object 'libfakeroot.so.0' from LD_PRELOAD cannot be preloaded: + ignored."</command>. This is due to the fact that mount is an suid root + binary, and for security reasons <command>LD_PRELOAD</command> is disabled + on suid binaries.</para> + + <para>There are some very important points to remember when dealing with + fakeroot:</para> + + <orderedlist> + <listitem> + <para>All information regarding devices nodes, uid and gids will be + lost when fakeroot exists;</para> + </listitem> + + <listitem> + <para>None of the device nodes, uids or gids will appear on disk. + However if you tar up a directory from within fakeroot (for example), + all of these device, uids and gids will appear correctly in the tar + archive;</para> + </listitem> + + <listitem> + <para>Any suid binaries will not interact with fakeroot;</para> + </listitem> + + <listitem> + <para>Any static binaries will not interact with fakeroot;</para> + </listitem> + </orderedlist> + </section> + + <section> + <title>Root filesystem, images and fakeroot</title> + + <para>Many people have been confused by the generated root filesystem not + containing any valid device nodes. This is in fact the expected + behaviour.</para> + + <para>When you look at a generated root filesystem you'll notice that the + device nodes all appear to be incorrectly created:<screen>~%> ls -l tmp/rootfs/dev | grep ttySC +-rw-r--r-- 1 root root 0 Aug 16 13:07 ttySC0 +-rw-r--r-- 1 root root 0 Aug 16 13:07 ttySC1 +-rw-r--r-- 1 root root 0 Aug 16 13:07 ttySC2 +~%></screen>These are empty files and not device nodes at all.</para> + + <para>If we look in the image files generated from that root filesystem + then everything is actually ok:<screen>~%> tar -ztvf tmp/deploy/images/titan-titan-20060816030639.rootfs.tar.gz | grep " ./dev/ttySC" +crw-r----- root/root 204,8 2006-08-16 13:07:12 ./dev/ttySC0 +crw-r----- root/root 204,9 2006-08-16 13:07:12 ./dev/ttySC1 +crw-r----- root/root 204,10 2006-08-16 13:07:12 ./dev/ttySC2 +~%></screen>The images are created from within the same fakeroot process as + the creation of the root filesystem and therefore it correctly picks up + all of the special files and permissions from fakeroot.</para> + + <para><emphasis role="bold">NOTE: This means that you cannot use the root + filesystem in tmp/rootfs directly on your target device. You need to use + the .tar.gz image and uncompress it, as root, in order to generate a root + filesystem which is suitable for use directly on the target (or as an NFS + root).</emphasis></para> + </section> + + <section> + <title>Recipes and fakeroot</title> + + <para>Some applications require that you have root permissions to run + their installation routine, and this is another area where fakeroot can + help. In a recipe the method for a standard task, such as the + <command>do_install</command> method for the <emphasis>install</emphasis> + task:<screen>do_install() { + install -d ${D}${bindir} ${D}${sbindir} ${D}${mandir}/man8 \ + ${D}${sysconfdir}/default \ + ${D}${sysconfdir}/init.d \ + ${D}${datadir}/arpwatch + + oe_runmake install DESTDIR=${D} + oe_runmake install-man DESTDIR=${D} + ...</screen>can be modified to run within a fakeroot environment by + prefixing the method name with fakeroot:<screen><emphasis role="bold">fakeroot</emphasis> do_install() { + install -d ${D}${bindir} ${D}${sbindir} ${D}${mandir}/man8 \ + ${D}${sysconfdir}/default \ + ${D}${sysconfdir}/init.d \ + ${D}${datadir}/arpwatch + + oe_runmake install DESTDIR=${D} + oe_runmake install-man DESTDIR=${D} + ...</screen></para> + </section> +</section>
\ No newline at end of file diff --git a/docs/usermanual/reference/image_types.xml b/docs/usermanual/reference/image_types.xml new file mode 100644 index 0000000000..4ea174fd46 --- /dev/null +++ b/docs/usermanual/reference/image_types.xml @@ -0,0 +1,385 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="image_types" xreflabel="image types"> + <title>Image types</title> + + <para>One of the most commonly used outputs from a build is a filesystem + image containing the root filesystem for the target device. There are + several variables which can be used to control the type of output images and + the settings for those images, such as endianess or compression ratios. This + section details the available images and the variables that effect them. See + the <xref linkend="image_class" /> section for details on how image + generation is configured.</para> + + <para>The final root file system will consist of all of the files located in + image root filesystem directory, <command>${IMAGE_ROOTFS}</command>, which + is usually <command>tmp/rootfs</command> in the build area. One important + difference between the images and the root file system directory is that any + files which can only be created by privileged users, such as device nodes, + will not appear in the <command>${IMAGE_ROOTFS}</command> directory but they + will be present in any images that are generated. This is due to + <emphasis><xref linkend="fakeroot" /> </emphasis>system keeping track of + these special files and making them available when generating the image - + even though they do not appear in the root filesystem directory. For this + reason it is important to always create an actual image to use for testing, + even if it's just a <command>.tar</command> archive, to ensure you have the + correct device nodes and any other special files.</para> + + <section> + <title>Defining images</title> + + <para>Each supported image type is defined via a set of variables. Each + variables has the name of the image type appended to indicate the settings + for that particular image type. The behaviour of the built in image types + can be changed by modifying these variables, and new types can be created + by defining these variables for the new type.</para> + + <para>The variables that define an image type are:</para> + + <variablelist> + <varlistentry> + <term>IMAGE_CMD_<type></term> + + <listitem> + <para>Specifies the actual command that is run to generate an image + of the specified type.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>EXTRA_IMAGECMD_<type></term> + + <listitem> + <para>Used to pass additional command line arguments to the + <command>IMAGE_CMD</command> without the need to redefine the entire + image command. This is often used to pass options such as endianess + and compression rations. You need to look at the + <command>IMAGE_CMD</command> definition to determine how these + options are being used.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>IMAGE_ROOTFS_SIZE_<type></term> + + <listitem> + <para>For those image types that generate a fixed size image this + variable is used to specify the required image size.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>IMAGE_DEPENDS_<type></term> + + <listitem> + <para>Lists the packages that the <command>IMAGE_CMD</command> + depends on. As an example the jffs2 filesystem creation depends on + <command>mkfs.jffs2</command> command which is part of the mtd + utilities and therefore depends on mtd-utils-native.</para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section> + <title>Available image types</title> + + <para>The following image types are built in to OpenEmbedded:</para> + + <variablelist> + <varlistentry> + <term>jffs2</term> + + <listitem> + <para>Creates jffs2 <emphasis>"Journaling flash file system + 2"</emphasis> images. This is a read/write, compressed filesystem + for mtd (flash) devices. It is not supported for block + devices.<screen>IMAGE_CMD_jffs2 = "mkfs.jffs2 \ + -x lzo \ + --root=${IMAGE_ROOTFS} \ + --faketime \ + --output=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 \ + ${EXTRA_IMAGECMD}"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable for jffs2 + passed to <command>mkfs.jffs2</command> and is left empty by + default:<screen>EXTRA_IMAGECMD_jffs2 = ""</screen></para> + + <para>This was not always empty, prior to 2007/05/02 the + <command>EXTRA_IMAGECMD</command> variable for jffs2 was set to + enable padding, to define the endianess and to specify the block + size:<screen><emphasis>EXTRA_IMAGECMD_jffs2 = "--pad --little-endian --eraseblock=0x40000"</emphasis></screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>cramfs</term> + + <listitem> + <para>Creates cramfs <emphasis>"Compression ROM file + system"</emphasis> images. This is a read only compressed filesystem + which is used directly by decompressing files into RAM as they are + accessed. Files sizes are limited to 16MB, file system size is + limited to 256MB, only 8-bit uids and gids are supported, no hard + links are supported and no time stamps are supported.<screen>IMAGE_CMD_cramfs = "mkcramfs ${IMAGE_ROOTFS} \ + ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.cramfs \ + ${EXTRA_IMAGECMD}"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable for cramfs is + passed to <command>mkcramfs</command> and is left empty by + default:<screen>EXTRA_IMAGECMD_cramfs = ""</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ext2</term> + + <listitem> + <para>Creates an <emphasis>"Extended Filesystem 2"</emphasis> image + file. This is the standard Linux non-journaling file system.<screen>IMAGE_CMD_ext2 = "genext2fs -b ${IMAGE_ROOTFS_SIZE} \ + -d ${IMAGE_ROOTFS} \ + ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.ext2 \ + ${EXTRA_IMAGECMD}"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable for ext2 is + passed to <command>genext2fs</command> and is left empty by + default:<screen>EXTRA_IMAGECMD_ext2 = ""</screen></para> + + <para>The <command>IMAGE_ROOTS_SIZE</command> variable is used to + specify the size of the ext2 image and is set to 64k by + default:<screen>IMAGE_ROOTFS_SIZE_ext2 = "65536"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ext3</term> + + <listitem> + <para>Creates an <emphasis>"Extended Filesystem 3"</emphasis> image + file. This is the standard Linux journaling file system.<screen>IMAGE_CMD_ext3 = "genext2fs -b ${IMAGE_ROOTFS_SIZE} \ + -d ${IMAGE_ROOTFS} \ + ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.ext3 \ + ${EXTRA_IMAGECMD}; \ +tune2fs -j ${DEPLOY_DIR_IMAGE}/tmp.gz/${IMAGE_NAME}.rootfs.ext3"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable for ext3 is + passed to <command>genext2fs</command> and is left empty by + default:<screen>EXTRA_IMAGECMD_ext3 = ""</screen></para> + + <para>The <command>IMAGE_ROOTS_SIZE</command> variable is used to + specify the size of the ext3 image and is set to 64k by + default:<screen>IMAGE_ROOTFS_SIZE_ext3 = "65536"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ext2.gz</term> + + <listitem> + <para>Creates a version of the ext2 filesystem image compressed with + <command>gzip</command>.</para> + + <para><screen>IMAGE_CMD_ext2.gz = "rm -rf ${DEPLOY_DIR_IMAGE}/tmp.gz && \ +mkdir ${DEPLOY_DIR_IMAGE}/tmp.gz; \ +genext2fs -b ${IMAGE_ROOTFS_SIZE} -d ${IMAGE_ROOTFS} \ + ${DEPLOY_DIR_IMAGE}/tmp.gz/${IMAGE_NAME}.rootfs.ext2 \ + ${EXTRA_IMAGECMD}; \ +gzip -f -9 ${DEPLOY_DIR_IMAGE}/tmp.gz/${IMAGE_NAME}.rootfs.ext2; \ +mv ${DEPLOY_DIR_IMAGE}/tmp.gz/${IMAGE_NAME}.rootfs.ext2.gz \ + ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.ext2.gz; \ +rmdir ${DEPLOY_DIR_IMAGE}/tmp.gz"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable for ext2.gz is + passed to <command>genext2fs</command> and is left empty by + default:<screen>EXTRA_IMAGECMD_ext2.gz = ""</screen></para> + + <para>The <command>IMAGE_ROOTS_SIZE</command> variable is used to + specify the size of the ext2 image and is set to 64k by + default:</para> + + <para><screen>IMAGE_ROOTFS_SIZE_ext2.gz = "65536"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ext3.gz</term> + + <listitem> + <para>Creates a version of the ext3 filesystem image compressed with + <command>gzip</command>.</para> + + <para><screen>IMAGE_CMD_ext3.gz = "rm -rf ${DEPLOY_DIR_IMAGE}/tmp.gz && \ +mkdir ${DEPLOY_DIR_IMAGE}/tmp.gz; \ +genext2fs -b ${IMAGE_ROOTFS_SIZE} -d ${IMAGE_ROOTFS} \ + ${DEPLOY_DIR_IMAGE}/tmp.gz/${IMAGE_NAME}.rootfs.ext3 \ + ${EXTRA_IMAGECMD}; \ +tune2fs -j ${DEPLOY_DIR_IMAGE}/tmp.gz/${IMAGE_NAME}.rootfs.ext3; \ +gzip -f -9 ${DEPLOY_DIR_IMAGE}/tmp.gz/${IMAGE_NAME}.rootfs.ext3; \ +mv ${DEPLOY_DIR_IMAGE}/tmp.gz/${IMAGE_NAME}.rootfs.ext3.gz \ + ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.ext3.gz; \ +rmdir ${DEPLOY_DIR_IMAGE}/tmp.gz"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable for ext3.gz is + passed to <command>genext2fs</command> and is left empty by + default:<screen>EXTRA_IMAGECMD_ext3.gz = ""</screen></para> + + <para>The <command>IMAGE_ROOTS_SIZE</command> variable is used to + specify the size of the ext2 image and is set to 64k by + default:</para> + + <para><screen>IMAGE_ROOTFS_SIZE_ext3.gz = "65536"</screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>squashfs</term> + + <listitem> + <para>Creates a squashfs image. This is a read only compressed + filesystem which is used directly with files uncompressed into RAM + as they are accessed. Files and filesystems may be up to 2^64 bytes + in size, full 32-bit uids and gids are stored, it detects duplicate + files and stores only a single copy, all meta-data is compressed and + big and little endian filesystems can be mounted on any + platform.</para> + + <para>Squashfs uses gzip as its compression method.</para> + + <para><screen>IMAGE_CMD_squashfs = "mksquashfs ${IMAGE_ROOTFS} \ + ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.squashfs \ + ${EXTRA_IMAGECMD} -noappend"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable for squashfs is + passed to <command>mksquashfs</command> and is left empty by + default:<screen>EXTRA_IMAGECMD_squashfs = ""</screen></para> + + <para>This was not always empty, prior to 2007/05/02 the + <command>EXTRA_IMAGECMD</command> variable for squashfs specified + the endianess and block size of the filesystem:<screen><emphasis>EXTRA_IMAGECMD_squashfs = "-le -b 16384"</emphasis></screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>squashfs-lzma</term> + + <listitem> + <para>Creates a squashfs image using lzma compression instead of + gzip which is the standard squashfs compression type. This is a read + only compressed filesystem which is used directly with files + uncompressed into RAM as they are accessed. Files and filesystems + may be up to 2^64 bytes in size, full 32-bit uids and gids are + stored, it detects duplicate files and stores only a single copy, + all meta-data is compressed and big and little endian filesystems + can be mounted on any platform.</para> + + <para>Squashfs-lzma uses lzma as its compression method.</para> + + <para><screen>IMAGE_CMD_squashfs-lzma = "mksquashfs-lzma ${IMAGE_ROOTFS} \ + ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.squashfs \ + ${EXTRA_IMAGECMD} -noappend"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable for squashfs is + passed to <command>mksquashfs-lzma</command> and is left empty by + default:<screen>EXTRA_IMAGECMD_squashfs-lzma = ""</screen></para> + + <para>This was not always empty, prior to 2007/05/02 the + <command>EXTRA_IMAGECMD</command> variable for squashfs specified + the endianess and block size of the filesystem:<screen><emphasis>EXTRA_IMAGECMD_squashfs-lzma = "-le -b 16384"</emphasis></screen></para> + </listitem> + </varlistentry> + + <varlistentry> + <term>tar</term> + + <listitem> + <para>Creates a .tar archive.</para> + + <para><screen>IMAGE_CMD_tar = "cd ${IMAGE_ROOTFS} && \ + tar -cvf ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.tar ."</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable in not + supported for tar images.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>tar.gz</term> + + <listitem> + <para>Creates a <command>gzip</command> compressed .tar + archive.</para> + + <para><screen>IMAGE_CMD_tar.gz = "cd ${IMAGE_ROOTFS} && \ + tar -zcvf ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.tar.gz ."</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable in not + supported for .tar.gz images.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>tar.bz2</term> + + <listitem> + <para>Creates a <command>bzip2</command> compressed .tar + archive.</para> + + <para><screen>IMAGE_CMD_tar.bz2 = "cd ${IMAGE_ROOTFS} && \ + tar -jcvf ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.tar.bz2 ."</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable in not + supported for tar.bz2 images.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>cpio</term> + + <listitem> + <para>Creates a .cpio archive:<screen>IMAGE_CMD_cpio = "cd ${IMAGE_ROOTFS} && \ + (find . | cpio -o -H newc >${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.cpio)"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable in not + supported for cpio images.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>cpio.gz</term> + + <listitem> + <para>Creates a <command>gzip</command> compressed .cpio + archive.<screen>IMAGE_CMD_cpio.gz = cd ${IMAGE_ROOTFS} && \ + (find . | cpio -o -H newc | gzip -c -9 >${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.cpio.gz)"</screen></para> + + <para>The <command>EXTRA_IMAGECMD</command> variable in not + supported for cpio.gz images.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>The above built in list of image types is defined in the bitbake + configuration file: + <command>org.openembedded.dev/conf/bitbake.conf</command>.</para> + </section> + + <section> + <title>Custom image types</title> + + <para>Custom image types can be created by defining the + <command>IMAGE_CMD</command> variable, and optionally the + <command>EXTRA_IMAGECMD</command>, <command>IMAGE_ROOTFS_SIZE</command> + and <command>IMAGE_DEPENDS</command> variables, for your new image + type.</para> + + <para>An example can be found in + <command>conf/machine/wrt54.conf</command> where it defines a new image + type, <emphasis>squashfs-lzma</emphasis>, for a squashfs filesystem using + lzma compression instead of the standard gzip compression (squashfs-lzma + is now a standard type, but the example still serves to show the + concept):<screen>IMAGE_DEPENDS_squashfs-lzma = "squashfs-tools-native" +IMAGE_CMD_squashfs-lzma = "mksquashfs-lzma ${IMAGE_ROOTFS} \ + ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.squashfs-lzma \ + ${EXTRA_IMAGECMD} -noappend" +EXTRA_IMAGECMD_squashfs-lzma = "-root-owned -le"</screen></para> + </section> +</section> diff --git a/docs/usermanual/reference/var_section.xml b/docs/usermanual/reference/var_section.xml new file mode 100644 index 0000000000..96b746e56c --- /dev/null +++ b/docs/usermanual/reference/var_section.xml @@ -0,0 +1,704 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="section_variable" xreflabel="SECTION variable"> + <title>SECTION variable: Package category</title> + + <para>Sections are a means for categorising packages into related groups to + enable users to find packages easier. The <command>SECTION</command> + variable is used to declare which section a package belongs to. The most + common use of the section information is in GUI based package management + applications.</para> + + <para>The default values for the section variables are:</para> + + <itemizedlist> + <listitem> + <para><command>SECTION = "base"</command></para> + </listitem> + + <listitem> + <para><command>SECTION_${PN}-doc = "doc"</command></para> + </listitem> + + <listitem> + <para><command>SECTION_${PN}-dev = "devel"</command></para> + </listitem> + </itemizedlist> + + <para>Note that each package generated by a recipe can have it's own section + and that by default documentation and development files are seperated out to + their own sections.</para> + + <para>The table of sections show the current usage of section information. + This is a recomendation only, althought it is recomended that any additions + or modifications be discusssed via the open embedded developer mailing list + first.</para> + + <informaltable> + <tgroup cols="2"> + <colspec colwidth="1*" /> + + <colspec colwidth="3*" /> + + <tbody> + <row> + <entry>Section</entry> + + <entry>Description</entry> + </row> + + <row> + <entry>admin</entry> + + <entry></entry> + </row> + + <row> + <entry>base</entry> + + <entry>Base system files. These are applications which are expected + to be included as part of a base system and include things such as + init scripts, core utilities, standard system daemons etc.</entry> + </row> + + <row> + <entry>base/shell</entry> + + <entry>Shells such as bash, tcsh, ksh etc.</entry> + </row> + + <row> + <entry>bootloaders</entry> + + <entry>Bootloaders, which are the applications responsible for + loading the kernel from the appropriate location (disk, flash, + network, etc.) and starting it running.</entry> + </row> + + <row> + <entry>console</entry> + + <entry>Applications which run on the console. These require no GUI + related libraries or interfaces to run.</entry> + </row> + + <row> + <entry>console/editors</entry> + + <entry></entry> + </row> + + <row> + <entry>console/games</entry> + + <entry></entry> + </row> + + <row> + <entry>console/multimedia</entry> + + <entry></entry> + </row> + + <row> + <entry>console/network</entry> + + <entry></entry> + </row> + + <row> + <entry>console/scientific</entry> + + <entry></entry> + </row> + + <row> + <entry>console/telephony</entry> + + <entry></entry> + </row> + + <row> + <entry>console/tools</entry> + + <entry></entry> + </row> + + <row> + <entry>console/utils</entry> + + <entry></entry> + </row> + + <row> + <entry>devel</entry> + + <entry>Development related files. These include compilers, + libraries, headers, debuggers etc.</entry> + </row> + + <row> + <entry>devel/libs</entry> + + <entry></entry> + </row> + + <row> + <entry>devel/perl</entry> + + <entry></entry> + </row> + + <row> + <entry>devel/python</entry> + + <entry></entry> + </row> + + <row> + <entry>devel/rexx</entry> + + <entry></entry> + </row> + + <row> + <entry>devel/ruby</entry> + + <entry></entry> + </row> + + <row> + <entry>devel/scheme</entry> + + <entry></entry> + </row> + + <row> + <entry>devel/tcltk</entry> + + <entry></entry> + </row> + + <row> + <entry>doc</entry> + + <entry>Documentation, including man pages and sample configuration + files.</entry> + </row> + + <row> + <entry>e/apps</entry> + + <entry></entry> + </row> + + <row> + <entry>e/libs</entry> + + <entry></entry> + </row> + + <row> + <entry>e/utils</entry> + + <entry></entry> + </row> + + <row> + <entry>fonts</entry> + + <entry>Fonts that are not X11 or OPIE specific such as truetype + fonts.</entry> + </row> + + <row> + <entry>games</entry> + + <entry>Games.</entry> + </row> + + <row> + <entry>games/arcade</entry> + + <entry></entry> + </row> + + <row> + <entry>gpe</entry> + + <entry>GPE GUI enviroment. For the anything that provides or uses + the GPE UI. Note that development and documentation related files + should be in the appropriate devel and doc section, not under + GPE.</entry> + </row> + + <row> + <entry>gpe/applications</entry> + + <entry></entry> + </row> + + <row> + <entry>gpe/base</entry> + + <entry></entry> + </row> + + <row> + <entry>gpe/games</entry> + + <entry></entry> + </row> + + <row> + <entry>gpe/libs</entry> + + <entry>GPE runtime libraries. This does not include libraries used + for development - they should be included in the appropriate devel + section.</entry> + </row> + + <row> + <entry>gpe/multimedia</entry> + + <entry></entry> + </row> + + <row> + <entry>inputmethods</entry> + + <entry>inputmethods that are neither libs, nor solely for GPE/Opie or the console</entry> + </row> + + <row> + <entry>interpreters</entry> + + <entry></entry> + </row> + + <row> + <entry>kde</entry> + + <entry>KDE related applications.</entry> + </row> + + <row> + <entry>kde/devel</entry> + + <entry></entry> + </row> + + <row> + <entry>kernel</entry> + + <entry>Linux kernels.</entry> + </row> + + <row> + <entry>kernel/modules</entry> + + <entry>Linux kernel modules. This include out-of-tree kernel + modules.</entry> + </row> + + <row> + <entry>kernel/userland</entry> + + <entry></entry> + </row> + + <row> + <entry>libs</entry> + + <entry>Runtime libraries. This does not include libraries used for + development - they should be included in the appropriate devel + section.</entry> + </row> + + <row> + <entry>libs/inputmethods</entry> + + <entry></entry> + </row> + + <row> + <entry>libs/multimedia</entry> + + <entry></entry> + </row> + + <row> + <entry>libs/network</entry> + + <entry></entry> + </row> + + <row> + <entry>network</entry> + + <entry></entry> + </row> + + <row> + <entry>network/cms</entry> + + <entry></entry> + </row> + + <row> + <entry>network/misc</entry> + + <entry></entry> + </row> + + <row> + <entry>openmoko</entry> + + <entry>Anything related to openmoko.org</entry> + </row> + + <row> + <entry>openmoko/applications</entry> + + <entry></entry> + </row> + + <row> + <entry>openmoko/base</entry> + + <entry></entry> + </row> + + <row> + <entry>openmoko/examples</entry> + + <entry></entry> + </row> + + <row> + <entry>openmoko/libs</entry> + + <entry></entry> + </row> + + <row> + <entry>openmoko/pim</entry> + + <entry></entry> + </row> + + <row> + <entry>openmoko/tools</entry> + + <entry></entry> + </row> + + <row> + <entry>opie</entry> + + <entry>OPIE GUI enviroment. For the anything that provides or uses + the OPIE UI. Note that development and documentation related files + should be in the appropriate devel and doc section, not under + OPIE.</entry> + </row> + + <row> + <entry>opie/applets</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/applications</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/base</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/codecs</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/datebook</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/decorations</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/fontfactories</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/fonts</entry> + + <entry>OPIE specific fonts. General fonts, such as truetype fonts, + should be in the fonts section.</entry> + </row> + + <row> + <entry>opie/games</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/help</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/inputmethods</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/libs</entry> + + <entry>OPIE runtime libraries. This does not include libraries used + for development - they should be included in the appropriate devel + section.</entry> + </row> + + <row> + <entry>opie/multimedia</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/network</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/pim</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/security</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/settings</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/shell</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/styles</entry> + + <entry></entry> + </row> + + <row> + <entry>opie/today</entry> + + <entry></entry> + </row> + + <row> + <entry>utils</entry> + + <entry></entry> + </row> + + <row> + <entry>x11</entry> + + <entry>X11 GUI platform. For anything that provides or uses the X11 + UI and is not GPE. Note that development and documentation related + files should be in the appropriate devel and doc section, not under + X11.</entry> + </row> + + <row> + <entry>x11/applications</entry> + + <entry>General applications.</entry> + </row> + + <row> + <entry>x11/base</entry> + + <entry>Core X11 applications.</entry> + </row> + + <row> + <entry>x11/data</entry> + + <entry></entry> + </row> + + <row> + <entry>x11/fonts</entry> + + <entry>X11 specific fonts. General fonts, such as truetype fonts, + should be in the fonts section.</entry> + </row> + + <row> + <entry>x11/games</entry> + + <entry>Games.</entry> + </row> + + <row> + <entry>x11/gnome</entry> + + <entry>Core gnome applications.</entry> + </row> + + <row> + <entry>x11/gnome/libs</entry> + + <entry>Gnome runtime libraries. This does not include libraries used + for development - they should be included in the appropriate devel + section.</entry> + </row> + + <row> + <entry>x11/graphics</entry> + + <entry>Applications which manipulate, display, edit, print etc. + images, photos, diagrams etc.</entry> + </row> + + <row> + <entry>x11/libs</entry> + + <entry>X11 runtime libraries. This does not include libraries used + for development - they should be included in the appropriate devel + section.</entry> + </row> + + <row> + <entry>x11/multimedia</entry> + + <entry>Multimedia applications.</entry> + </row> + + <row> + <entry>x11/network</entry> + + <entry></entry> + </row> + + <row> + <entry>x11/office</entry> + + <entry>Office and productivity applications.</entry> + </row> + + <row> + <entry>x11/scientific</entry> + + <entry>Scientific applications.</entry> + </row> + + <row> + <entry>x11/utils</entry> + + <entry></entry> + </row> + + <row> + <entry>x11/wm</entry> + + <entry>Window managers.</entry> + </row> + </tbody> + </tgroup> + </informaltable> + + <para>The following tables lists some sections which may be in existing + recipes. These should not be used in new recipes and should be renamed when + updated existing recipes that use the specified sections.</para> + + <informaltable> + <tgroup cols="2"> + <colspec colwidth="1*" /> + + <colspec colwidth="3*" /> + + <tbody> + <row> + <entry>Section</entry> + + <entry>Action</entry> + </row> + + <row> + <entry>apps</entry> + + <entry>Replace with appropriate section</entry> + </row> + + <row> + <entry>gui</entry> + + <entry>Replace with appropriate section</entry> + </row> + + <row> + <entry>media-gfx</entry> + + <entry>Replace with appropriate section</entry> + </row> + + <row> + <entry>multimedia</entry> + + <entry>Replace with appropriate section</entry> + </row> + + <row> + <entry>net</entry> + + <entry>Replace with network</entry> + </row> + + <row> + <entry>unknown</entry> + + <entry>Replace with appropriate section</entry> + </row> + + <row> + <entry>x11-misc</entry> + + <entry>Replace with appropriate section</entry> + </row> + </tbody> + </tgroup> + </informaltable> + + <para></para> +</section> diff --git a/docs/usermanual/reference/var_src_uri.xml b/docs/usermanual/reference/var_src_uri.xml new file mode 100644 index 0000000000..a9a2985a70 --- /dev/null +++ b/docs/usermanual/reference/var_src_uri.xml @@ -0,0 +1,692 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section id="src_uri_variable" xreflabel="SRC_URI variable"> + <title>SRC_URI variable: Source code and patches</title> + + <para>All recipies need to contain a definition of + <command>SRC_URI</command>. It determines what files and source code is + needed and where that source code should be obtained from. This includes + patches to be applied and basic files that are shipped as part of the + meta-data for the package.</para> + + <para>A typical <command>SRC_URI</command> contains a list of URL's, patches + and files as shown in this example from quagga:<screen>SRC_URI = "http://www.quagga.net/download/quagga-${PV}.tar.gz \ + file://ospfd-no-opaque-lsa-fix.patch;patch=1 \ + file://fix-for-lib-inpath.patch;patch=1 \ + file://quagga.init \ + file://quagga.default \ + file://watchquagga.init \ + file://watchquagga.default"</screen>All source code and files will + be placed into the work directory, <command>${WORKDIR}</command>, for the + package. All patches will be placed into a <command>patches</command> + subdirectory of the package source directory, <command>${S}</command>, and + then automatically applied to the source.</para> + + <para>Before downloading from a remote URI a check will be made to see if + what is to be retrieved is already present in the download source directory, + <command>${DL_DIR}</command>, along with an associated md5 sum. If the + source is present in the downloaded sources directory and the md5 sum + matches that listed in the associated md5 sum file, then that version will + be used in preference to retrieving a new version . Any source that is + retrieved from a remote URI will be stored in the download source directory + and an appropriate md5 sum generated and stored alongside it.</para> + + <para>Each URI supports a set of additional options. These options are + tag/value pairs of the form <command>"a=b"</command> and are semi-colon + separated from each other and from the URI. The follow examples shows two + options being included, the patch and pnum options:<screen>file://ospfd-no-opaque-lsa-fix.patch;patch=1;pnum=2</screen>The + supported methods for fetching source and files are:</para> + + <variablelist> + <varlistentry> + <term>http, https, ftps</term> + + <listitem> + <para>Used to download files and source code via the specified URL. + These are fetched from the specified location using wget.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>file</term> + + <listitem> + <para>Used for files that are included locally in the meta-data. These + may be plain files, such as init scripts to be added to the final + package, or they may be patch files to be applied to other + source.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>cvs</term> + + <listitem> + <para>Used to download from a CVS repository.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>svn</term> + + <listitem> + <para>Used to download from a subversion repository.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>git</term> + + <listitem> + <para>Used to download from a git repository.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>When source code is specified as a part of <command>SRC_URI</command> + it is unpacked into the work directory, <command>${WORKDIR}</command>. The + unpacker recognises several archive and compression types and for these it + will decompress any compressed files and extract all of the files from + archives into the work directory. The supported types are:</para> + + <variablelist> + <varlistentry> + <term>.tar</term> + + <listitem> + <para>Tar archives which will be extracted with <command>"tar x + --no-same-owner -f <srcfile>"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>.tgz, .tar.gz, tar.Z</term> + + <listitem> + <para>Gzip compressed tar archives which will be extracted with + <command>"tar xz --no-same-owner -f <srcfile>"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>.tbz, .tar.bz2</term> + + <listitem> + <para>Bzip2 compressed tar archives which will be extracted with + <command>"bzip2 -dc <srcfile> | tar x --no-same-owner -f + -"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>.gz, .Z, .z</term> + + <listitem> + <para>Gzip compressed files which will be decompressed with + <command>"gzip -dc <srcfile> > + <dstfile>"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>.bz2</term> + + <listitem> + <para>Bzip2 compressed files which will be decompressed with + <command>"bzip2 -dc <srcfile> > + <dstfile>"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>.zip</term> + + <listitem> + <para>Zip archives which will be extracted with <command>"unzip -q + <srcfile>"</command>.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>The downloading of the source files occurs in the + <emphasis>fetch</emphasis> task, the unpacking and copying to the work + directory occurs in the <emphasis>unpack</emphasis> task and the applying of + patches occurs in the <emphasis>patch</emphasis> task.</para> + + <section> + <title>http/https/ftp (wget)</title> + + <para>The wget fetcher handles http, https and ftp URLs.<screen>http://www.quagga.net/download/quagga-${PV}.tar.gz</screen></para> + + <para>Supported options:</para> + + <variablelist> + <varlistentry> + <term>md5sum</term> + + <listitem> + <para>If an md5sum is provided then the downloaded files will only + be considered valid if the md5sum of the downloaded file matches the + md5sum option provided.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Related variables:</para> + + <variablelist> + <varlistentry> + <term>MIRRORS</term> + + <listitem> + <para>Mirrors define alternative locations to download source files + from. See the mirror section below for more information.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>DL_DIR</term> + + <listitem> + <para>The downloaded files will be placed in this directory with the + name exactly as supplied via the URI.</para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section> + <title>file: for patches and additional files</title> + + <para>The file URI's are used to copy files, included as part of the + package meta data, into the work directory to be used when building the + package. Typical use of the file URI's is to specify patches that be + applied to the source and to provide additional files, such as init + scripts, to be included in the final package.</para> + + <para>The following example shows the specification of a patch + file:<screen>file://ospfd-no-opaque-lsa-fix.patch;patch=1</screen></para> + + <para>Patch files are be copied to the patches subdirectory of the source + directory, <command>${S}/patches</command>, and then applied from the + source directory. The patches are searched for along the path specified + via the file path variable, <command>${FILESPATH},</command> and if not + found the directory specified by the file directory variable, + <command>${FILEDIR}</command>, is also checked.</para> + + <para>The following example shows the specification of a non-patch file. + In this case it's an init script:<screen>file://quagga.init</screen>Non-patch + files are copied to the work directory, <command>${WORKDIR}</command>. You + can access these files from within a recipe by referring to them relative + to the work directory. The following example, from the quagga recipe, + shows the above init script being included in the package by copying it + during the <emphasis>install</emphasis> task:<screen>do_install () { + # Install init script and default settings + install -m 0755 -d ${D}${sysconfdir}/default ${D}${sysconfdir}/init.d ${D}${sysconfdir}/quagga + install -m 0644 <emphasis role="bold">${WORKDIR}/quagga.init</emphasis> ${D}${sysconfdir}/init.d/quagga +...</screen></para> + + <para>Supported options:</para> + + <variablelist> + <varlistentry> + <term>patch</term> + + <listitem> + <para>Used as <command>"patch=1"</command> to define this file as a + patch file. Patch files will be copied to + <command>${S}/patches</command> and then applied to source from + within the source directory, <command>${S}</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>pnum</term> + + <listitem> + <para>By default patches are applied with the <command>"-p + 1"</command> parameter, which strips off the first directory of the + pathname in the patches. This option is used to explicitly control + the value passed to <command>"-p"</command>. The most typical use is + when the patches are relative to the source directory already and + need to be applied using <command>"-p 0"</command>, in which case + the <command>"pnum=0"</command> option is supplied.</para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section> + <title>cvs</title> + + <para>The cvs fetcher is used to retrieve files from a CVS repository. + <screen> cvs://anonymous@cvs.sourceforge.net/cvsroot/linuxsh;module=linux;date=20051111</screen>A + cvs URI will retrieve the source from a cvs repository. Note that use of + the <emphasis>date=</emphasis> to specify a checkout for specified date. + It is preferable to use either a <emphasis>date=</emphasis> or a + <emphasis>tag=</emphasis> option to select a specific date and/or tag from + cvs rather than leave the checkout floating at the head revision.</para> + + <para>Supported options:</para> + + <variablelist> + <varlistentry> + <term>module</term> + + <listitem> + <para>The name of a module to retrieve. This is a required parameter + and there is no default value.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>tag</term> + + <listitem> + <para>The name of a cvs tag to retrieve. Releases are often tagged + with a specific name to allow easy access. Either a tag or a date + can be specified, but not both.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>date</term> + + <listitem> + <para>The date to retrieve. This requests that files as of the + specified date, rather then the current code or a tagged release. If + no date or tag options are specified, then the date is set to the + current date. The date is of any form accepted by cvs with the most + common format being <command>"YYYYMMDD"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>method</term> + + <listitem> + <para>The method used to access the repository. Common options are + <command>"pserver"</command> and <command>"ext"</command> (for cvs + over rsh or ssh). The default is + <command>"pserver"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>rsh</term> + + <listitem> + <para>The rsh command to use with the <command>"ext"</command> + method. Common options are <command>"rsh"</command> or + <command>"ssh"</command>. The default is + <command>"rsh"</command>.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Related variables:<variablelist> + <varlistentry> + <term>CVS_TARBALL_STASH</term> + + <listitem> + <para>Used to specifies a location to search for pre-generated tar + archives to use instead of accessing cvs directly.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>CVSDIR</term> + + <listitem> + <para>The directory in which the cvs checkouts will be performed. + The default is <command>${DL_DIR}/cvs</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>DL_DIR</term> + + <listitem> + <para>A compressed tar archive of the retrieved files will be + placed in this directory. The archive name will be of the form: + <command>"<module>_<host>_<tag>_<date>.tar.gz"</command>. + Path separators in <command>module</command> will be replaced with + full stops.</para> + </listitem> + </varlistentry> + </variablelist></para> + </section> + + <section> + <title>svn</title> + + <para>The svn fetcher is used to retrieve files from a subversion + repository.</para> + + <para><screen> svn://svn.xiph.org/trunk;module=Tremor;rev=4573;proto=http</screen></para> + + <para>Supported options:</para> + + <variablelist> + <varlistentry> + <term>module</term> + + <listitem> + <para>The name of a module to retrieve. This is a required parameter + and there is no default value.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>rev</term> + + <listitem> + <para>The revision to retrieve. Revisions in subversion are integer + values.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>proto</term> + + <listitem> + <para>The method to use to access the repository. Common options are + <command>"svn"</command>, <command>"svn+ssh"</command>, + <command>"http"</command> and <command>"https"</command>. The + default is <command>"svn"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>rsh</term> + + <listitem> + <para>The rsh command to use with using the + <command>"svn+ssh"</command> method. Common options are + <command>"rsh"</command> or <command>"ssh"</command>. The default is + <command>"ssh"</command>.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Related variables:<variablelist> + <varlistentry> + <term>SVNDIR</term> + + <listitem> + <para>The directory in which the svn checkouts will be performed.. + The default is <command>${DL_DIR}/svn</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>DL_DIR</term> + + <listitem> + <para>A compressed tar archive of the retrieved files will be + placed in this directory. The archive name will be of the form: + <command>"<module>_<host>_<path>_<revn>_<date>.tar.gz"</command>. + Path separators in <command>path</command> and + <command>module</command> will be replaced with full stops.</para> + </listitem> + </varlistentry> + </variablelist></para> + </section> + + <section> + <title>git</title> + + <para>The git fetcher is used to retrieve files from a git repository. + <screen> SRC_URI = "git://www.denx.de/git/u-boot.git;protocol=git;tag=${TAG}"</screen></para> + + <para>Supported options:</para> + + <variablelist> + <varlistentry> + <term>tag</term> + + <listitem> + <para>The tag to retrieve. The default is + <command>"master"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>protocol</term> + + <listitem> + <para>The method to use to access the repository. Common options are + <command>"git"</command> and <command>"rsync"</command>. The default + is <command>"rsync"</command>.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Related variables</para> + + <para><variablelist> + <varlistentry> + <term>GITDIR</term> + + <listitem> + <para>The directory in which the git checkouts will be performed. + The default is <command>${DL_DIR}/git</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>DL_DIR</term> + + <listitem> + <para>A compressed tar archive of the retrieved files will be + placed in this directory. The archive name will be of the form: + <command>"git_<host><mpath>_<tag>.tar.gz"</command>. + Path separators in <command>host</command> will be replaced with + full stops.</para> + </listitem> + </varlistentry> + </variablelist></para> + </section> + + <section> + <title>Mirrors</title> + + <para>The support for mirror sites enables spreading the load over sites + and allows for downloads to occur even when one of the mirror sites are + unavailable.</para> + + <para>Default mirrors, along with their primary URL, include:</para> + + <variablelist> + <varlistentry> + <term>GNU_MIRROR</term> + + <listitem> + <para>ftp://ftp.gnu.org/gnu</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>DEBIAN_MIRROR</term> + + <listitem> + <para>ftp://ftp.debian.org/debian/pool</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>SOURCEFORGE_MIRROR</term> + + <listitem> + <para>http://heanet.dl.sourceforge.net/sourceforge</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>GPE_MIRROR</term> + + <listitem> + <para>http://handhelds.org/pub/projects/gpe/source</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>XLIBS_MIRROR</term> + + <listitem> + <para>http://xlibs.freedesktop.org/release</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>XORG_MIRROR</term> + + <listitem> + <para>http://xorg.freedesktop.org/releases</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>GNOME_MIRROR</term> + + <listitem> + <para>http://ftp.gnome.org/pub/GNOME/sources</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>FREEBSD_MIRROR</term> + + <listitem> + <para>ftp://ftp.freebsd.org/pub/FreeBSD</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>GENTOO_MIRROR</term> + + <listitem> + <para>http://distro.ibiblio.org/pub/linux/distributions/gentoo/distfiles</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>APACHE_MIRROR</term> + + <listitem> + <para>http://www.apache.org/dist</para> + </listitem> + </varlistentry> + </variablelist> + + <para>When creating new recipes this mirrors should be used when you wish + to use one of the above sites by referring to the name of the mirror in + the URI, as show in this example from flex:<screen>SRC_URI = "${SOURCEFORGE_MIRROR}/lex/flex-2.5.31.tar.bz2</screen></para> + + <para>You can manually define your mirrors if you wish to force the use of + a specific mirror by exporting the appropriate mirrors in + <command>local.conf</command> with them set to the local mirror:<screen>export GNU_MIRROR = "http://www.planetmirror.com/pub/gnu" +export DEBIAN_MIRROR = "http://mirror.optusnet.com.au/debian/pool" +export SOURCEFORGE_MIRROR = "http://optusnet.dl.sourceforge.net/sourceforge"</screen></para> + + <para>Mirrors can be extended in individual recipes via the use of + <command>MIRRORS_prepend</command> or <command>MIRRORS_append</command>. + Each entry in the list contains the mirror name on the left-hand side and + the URI of the mirror on the right-hand side. The following example from + libffi shows the addition of two URI for the + <command>"${GNU_MIRROR}/gcc/"</command> URI:<screen>MIRRORS_prepend () { + ${GNU_MIRROR}/gcc/ http://gcc.get-software.com/releases/ + ${GNU_MIRROR}/gcc/ http://mirrors.rcn.net/pub/sourceware/gcc/releases/ +}</screen></para> + </section> + + <section> + <title>Manipulating SRC_URI</title> + + <para>Sometimes it is desirable to only include patches for a specific + architecture and/or to include different files based on the architecture. + This can be done via the <command>SRC_URI_append</command> and/or + <command>SRC_URI_prepend</command> methods for adding additional URI's + based on the architecture or machine name.</para> + + <para>In this example from glibc, the patch creates a configuration file + for glibc, which should only be used or the sh4 architecture. Therefore + this patch is appended to the <command>SRC_URI</command>, but only for the + sh4 architecture. For other architectures it is ignored:<screen># Build fails on sh4 unless no-z-defs is defined +SRC_URI_append_sh4 = " file://no-z-defs.patch;patch=1"</screen></para> + </section> + + <section> + <title>Source distribution (src_distribute_local)</title> + + <para>In order to obtain a set of source files for a build you can use the + <emphasis>src_distribute_local</emphasis> class. This will result in all + the files that were actually used during a build being made available in a + seperate directory and therefore they can be distributed with the + binaries.</para> + + <para>Enabling this option is as simple as activating the functionality by + including the required class in one of your configuration files:<screen>SRC_DIST_LOCAL = "copy" +INHERIT += "src_distribute_local"</screen></para> + + <para>Now during a build each recipe which has a LICENSE that mandates + source availability, like the GPL, will be placed into the source + distribution directory, <command>${SRC_DISTRIBUTEDIR}</command>, after + building.</para> + + <para>There are some options available to effect the option</para> + + <variablelist> + <varlistentry> + <term>SRC_DIST_LOCAL</term> + + <listitem> + <para>Specifies if the source files should be copied, symlinked or + moved and symlinked back. The default is + <command>"move+symlink"</command>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>SRC_DISTRIBUTEDIR</term> + + <listitem> + <para>Specifies the source distribution directory - this is why the + source files that was used for the build are placed. The default is + <command>"${DEPLOY_DIR}/sources"</command>.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>The valid values for <command>SRC_DIST_LOCAL</command> are:</para> + + <variablelist> + <varlistentry> + <term>copy</term> + + <listitem> + <para>Copies the files to the downloaded sources directory into the + distribution directory.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>symlink</term> + + <listitem> + <para>Symlinks the files from the downloaded sources directory into + the distribution directory.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>move+symlink</term> + + <listitem> + <para>Moves the files from the downloaded sources directory into the + distribution directory. Then creates a symlink in the download + sources directory to the moved files.</para> + </listitem> + </varlistentry> + </variablelist> + </section> +</section>
\ No newline at end of file diff --git a/docs/usermanual/usermanual.xml b/docs/usermanual/usermanual.xml new file mode 100644 index 0000000000..ca2e7a93ac --- /dev/null +++ b/docs/usermanual/usermanual.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ex:ts=4:sw=4:sts=4:et + -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +--> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" +"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [ +<!ENTITY chapter-introduction SYSTEM "chapters/introduction.xml"> +<!ENTITY chapter-metadata SYSTEM "chapters/metadata.xml"> +<!ENTITY chapter-gettingoe SYSTEM "chapters/getting_oe.xml"> +<!ENTITY chapter-features SYSTEM "chapters/features.xml"> +<!ENTITY chapter-commonusecases SYSTEM "chapters/common_use_cases.xml"> +<!ENTITY chapter-comparing SYSTEM "chapters/comparing.xml"> +<!ENTITY chapter-usage SYSTEM "chapters/usage.xml"> +<!ENTITY chapter-recipes SYSTEM "chapters/recipes.xml"> +<!ENTITY class-autotools SYSTEM "reference/class_autotools.xml"> +<!ENTITY class-binconfig SYSTEM "reference/class_binconfig.xml"> +<!ENTITY dirs-install SYSTEM "reference/dirs_install.xml"> +<!ENTITY dirs-staging SYSTEM "reference/dirs_staging.xml"> +<!ENTITY class-distutils SYSTEM "reference/class_distutils.xml"> +<!ENTITY fakeroot SYSTEM "reference/fakeroot.xml"> +<!ENTITY class-image SYSTEM "reference/class_image.xml"> +<!ENTITY image-types SYSTEM "reference/image_types.xml"> +<!ENTITY class-pkgconfig SYSTEM "reference/class_pkgconfig.xml"> +<!ENTITY class-rootfs_ipkg SYSTEM "reference/class_rootfs_ipkg.xml"> +<!ENTITY var-section SYSTEM "reference/var_section.xml"> +<!ENTITY class-siteinfo SYSTEM "reference/class_siteinfo.xml"> +<!ENTITY var-src-uri SYSTEM "reference/var_src_uri.xml"> +<!ENTITY class-update-alternatives SYSTEM "reference/class_update-alternatives.xml"> +<!ENTITY class-update-rcd SYSTEM "reference/class_update-rc.d.xml"> +]> +<book> + <bookinfo> + <title>OpenEmbedded User Manual</title> + + <authorgroup> + <corpauthor>OpenEmbedded Team</corpauthor> + </authorgroup> + + <copyright> + <year>2006</year> + + <year>2007</year> + + <year>2008</year> + + <holder>Holger Hans Peter Freyther</holder> + + <holder>Koen Kooi</holder> + + <holder>Detlef Vollmann</holder> + + <holder>Jamie Lenehan</holder> + + <holder>Marcin Juszkiewicz</holder> + + <holder>Rolf Leggewie</holder> + </copyright> + + <legalnotice> + <para>This work is licensed under the Creative Commons Attribution + License. To view a copy of this license, visit <ulink + url="http://creativecommons.org/licenses/by/2.0/">http://creativecommons.org/licenses/by/2.0/</ulink> + or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, + California 94305, USA.</para> + </legalnotice> + </bookinfo> + + <!-- Main chapters--> + + &chapter-introduction; + + &chapter-gettingoe; + + &chapter-metadata; + + &chapter-features; + + &chapter-commonusecases; + + &chapter-comparing; + + &chapter-usage; + + &chapter-recipes; + + <!-- Reference manual. Sorted alphabetically. --> + + <chapter id="chapter_reference"> + <title>Reference</title> + + &class-autotools; + + &class-binconfig; + + &dirs-install; + + &dirs-staging; + + &class-distutils; + + &fakeroot; + + &class-image; + + &image-types; + + &class-pkgconfig; + + &class-rootfs_ipkg; + + &var-section; + + &class-siteinfo; + + &var-src-uri; + + &class-update-alternatives; + + &class-update-rcd; + </chapter> +</book> |