[Warning: lengthy post, and probably boring to most.]

My Bitbake "Hello World" is a little more than a basic "Hello World". It's
idea is to incorporate a layer and use a structure similar to what OE and
Yocto are using. You can do it simpler if you want to. I did this a while
ago with Bitbake 1.12.0. I would think it works with newer versions too
although I have not tested it. This is the layout I am using:

├── conf
│   ├── bblayers.conf
│   └── bitbake.conf
├── downloads
│   └── /* need to create but will be populated with downloads */
├── meta-test
│   ├── classes
│   │   └── base.bbclass
│   ├── conf

│   │   └── layer.conf

│   └── recipes-test

│       └── nano

│         └── nano.bb

└── tmp

    └── /* will be created and populated when building */

The first thing Bitbake looks for is a conf/bblayers.conf file in the
directory you started it from. This file must provide an initial setting


  ${TOPDIR}/meta-test \

Without BBPATH Bitbake will not find any conf/<filename>.conf files and
recipe files at all. It will also not find bitbake.conf. I simply copied
bitbake.conf from the Bitbake download and edited DL_DIR:


# comments omitted
B = "${S}"

CVSDIR = "${DL_DIR}/cvs"


DEPLOY_DIR = "${TMPDIR}/deploy"
DL_DIR = "${TOPDIR}/downloads"
FETCHCOMMAND_cvs = "/usr/bin/env cvs -d${CVSROOT} co ${CVSCOOPTS}
FETCHCOMMAND_svn = "/usr/bin/env svn co ${SVNCOOPTS} ${SVNROOT}
FETCHCOMMAND_wget = "/usr/bin/env wget -t 5 --passive-ftp -P ${DL_DIR}
FILESDIR = "${@bb.utils.which(bb.data.getVar('FILESPATH', d, 1), '.')}"
FILE_DIRNAME = "${@os.path.dirname(bb.data.getVar('FILE', d))}"
GITDIR = "${DL_DIR}/git"
MKTEMPCMD = "mktemp -q ${TMPBASE}"
MKTEMPDIRCMD = "mktemp -d -q ${TMPBASE}"
P = "${PN}-${PV}"
PF = "${PN}-${PV}-${PR}"
PN = "${@bb.parse.BBHandler.vars_from_file(bb.data.getVar('FILE',d),d)[0]
or 'defaultpkgname'}"
PR = "${@bb.parse.BBHandler.vars_from_file(bb.data.getVar('FILE',d),d)[2]
or 'r0'}"
PV = "${@bb.parse.BBHandler.vars_from_file(bb.data.getVar('FILE',d),d)[1]
or '1.0'}"
RESUMECOMMAND_wget = "/usr/bin/env wget -c -t 5 --passive-ftp -P ${DL_DIR}
S = "${WORKDIR}/${P}"
SRC_URI = "file://${FILE}"
STAMP = "${TMPDIR}/stamps/${PF}"
SVNDIR = "${DL_DIR}/svn"
T = "${WORKDIR}/temp"
TMPDIR = "${TOPDIR}/tmp"
UPDATECOMMAND_cvs = "/usr/bin/env cvs -d${CVSROOT} update ${CVSCOOPTS}"
UPDATECOMMAND_svn = "/usr/bin/env svn update ${SVNCOOPTS}"
WORKDIR = "${TMPDIR}/work/${PF}"

That's more than you need but it's convenient.

Bitbake will require a base.bbclass file somewhere in a classes
subdirectory of BBPATH. I used the base.bbclass file from the Bitbake
download. As a minimum it should contain a do_build task. That's the target
that Bitbake invokes by default if you do not use the -c option explicitly.
It's empty and does not do anything but it functions as an anchor for tasks
you define in your recipes:


# comments omitted
die() {
        bbfatal "$*"

bbnote() {
        echo "NOTE:" "$*"

bbwarn() {
        echo "WARNING:" "$*"

bbfatal() {
        echo "FATAL:" "$*"
        exit 1

addtask showdata
do_showdata[nostamp] = "1"
python do_showdata() {
        import sys
        # emit variables and shell functions
        bb.data.emit_env(sys.__stdout__, d, True)
        # emit the metadata which isnt valid shell
        for e in bb.data.keys(d):
                if bb.data.getVarFlag(e, 'python', d):
                        sys.__stdout__.write("\npython %s () {\n%s}\n" %
(e, bb.data.getVar(e, d, 1)))

addtask listtasks
do_listtasks[nostamp] = "1"
python do_listtasks() {
        import sys
        for e in bb.data.keys(d):
                if bb.data.getVarFlag(e, 'task', d):
                        sys.__stdout__.write("%s\n" % e)

addtask build
do_build[dirs] = "${TOPDIR}"
do_build[nostamp] = "1"
python base_do_build () {
        bb.note("The included, default BB base.bbclass does not define a
useful default task.")
        bb.note("Try running the 'listtasks' task against a .bb to see what
tasks are defined.")

EXPORT_FUNCTIONS do_clean do_mrproper do_build

Again, it's more than you need. It's just convenient to use it. I put this
file inside the layer but you can also create a classes directory in
${TOPDIR} (bbtest in this example). Next, create a layer (meta-bbtest in my
example, name does not matter, meta-* is convention). It needs a
conf/layer.con file:


# We have a metadata layer directory, add to BBPATH

# We have a recipe directory, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \


The path expression for the recipes is more complex than necessary, it just
follows the convention. Finally a recipe to build the Nano editor:

DESCRIPTION = "Recipe to build the 'nano' editor"

PN = "nano"
PV = "2.2.6"

SRC_URI = "http://www.nano-editor.org/dist/v2.2/nano-2.2.6.tar.gz";

python do_fetch() {
   bb.note("Downloading source tarball from ${SRC_URI} ...")

   src_uri = (bb.data.getVar('SRC_URI', d, True) or "").split()
   if len(src_uri) == 0:
      bb.fatal("Empty URI")

      bb.fetch.init(src_uri, d)
   except FetchError:
      bb.fatal("Could not fetch source tarball.")

   bb.note("Download successful.")

addtask fetch before do_build

python do_unpack() {
   bb.note("Unpacking source tarball ...")

   os.system("tar x -C ${WORKDIR} -f ${DL_DIR}/${P}.tar.gz")

   bb.note("Unpacked source tarball.")

addtask unpack before do_build after do_fetch

python do_configure() {
   bb.note("Configuring source package ...")

   os.system("cd ${WORKDIR}/${P} && ./configure")

   bb.note("Configured source package.")

addtask configure before do_build after do_unpack

python do_compile() {
   bb.note("Compiling package...")

   os.system("cd ${WORKDIR}/${P} && make")

   bb.note("Compiled package.")

addtask compile before do_build after do_configure

Nano is an autotooled package. This recipe simply at a very basic level
does what you would do manually. OECore's autotools.bbclass is much more
sophisticated and so are the fetcher class files.

yocto mailing list

Reply via email to