Yocto: Add Shared Library

In this section, you are going to learn

How to create a shared 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 shared 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 shared 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 mysharedlib();

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

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

$ vi meta-mylayer/recipe-mylayer/lib/lib.bb
DESCRIPTION = "A sample shared library"
LICENSE = "MIT"

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

S = "${WORKDIR}"

do_compile(){
        ${CC} ${CFLAGS} -shared -fPIC -o libmysharedlib.so lib.c
}

do_install(){
        install -d ${D}${libdir}
        install -m 0644 libmysharedlib.so ${D}${libdir}
}
SUMMARY = "A sample shared library"
LICENSE = "MIT"
  • Summary gives a basic definition about the application.

  • License is used to specifie the license related information for the recipe. Here MIT indicates it has open-source MIT License.

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} -shared -fPIC -o libmysharedlib.so lib.c
}
  • 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 shared library file libmysharedlib.so is generated.

do_install() {
        install -d ${D}${libdir}
        install -m 0644 libmysharedlib.so ${D}${libdir}
}
  • 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 libmysharedlib.so ${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)

  • 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");

        mysharedlib();

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

$ vim meta-mylayer/recipe-mylayer/app.bb
DESCRIPTION = "A sample shared library application"
LICENSE = "MIT"

RDEPENDS_${PN} = "libmysharedlib"

SRC_URI = "file:://app.c"

do_compile() {
        ${CC} ${CFLAGS} -o app app.c -L${libdir} -lmysharedlib
}

do_install() {
        install -d ${D}${bindir}
        install -m 0755 app ${D}${bindir}
}
SUMMARY = "A sample shared library"
LICENSE = "MIT"
  • Summary gives a basic definition about the application.

  • License is used to specifie the license related information for the recipe. MIT is used to indicate open-source MIT license.

RDEPENDS_${PN} = "libmysharedlib"
  • This instruction tells that the application depends on the libmysharedlib so the compiler makes sure that the libsharedlib is already build before building the application.

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${libdir} -lmysharedlib
}
  • 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 mysharedlib"

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 mysharedlib"
  • 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

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

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

0000000000000000       F *UND*  0000000000000000              mysharedlib
  • Symbols “main” and “mysharedlib” 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
    
    1098:   48 8d 3d ca 00 00 00    lea    1169 <main>
    
  • Check if “mysharedlib” is present or not in the “objdump”

    $ $HOME/yocto/build/tmp/hosttools/objdump -S app | grep -i mysharedlib
    
    0000000000001070 <mysharedlibplt>:
    1074:   f2 ff 25 55 2f 00 00    bnd jmp 3fd0 <mysharedlibBase>
    1185:   e8 e6 fe ff ff          call    1070 <mysharedlibplt>
    
  • Symbols “main” and “mysharedlib” 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

32: 0000000000001169    40 FUNC    GLOBAL DEFAULT   16 main
  • Check if “mysharedlib” is present or not in the “readelf”

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

 5: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND mysharedlib
26: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND mysharedlib
  • Symbols “main” and “mysharedlib” 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

0000000000001169 0000000000000028 T main
  • Check if “mysharedlib” is present or not in the “nm”

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

                 U mysharedlib
  • Symbols “main” and “mysharedlib” 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

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

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

                 U mysharedlib
  • Symbols “main” and “mysharedlib” 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
1509        624       8    2141     85d 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 Hi
Hi from main function
Hi from shared 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 16251627 Jan  5 13:29 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