<?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/recipes/*/*.bb ${LOCALDIR}/recipes/*/*.bb" BBFILE_COLLECTIONS = "upstream local" BBFILE_PATTERN_upstream = "^${OEDIR}/openembedded/recipes/" BBFILE_PATTERN_local = "^${LOCALDIR}/recipes/" 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>