Search code examples
ccross-compilingyoctobitbakeopenembedded

How to build hello world recipe in yocto


  1. C file

    int main() {
    printf("Hello, World!\n");
    return 0;
    } 
  1. helloworld.bb
DESCRIPTION = "Recipe created by bitbake-layers"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"


SRC_URI = "file://${BSPDIR}/poky/build-microchip/my_layer/recipes-example/helloworld/helloworld/helloworld.c"

S = "/home/user/my_dir/poky/build-microchip/conf"

do_compile() {
        ${CC} helloworld.c  -o helloworld
}

do_install() {
        install -d ${D}${bindir}
        install -m 0755 helloworld ${D}${bindir}
} 
  1. Run Command

bitbake helloworld

ERROR error in do_compile() block helloworld.c file not found

  1. File Tree
    build-microchip/my_layer/recipes-examples/
    └── helloworld
        ├── helloworld
        │   └── helloworld.c
        └── helloworld.bb

2 directories, 2 files


Solution

  • It's rather unusual to have absolute paths in SRC_URI.

    For a recipe called helloworld_0.1.bb located at build-microchip/my_layer/recipes-examples/helloworld/, SRC_URI content is looked up for by default (and in order) in one of the following directories (FILESPATH[1]) for your recipe:

    1. build-microchip/my_layer/recipes-examples/helloworld/helloworld-0.1
    2. build-microchip/my_layer/recipes-examples/helloworld/helloworld
    3. build-microchip/my_layer/recipes-examples/helloworld/files

    So, you actually do NOT need to pass any of those directory names, Yocto will find it by itself. You just pass to SRC_URI the path relative to one of the aforementioned paths.

    If you want to use files outside of the current directory of the recipe, usually externalsrc class has to be inherited (and it's usually not a good idea to do such a thing). Except in the case of bbappends where you add another path to the list with FILESEXTRAPATHS_prepend := "${THISDIR}/<otherdir>" which puts ${THISDIR}/<otherdir> at the first place in the above list.

    Please note that there can be one more layer of "abstraction" with the content of FILESOVERRIDES[2]. In case of doubt, always look at log.do_fetch in the WORKDIR of your recipe, it will give you all the paths traversed to find a file and in which order they're traversed.

    SRC_URI = "file://helloworld.c" should be fine for you.

    I'm pretty much sure S is not set to what Yocto is expecting. S[3] is the directory where the sources are for Yocto after the do_unpack task. It is a temporary directory setup by Yocto. It usually starts with ${WORKDIR} which is the temp directory for a given recipe. In the case of local sources only, set S = "${WORKDIR}" because local files from SRC_URI (those starting with file://) are put in ${WORKDIR} by the fetcher. By default it is set to ${WORKDIR}/<recipename-recipeversion>.

    do_compile task runs in B which is by default set to ${S}, incorrectly set in the recipe. That is why your file couldn't be found.[4]

    TL;DR:

    SRC_URI = "file://helloworld.c"
    S = "${WORKDIR}"
    

    [1] https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#var-FILESPATH

    [2] https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#var-FILESOVERRIDES

    [3] https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#var-S

    [4] https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#ref-tasks-compile