Open Embedded: An alternative way to build embedded Linux distributions

Nick Lethaby and Denys Dmytriyenko, Texas Instruments

August 3, 2011

Nick Lethaby and Denys Dmytriyenko, Texas Instruments

OE Recipe Files
OE recipes can be written in shell script, with possible Python snippets, and are divided in five categories:
  • classes
  • packages
  • tasks
  • images
  • meta

These are hierarchical with an image being the top level recipe. The image recipe defines what goes into a particular root file system image. The recipe simply defines a set of tasks required to build the image. A task recipe is a group of related packages required to bring a block of related features or functionality. For example, a distribution intended for a smart phone might have digital music, digital camera, and contacts book tasks that bring in all the packages needed to provide a particular capability. One of the reasons of such indirection is to abstract sets of packages in tasks, so tasks can be easily re-used in different images.

It is common practice for distributions to have multiple image files to offer a variety of functionality/footprint tradeoffs. For example, Arago includes a base image, console image, digital video demonstration image, and gstreamer image. As can be seen from its image recipe (see Listing #1), the gstreamer image is created by building four different task recipes. The other image recipes are similar, with the base image, for example, simply omitting the console, dvsdk, and gstreamer tasks and having a different image name and root file system size.

Listing #1: Example Image Recipe

# Arago GStreamer image
# gives you an image with DVSDK libs and GStreamer demo

require arago-image.inc
 
COMPATIBLE_MACHINE = "(?!arago)"
 
# The size of the uncompressed ramdisk is 150MB
ROOTFS_SIZE = "153600"

IMAGE_INSTALL += "\
     task-arago-base \
     task-arago-console \
     task-arago-dvsdk \
     task-arago-gst \
     "
export IMAGE_BASENAME = "arago-gst-image"

Task recipes represent individual aggregations of packages. For example, the arago-base task builds about 15 packages. This recipe (see Listing #2) introduces some standard BitBake variables you will need to become familiar with. PR represents the Package Revision, which is the version number for package recipe file. PN represents the Package Name, while PV (not used here) represents the Package Version, which is the version for the actual package source files. The tasks do not specify most package versions as these are set in the configurations files.

Listing #2: Example Task Recipe


DESCRIPTION = "Basic task to get a device booting"

LICENSE = "MIT"
PR = "r9"

inherit task

# these can be set in machine config to supply packages needed to get machine booting
MACHINE_ESSENTIAL_EXTRA_RDEPENDS ?= ""
MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS ?= ""

ARAGO_ALSA_BASE = "\
     alsa-lib \
     alsa-utils-aplay \
     "

ARAGO_BASE = "\
     ${ARAGO_ALSA_BASE} \
     ldd \
     mtd-utils \
     curl \
     arago-feed-configs \
     initscript-telnetd \
     devmem2 \
     "
   
# minimal set of packages - needed to boot
RDEPENDS_${PN} = "\
     base-files \
     base-passwd \
     busybox \
     initscripts \
     modutils-initscripts \
     netbase \
     update-alternatives \
     module-init-tools \
     ${ARAGO_BASE} \
     ${MACHINE_ESSENTIAL_EXTRA_RDEPENDS} \
     "
 
RRECOMMENDS_${PN} = "\
     ${MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS} \
     "

The package recipes address the specific needs of each package. A relatively simple example (see Listing #3) for a GStreamer-based application illustrates some of the key functions of a package recipe. The build mechanism is specified by inheriting the autotools and pkgconfig classes, dependencies are identified, package version and revision numbers identified, and the location of the package sources is given.

Listing #3: Example Package Recipe

DESCRIPTION = "gstd: a GStreamer-based streaming server"
HOMEPAGE = "http://sourceforge.net/projects/harrier/"
LICENSE = "BSD"
SECTION = "multimedia"
PRIORITY = "optional"

inherit autotools pkgconfig

DEPENDS = "dbus dbus-glib gstreamer"
RDEPENDS_${PN} = "dbus dbus-glib gstreamer gst-plugins-base"
RRECOMENDS_${PN} = "gstreamer-ti"

SRCREV = "f3e22c93f4fd7ca47d6309b8450788127550ecb9"

PV = "1.0"
PR = "r13"
PR_append = "+gitr${SRCREV}"

SRC_URI = "git://gstd.git.sourceforge.net/gitroot/gstd/gstd;protocol=git \"
S = "${WORKDIR}/git"

# We don't want to run autoconf or automake, unless you have
# automake > 1.11 with vala support
do_configure() {
      oe_runconf
}

FILES_${PN} += "${datadir}/dbus-1/*/*.service"
FILES_${PN}-dev += "${datadir}/dbus-1/interfaces/*.xml"



In the package recipe (see Listing #3), there is a line that states ‘inherit autotools pkgconfig’. This line is utilizing the remaining recipes type – a BitBake class. Classes have a peer-to-peer relationship with the other recipes rather than a hierarchical one. They are used to factor out common recipe elements that can then be reused, through the inherit command. The most frequent use of classes is to inherit functions or portions of recipes for commonly used build tools like the GNU autotools. An example (see Listing #4) is the class used for the pkgconfig tool (pkgconfig.bbclass):

Listing #4: An Example Class Recipe

inherit base

DEPENDS_prepend = "pkgconfig-native "

do_install_prepend () {

for i in `find ${S}/ -name "*.pc" -type f` ; do \
            sed -i -e 's:-L${STAGING_LIBDIR}::g' $i
        done
}

do_stage_append () {
    install -d ${PKG_CONFIG_DIR}
    for pc in `find ${S} -name '*.pc' -type f | grep -v -- '-uninstalled.pc$'`; do
        pcname=`basename $pc`
        cat $pc > ${PKG_CONFIG_DIR}/$pcname
    done
}


< Previous
Page 2 of 4
Next >

Loading comments...

Most Commented

Parts Search Datasheets.com

KNOWLEDGE CENTER