Yocto: Add Static Library

In this section, you are going to learn

How to create a static library in yocto ?

How to generate full yocto image for RPI-4B ?

How to flash full yocto image for RPI-4B ?

How to run minicom and work remotely with RPI-4B ?

  • Step 1: Install all the required packages

    $ sudo apt-get install gawk wget git diffstat unzip texinfo gcc-multilib build-essential chrpath cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping
    
  • Step 2: Clone the yocto source directory

    • To clone poky directory

    $ mkdir sources
    $ cd sources
    $ git clone -b langdale git://git.yoctoproject.org/poky.git
    
    • To clone openembedded core layer

    $ git clone -b langdale git://git.openembedded.org/meta-openembedded
    
    • To clone meta-raspberrypi layer

    $ git clone -b langdale git://git.yoctoproject.org/meta-raspberrypi
    
  • Step 3: Initialize the build environment

    $ cd ..
    $ . sources/poky/oe-init-build-env
    
  • Step 4: Edit the local.conf and bblayers.conf file

    • Add the following configurations in conf/local.conf

    MACHINE ??= "raspberrypi4"
    
    • Add the following yocto layers in conf/bblayers.conf

    BBLAYERS ?= " \
      /home/test/yocto/sources/poky/meta \
      /home/test/yocto/sources/poky/meta-poky \
      /home/test/yocto/sources/poky/meta-yocto-bsp \
      /home/test/yocto/sources/meta-openembedded/meta-oe \
      /home/test/yocto/sources/meta-openembedded/meta-python \
      /home/test/yocto/sources/meta-raspberrypi \
      "
    
  • Step 5: Set locale settings as “en_US.UTF-8”

    export LC_ALL="en_US.UTF-8"
    export LC_CTYPE="en_US.UTF-8"
    sudo dpkg-reconfigure locales
    
    • Select en_US.UTF-8 and apply the changes.

  • Step 5: Build the image

    $ bitbake core-image-base
    
  • Step 6: Once build is completed the image will be in present in the following directory.

    $ pwd
    /home/test/yocto/build/tmp/deploy/images/raspberrypi4/
    
  • Step 7: Extract the base image file using bzip2 command to generate the .wic file.

    $ bzip2 -d -f core-image-base-raspberrypi4.wic.bz2
    
  • Step 8: Flash the image file core-image-base-raspberrypi4.wic to SD card using Elena Batcher tool.

  • Step 9: Run minicom to open the RPI-4B console.

    $ sudo minicom -D /dev/ttyUSB0
    

In this section you will learn how to add static library

  • Make sure the current directory is “yocto”

$ pwd
/home/test/yocto
  • Create the new meta-layer directory for the custom application

$ mkdir meta-mylayer
  • Create a new directory called “conf” inside the meta-mylayer directory

$ mkdir meta-mylayer/conf
  • Create the layer.conf file and add the following configurations.

$ vi meta-mylayer/conf/layer.conf
BBPATH .= ":${LAYERDIR}"

BBFILES += "${LAYERDIR}/recipes-*/*/*.bb"

BBFILE_COLLECTIONS += "mylayer"
BBFILE_PATTERN_mylayer = "^${LAYERDIR}/"
BBFILE_PRIORITY_mylayer = "5"

LAYERVERSION_mylayer = "1"
LAYERDEPENDS_mylayer = ""
  • Create a directory recipes-mylayer

$ mkdir meta-mylayer/recipes-mylayer
  • Create a library folder inside recipes-mylayer to add all static library related source files.

$ mkdir meta-mylayer/recipes-mylayer/lib
  • Create lib.h and lib.c inside the library folder and add the necessary instructions.

$ vi meta-mylayer/recipes-mylayer/lib/lib.h
#ifndef LIB_H
#define LIB_H

void mystaticlib();

#endif
$ vi meta-mylayer/recipes-mylayer/lib/lib.c
#include <stdio.h>
#include "lib.h"

void mystaticlib()
{
        printf("Hi from static library\n");
}
  • Create a recipe file lib.bb inside the lib directory

$ vi meta-mylayer/recipe-mylayer/lib/lib.bb
DESCRIPTION = "A sample static library"
SECTION = "devel"
LICENSE = "CLOSED"

SRC_URI = "file://lib.c \
           file://lib.h"

S = "${WORKDIR}"

do_compile(){
        ${CC} ${CFLAGS} -c lib.c -o lib.o
        ${AR} rcs libmylib.a lib.o
}

do_install(){
        install -d ${D}${libdir}
        install -m 0644 libmylib.a ${D}${libdir}
        install -m 0644 lib.h ${D}${includedir}
}
SUMMARY = "A sample static library"
SECTION = "devel"
LICENSE = "CLOSED"
  • Summary gives a basic definition about the application.

  • Section is used to categorise under which the recipe is used. “devel” is used to indicate it is a development recipe.

  • License is used to specifie the license related information for the recipe.

SRC_URI = "file://lib.c \
           file://lib.h"
  • SRC_URI is used to indicate the uri for the recipe source files.

  • file://” denote that the source code is present in the same directory where the recipe file is.

do_compile() {
        ${CC} ${CFLAGS} -c lib.c -o lib.o
        ${AR} rcs libmylib.a lib.o
}
  • do_compile() is used to define the rules to compile the source code.

  • CC, CFLAGS and LDFLAGS are set by Yocto to appropriate cross-compilation tools and flags.

  • Here the library source code lib.c is compiled and the library file libmylib.a is generated.

do_install() {
        install -d ${D}${libdir}
        install -m 0644 libmylib.a ${D}${libdir}
        install -m 0644 lib.h ${D}${includedir}
}
  • do_install() defines the rules on how to install the generated binary from do_compile() to the final target image.

  • install -d ${D}${libdir} : creates the library directory in the target image.

  • install -m 0644 libmylib.a ${D}${libdir} : copies the library file to the library directory in the target image with the following permissions (read,write for owner and read-only for group and others)

  • install -m 0644 lib.h ${D}${includedir} : copies the library header file to the include directory in the target image with the following permissions (read,write for owner and read-only permission for group and others)

  • Create a app inside recipe-mylayer

$ mkdir meta-mylayer/recipe-mylayer/app
  • Create app.c inside recipe-mylayer and add the necessary instructions.

$ vi meta-mylayer/recipe-mylayer/app.c
#include <stdio.h>
#include "lib.h"

int main(void)
{

        printf("Hi from main function\n");

        mystaticlib();

        return 0;
}
  • Create recipe file app.bb inside the app directory.

$ vim meta-mylayer/recipe-mylayer/app.bb
DESCRIPTION = "My Static Library Application"
SECTION = "examples"
LICENSE = "Closed"

SRC_URI = "file://app.c"

S = "${WORKDIR}"

do_compile() {
        ${CC} ${CFLAGS} ${LDFLAGS} app.c -o app
}

do_install() {
        install -d ${D}${bindir}
        install -m 0755 app ${D}${bindir}
}
SUMMARY = "Hello World Application"
SECTION = "examples"
LICENSE = "CLOSED"
  • Summary gives a basic definition about the application.

  • Section is used to specify under which category the recipe file comes.

  • License is used to specifie the license related information for the recipe.

SRC_URI = "file://app.c"
  • SRC_URI is used to indicate the uri for the recipe source files.

  • file://” denote that the source code is present in the same directory where the recipe file is.

do_compile() {
        ${CC} ${CFLAGS} ${LDFLAGS} app.c -o app -L${STAGING_LIBDIR} -lmylib
}
  • do_compile() is used to define the rules to compile the source code.

  • CC, CFLAGS and LDFLAGS are set by Yocto to appropriate cross-compilation tools and flags.

  • Here the source code app.c is compiled and the binary file app is generated and the linking of library is done.

do_install() {
        install -d ${D}${bindir}
        install -m 0755 app ${D}${bindir}
}
  • do_install() defines the rules on how to install the generated binary from do_compile() to the final target image.

  • install -d ${D}${bindir} : creates the destination directory in the target image.

  • install -m 0755 app ${D}${bindir} : copies the app binary in the destination directory with the following permissions (read,write and execute for owner and read,execute permission for group and others)

In this section you will learn how to add application layer and adding the application binary to final target image.

$ vim build/bblayers.conf
BBLAYERS ?= " \
  /home/test/yocto/sources/poky/meta \
  /home/test/yocto/sources/poky/meta-poky \
  /home/test/yocto/sources/poky/meta-yocto-bsp \
  /home/test/yocto/sources/meta-openembedded/meta-oe \
  /home/test/yocto/sources/meta-openembedded/meta-python \
  /home/test/yocto/sources/meta-raspberrypi \
  /home/test/yocto/sources/meta-mylayer \
  "
$ vim build/local.conf
IMAGE_INSTALL_append = "app mylib"

In this section you will learn how to do Pre-build checks

In .conf file application image and layer should be added.

  • Below line should be present in local.conf file

IMAGE_INSTALL_append = "app mylib"
  • Below line should be present in bblayers.conf file inside BBLAYERS parameter

/home/test/yocto/sources/meta-mylayer
  • Make sure the current directory “yocto”

    $ cd build/tmp/hosttools/
    
  • Make sure the current directory is ‘yocto’

$ cd build
$ bitbake lib
  • Once library is done build now the application recipe.

$ bitbake app

In this section you will learn about post build checks

  • Make sure the current directory is ‘yocto’

$ pwd
/home/test/yocto

$ cd build/tmp/work/raspberrypi4-poky-linux-gnueabi/app/1.0-r0/image/usr/bin/

See that binary called app is present inside directory ?

  • objdump -t : Displays the symbols of application binary file

  • Check if “main” is present or not in the “objdump”

$HOME/yocto/build/tmp/hosttools/objdump -t app | grep -i main

0000000000001149 g     F .text  0000000000000028              main
  • Check if “mystaticlib” is present or not in the “objdump”

$HOME/yocto/build/tmp/hosttools/objdump -t app | grep -i mystaticlib

0000000000001171 g     F .text  000000000000001a              mystaticlib
  • Symbols “main” and “mystaticlib” are present in application binary file

  • Hence we can confirm application is compiled successfully

What is “-t” option is used in “objdump” command ?

What “objdump” command does ?

  • objdump -S : Display source code intermixed with disassembly

  • Check if “main” is present or not in the “objdump”

    $HOME/yocto/build/tmp/hosttools/objdump -S app | grep -i main
    
    1078:   48 8d 3d ca 00 00 00    lea    1149 <main>
    
  • Check if “mystaticlib” is present or not in the “objdump”

    $ $HOME/yocto/build/tmp/hosttools/objdump -S app | grep -i mystaticlib
    
    1165:   e8 07 00 00 00          call   1171 <mystaticlib>
    0000000000001171 <mystaticlib>:
    
  • Symbols “main” and “mystaticlib” are present in application binary file

  • Hence we can confirm application is compiled successfully

What is “-S” option is used in “objdump” command ?

What is the purpose of “objdump” command ?

  • readelf -s: Display the symbol table

  • Check if “main” is present or not in the “readelf”

$HOME/yocto/build/tmp/hosttools/readelf -s app | grep -i main

33: 0000000000001149    40 FUNC    GLOBAL DEFAULT   16 main
  • Check if “mystaticlib” is present or not in the “readelf”

$ $HOME/yocto/build/tmp/hosttools/readelf -s app | grep -i mystaticlib

31: 0000000000001171    26 FUNC    GLOBAL DEFAULT   16 mystaticlib
  • Symbols “main” and “mystaticlib” are present in application binary file

  • Hence we can confirm application is compiled successfully

What is “-s” option is used in “readelf” command ?

What “readelf” command does ?

What is the purpose of “readelf” command ?

  • nm -S: Print both value and size of defined symbols for the “bsd” output style

  • Check if “main” is present or not in the “nm”

$HOME/yocto/build/tmp/hosttools/nm -S app | grep -i main

0000000000001149 0000000000000028 T main
  • Check if “mystaticlib” is present or not in the “nm”

$HOME/yocto/build/tmp/hosttools/nm -S app | grep -i mystaticlib

0000000000001171 000000000000001a T mystaticlib
  • Symbols “main” and “mystaticlib” are present in application binary file

  • Hence we can confirm application is compiled successfully

What is “-S” option is used in “nm” command ?

What “nm” command does ?

What is the purpose of “nm” command ?

  • nm -s: When listing symbols from archive members, include the index: a mapping of which modules contain definitions for which names.

  • Check if “main” is present or not in the “nm”

$HOME/yocto/build/tmp/hosttools/nm -s app | grep -i main

0000000000001149 T main
  • Check if “mystaticlib” is present or not in the “nm”

$HOME/yocto/build/tmp/hosttools/nm -s app | grep -i mystaticlib

0000000000001171 T mystaticlib
  • Symbols “main” and “mystaticlib” are present in application binary file

  • Hence we can confirm application is compiled successfully

What is “-s” option is used in “nm” command ?

  • file: Determine file tye

$ file app

app: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, for GNU/Linux3.7.0, not stripped

Why “file” command is used ?

  • size: List section sizes and total size of binary files

$ size app

text       data     bss     dec     hex filename
1489        600       8    2097     831 app

What “size” command does ?

  • strings - print the sequences of printable characters in files

  • As we can see string output are added in the program are confirmed.

$ strings app | grep -i Hello
Hello from main function
Hello from static library

What “strings” command does ?

In this section you will learn how to build full yocto

  • Make sure the current directory “build”

$ cd $HOME/yocto/build
$ bitbake core-image-base
  • It downloads, compiles and configures all the necessary packages required for the build.

  • Make sure the current directory “build”

  • To check package is successfully compiled, below is the path

$ cd tmp/deploy/images/raspberrypi4/
$ ls
-rw-r--r-- 1 test test 19436211 Jan  4 19:38 core-image-base-raspberrypi4.wic.bz2
  • As we can see image is present in the tmp/deploy/images/raspberrypi4 directory

  • Image file is core-image-base-raspberrypi4.wic.bz