Create a recipe#

To create a bitbake recipe, we are going to make use of recipetool, that will help you do the heavy lifting of creating a valid bitbake recipe.

  • Scotty
  • Bitbake
    ## On your computer run
    $ scotty command recipetool create --help
    usage: recipetool create [-h] [-o OUTFILE] [-p PROVIDES] [-m] [-x EXTRACTPATH] [-N NAME] [-V VERSION] [-b] [--also-native] [--src-subdir SUBDIR] [-a | -S SRCREV] [-B SRCBRANCH] [--keep-temp]
             [--npm-dev] [--mirrors]
             source

    Creates a new recipe from a source tree

    arguments:
    source                Path or URL to source

    options:
    -h, --help            show this help message and exit
    -o OUTFILE, --outfile OUTFILE
                            Specify filename for recipe to create
    -p PROVIDES, --provides PROVIDES
                            Specify an alias for the item provided by the recipe
    -m, --machine         Make recipe machine-specific as opposed to architecture-specific
    -x EXTRACTPATH, --extract-to EXTRACTPATH
                            Assuming source is a URL, fetch it and extract it to the directory specified as EXTRACTPATH
    -N NAME, --name NAME  Name to use within recipe (PN)
    -V VERSION, --version VERSION
                            Version to use within recipe (PV)
    -b, --binary          Treat the source tree as something that should be installed verbatim (no compilation, same directory structure)
    --also-native         Also add native variant (i.e. support building recipe for the build host as well as the target machine)
    --src-subdir SUBDIR   Specify subdirectory within source tree to use
    -a, --autorev         When fetching from a git repository, set SRCREV in the recipe to a floating revision instead of fixed
    -S SRCREV, --srcrev SRCREV
                            Source revision to fetch if fetching from an SCM such as git (default latest)
    -B SRCBRANCH, --srcbranch SRCBRANCH
                            Branch in source repository if fetching from an SCM such as git (default master)
    --keep-temp           Keep temporary directory (for debugging)
    --npm-dev             For npm, also fetch devDependencies
    --mirrors             Enable PREMIRRORS and MIRRORS for source tree fetching (disabled by default).
    ## On your computer run
    $ recipetool create --help
    usage: recipetool create [-h] [-o OUTFILE] [-p PROVIDES] [-m] [-x EXTRACTPATH] [-N NAME] [-V VERSION] [-b] [--also-native] [--src-subdir SUBDIR] [-a | -S SRCREV] [-B SRCBRANCH] [--keep-temp]
             [--npm-dev] [--mirrors]
             source

    Creates a new recipe from a source tree

    arguments:
    source                Path or URL to source

    options:
    -h, --help            show this help message and exit
    -o OUTFILE, --outfile OUTFILE
                            Specify filename for recipe to create
    -p PROVIDES, --provides PROVIDES
                            Specify an alias for the item provided by the recipe
    -m, --machine         Make recipe machine-specific as opposed to architecture-specific
    -x EXTRACTPATH, --extract-to EXTRACTPATH
                            Assuming source is a URL, fetch it and extract it to the directory specified as EXTRACTPATH
    -N NAME, --name NAME  Name to use within recipe (PN)
    -V VERSION, --version VERSION
                            Version to use within recipe (PV)
    -b, --binary          Treat the source tree as something that should be installed verbatim (no compilation, same directory structure)
    --also-native         Also add native variant (i.e. support building recipe for the build host as well as the target machine)
    --src-subdir SUBDIR   Specify subdirectory within source tree to use
    -a, --autorev         When fetching from a git repository, set SRCREV in the recipe to a floating revision instead of fixed
    -S SRCREV, --srcrev SRCREV
                            Source revision to fetch if fetching from an SCM such as git (default latest)
    -B SRCBRANCH, --srcbranch SRCBRANCH
                            Branch in source repository if fetching from an SCM such as git (default master)
    --keep-temp           Keep temporary directory (for debugging)
    --npm-dev             For npm, also fetch devDependencies
    --mirrors             Enable PREMIRRORS and MIRRORS for source tree fetching (disabled by default).

Let’s say we want to create a recipe of cmake-examples we need to run

  • Scotty
  • bitbake
    $ scotty command recipetool create -B master https://github.com/bast/cmake-example.git
    $ recipetool create -B master https://github.com/bast/cmake-example.git

this will create a recipe at build/example_git.bb with the following content

# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
#
# The following license files were not able to be identified and are
# represented as "Unknown" below, you will need to check them yourself:
#   LICENSE
LICENSE = "Unknown"
LIC_FILES_CHKSUM = "file://LICENSE;md5=564aeaf6168b4efd16d2afaf83419333"

SRC_URI = "git://github.com/bast/cmake-example.git;protocol=https;branch=master"

# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "3fe18373d11b7801df7db0474045d027e46af43b"

S = "${WORKDIR}/git"

inherit cmake python3native

# Specify any options you want to pass to cmake using EXTRA_OECMAKE:
EXTRA_OECMAKE = ""

now we need to fine tune a few things

  • remove the leading comment lines starting with #`

  • a look at the license reveals the repository being licensed under BSD-3-Clause, so we need to set LICENSE = "BSD-3-Clause"

  • a look at CMakeLists.txt does not show any cmake options we could use. So it’s safe to remove EXTRA_OECMAKE = ""

  • we should add a SUMMARY = "..." entry at the top to describe what this recipe is about

our recipe now looks like this

SUMMARY = "CMake example repository"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://LICENSE;md5=564aeaf6168b4efd16d2afaf83419333"

SRC_URI = "git://github.com/bast/cmake-example.git;protocol=https;branch=master"

# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "3fe18373d11b7801df7db0474045d027e46af43b"

S = "${WORKDIR}/git"

inherit cmake python3native

now move the file to your layer (see Create your project layer for more details). E.g.

$ mkdir -p <path to my custom layer>/recipes-examples/
$ mv build/example_git.bb <path to my custom layer>/recipes-examples/

Note

You can also rename the recipe file to something more descriptive, e.g. cmake-example_git.bb

at this point we can start our first build of this new recipe

  • Scotty
  • bitbake
    $ scotty build example
    ## or
    $ scotty build cmake-example
    $ bitbake example
    ## or
    $ bitbake cmake-example

What do I do if the recipe doesn’t build?#

If the build now fails with an error during compilation, it is most likely that a dependency is missing. Those can be added by adding

DEPENDS += "<package name>"

to the recipe.

Note

if you do not know the name of the package providing the support you can try to find it by running

  • Scotty
  • bitbake
    $ scotty command oe-pkgdata-util find-path '*/<file you are looking for>'
    $ oe-pkgdata-util find-path '*/<file you are looking for>'

e.g. if the build complains about yaml missing run

  • Scotty
  • bitbake
    $ scotty command oe-pkgdata-util find-path '*/libyaml*'
    libyaml: /usr/lib/libyaml-0.so.2
    libyaml: /usr/lib/libyaml-0.so.2.0.9
    libyaml-dbg: /usr/lib/.debug/libyaml-0.so.2.0.9
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/include/yaml.h
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/api.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/dumper.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/emitter.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/loader.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/parser.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/reader.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/scanner.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/writer.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/yaml_private.h
    libyaml-lic: /usr/share/licenses/libyaml/License
    libyaml-lic: /usr/share/licenses/libyaml/generic_MIT
    libyaml-dev: /usr/lib/libyaml.so
    $ oe-pkgdata-util find-path '*/libyaml*'
    libyaml: /usr/lib/libyaml-0.so.2
    libyaml: /usr/lib/libyaml-0.so.2.0.9
    libyaml-dbg: /usr/lib/.debug/libyaml-0.so.2.0.9
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/include/yaml.h
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/api.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/dumper.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/emitter.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/loader.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/parser.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/reader.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/scanner.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/writer.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/yaml_private.h
    libyaml-lic: /usr/share/licenses/libyaml/License
    libyaml-lic: /usr/share/licenses/libyaml/generic_MIT
    libyaml-dev: /usr/lib/libyaml.so

which shows libyaml is providing the file needed.

In this case add DEPENDS += "libyaml" to the recipe.

If the search does not show any results, you may want to search if there is a recipe available from a known layer. Visit OpenEmbedded Layer Index for that.

Add the recipe to your image#

Next step will be to add your new and compiling recipe to your custom image. For our example it can simply be done, by adding

IMAGE_INSTALL += "example"

# or

IMAGE_INSTALL += "cmake-example"

to your image recipe.

What do I do if the recipe does not work on the device?#

In that case it can be that packages needed to run your application are not installed to the running image. This can be easily fixed by adding

RDEPENDS:${PN} += "${PACKAGE}"

to your recipe.

Note

if you do not know the name of the package providing the support you can try to find it by running

  • Scotty
  • bitbake
    $ scotty command oe-pkgdata-util find-path '*/<file you are looking for>'
    $ oe-pkgdata-util find-path '*/<file you are looking for>'

e.g. if the application complains about libyaml missing run

  • Scotty
  • bitbake
    $ scotty command oe-pkgdata-util find-path '*/libyaml*'
    libyaml: /usr/lib/libyaml-0.so.2
    libyaml: /usr/lib/libyaml-0.so.2.0.9
    libyaml-dbg: /usr/lib/.debug/libyaml-0.so.2.0.9
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/include/yaml.h
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/api.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/dumper.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/emitter.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/loader.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/parser.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/reader.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/scanner.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/writer.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/yaml_private.h
    libyaml-lic: /usr/share/licenses/libyaml/License
    libyaml-lic: /usr/share/licenses/libyaml/generic_MIT
    libyaml-dev: /usr/lib/libyaml.so
    $ oe-pkgdata-util find-path '*/libyaml*'
    libyaml: /usr/lib/libyaml-0.so.2
    libyaml: /usr/lib/libyaml-0.so.2.0.9
    libyaml-dbg: /usr/lib/.debug/libyaml-0.so.2.0.9
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/include/yaml.h
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/api.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/dumper.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/emitter.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/loader.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/parser.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/reader.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/scanner.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/writer.c
    libyaml-src: /usr/src/debug/libyaml/0.2.5-r0/yaml-0.2.5/src/yaml_private.h
    libyaml-lic: /usr/share/licenses/libyaml/License
    libyaml-lic: /usr/share/licenses/libyaml/generic_MIT
    libyaml-dev: /usr/lib/libyaml.so

which shows libyaml is providing the file needed.

In this case add RDEPENDS:${PN} += "libyaml" to the recipe.

If the search does not show any results, you may want to search if there is a recipe available from a known layer. Visit OpenEmbedded Layer Index for that.

Tip

For more ways to tune your recipe in the best possible way, we recommend having a look at this great free video playlist of Yocto tutorials.