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 ?
Topics in this section,
Step 1 : Add custom application
Step 2 : Add configurations in .conf files
Step 5.2: Check the “objdump” output of the application binary file
Step 5.3: Check the “readelf” output of the application binary file
Step 5.4: Check the “nm” output of the application binary file
Step 5.5: Check the “file” command output of application binary file
Step 5.6: Check the “size” command output of application binary file
Step 5.7: Check the “strings” command output of application binary file
Step 6: Build full yocto - Incremental
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.confBBPATH .= ":${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.bbDESCRIPTION = "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.bbDESCRIPTION = "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.confBBLAYERS ?= " \ /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.confIMAGE_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/See Output Below
$ ls -l lrwxrwxrwx 1 test test 10 Jan 4 12:59 '[' lrwxrwxrwx 1 test test 11 Jan 4 12:59 ar lrwxrwxrwx 1 test test 11 Jan 4 12:59 as lrwxrwxrwx 1 test test 12 Jan 4 12:59 awk lrwxrwxrwx 1 test test 17 Jan 4 12:59 basename lrwxrwxrwx 1 test test 13 Jan 4 12:59 bash lrwxrwxrwx 1 test test 14 Jan 4 12:59 bzip2 lrwxrwxrwx 1 test test 12 Jan 4 13:00 bzr lrwxrwxrwx 1 test test 12 Jan 4 12:59 cat lrwxrwxrwx 1 test test 14 Jan 4 12:59 chgrp lrwxrwxrwx 1 test test 14 Jan 4 12:59 chmod lrwxrwxrwx 1 test test 14 Jan 4 12:59 chown lrwxrwxrwx 1 test test 16 Jan 4 12:59 chrpath lrwxrwxrwx 1 test test 12 Jan 4 12:59 cmp lrwxrwxrwx 1 test test 13 Jan 4 12:59 comm lrwxrwxrwx 1 test test 11 Jan 4 12:59 cp lrwxrwxrwx 1 test test 13 Jan 4 12:59 cpio lrwxrwxrwx 1 test test 12 Jan 4 12:59 cpp lrwxrwxrwx 1 test test 12 Jan 4 12:59 cut lrwxrwxrwx 1 test test 13 Jan 4 12:59 date lrwxrwxrwx 1 test test 11 Jan 4 12:59 dd lrwxrwxrwx 1 test test 13 Jan 4 12:59 diff lrwxrwxrwx 1 test test 17 Jan 4 12:59 diffstat lrwxrwxrwx 1 test test 16 Jan 4 12:59 dirname lrwxrwxrwx 1 test test 11 Jan 4 12:59 du lrwxrwxrwx 1 test test 13 Jan 4 12:59 echo lrwxrwxrwx 1 test test 14 Jan 4 12:59 egrep lrwxrwxrwx 1 test test 12 Jan 4 12:59 env lrwxrwxrwx 1 test test 15 Jan 4 12:59 expand lrwxrwxrwx 1 test test 13 Jan 4 12:59 expr lrwxrwxrwx 1 test test 14 Jan 4 12:59 false lrwxrwxrwx 1 test test 14 Jan 4 12:59 fgrep lrwxrwxrwx 1 test test 13 Jan 4 12:59 file lrwxrwxrwx 1 test test 13 Jan 4 12:59 find lrwxrwxrwx 1 test test 14 Jan 4 12:59 flock lrwxrwxrwx 1 test test 12 Jan 4 12:59 g++ lrwxrwxrwx 1 test test 13 Jan 4 12:59 gawk lrwxrwxrwx 1 test test 12 Jan 4 12:59 gcc lrwxrwxrwx 1 test test 15 Jan 4 13:00 gcc-ar lrwxrwxrwx 1 test test 16 Jan 4 12:59 getconf lrwxrwxrwx 1 test test 15 Jan 4 12:59 getopt lrwxrwxrwx 1 test test 12 Jan 4 12:59 git lrwxrwxrwx 1 test test 12 Jan 4 13:00 gpg lrwxrwxrwx 1 test test 18 Jan 4 13:00 gpg-agent lrwxrwxrwx 1 test test 13 Jan 4 12:59 grep lrwxrwxrwx 1 test test 15 Jan 4 12:59 gunzip lrwxrwxrwx 1 test test 13 Jan 4 12:59 gzip lrwxrwxrwx 1 test test 13 Jan 4 12:59 head lrwxrwxrwx 1 test test 17 Jan 4 12:59 hostname lrwxrwxrwx 1 test test 14 Jan 4 12:59 iconv lrwxrwxrwx 1 test test 11 Jan 4 12:59 id lrwxrwxrwx 1 test test 16 Jan 4 12:59 install lrwxrwxrwx 1 test test 13 Jan 4 13:00 join lrwxrwxrwx 1 test test 11 Jan 4 12:59 ld lrwxrwxrwx 1 test test 15 Jan 4 13:00 ld.bfd lrwxrwxrwx 1 test test 12 Jan 4 12:59 ldd lrwxrwxrwx 1 test test 16 Jan 4 13:00 ld.gold lrwxrwxrwx 1 test test 11 Jan 4 12:59 ln lrwxrwxrwx 1 test test 11 Jan 4 12:59 ls lrwxrwxrwx 1 test test 13 Jan 4 13:00 lz4c lrwxrwxrwx 1 test test 13 Jan 4 12:59 make lrwxrwxrwx 1 test test 15 Jan 4 12:59 md5sum lrwxrwxrwx 1 test test 14 Jan 4 12:59 mkdir lrwxrwxrwx 1 test test 15 Jan 4 12:59 mkfifo lrwxrwxrwx 1 test test 14 Jan 4 12:59 mknod lrwxrwxrwx 1 test test 15 Jan 4 12:59 mktemp lrwxrwxrwx 1 test test 11 Jan 4 12:59 mv lrwxrwxrwx 1 test test 11 Jan 4 13:00 nc lrwxrwxrwx 1 test test 11 Jan 4 13:00 nl lrwxrwxrwx 1 test test 11 Jan 4 12:59 nm lrwxrwxrwx 1 test test 16 Jan 4 12:59 objcopy lrwxrwxrwx 1 test test 16 Jan 4 12:59 objdump lrwxrwxrwx 1 test test 11 Jan 4 12:59 od lrwxrwxrwx 1 test test 14 Jan 4 12:59 patch lrwxrwxrwx 1 test test 13 Jan 4 12:59 perl lrwxrwxrwx 1 test test 11 Jan 4 12:59 pr lrwxrwxrwx 1 test test 15 Jan 4 12:59 printf lrwxrwxrwx 1 test test 12 Jan 4 12:59 pwd lrwxrwxrwx 1 test test 16 Jan 4 12:59 python3 lrwxrwxrwx 1 test test 14 Jan 4 12:59 pzstd lrwxrwxrwx 1 test test 15 Jan 4 12:59 ranlib lrwxrwxrwx 1 test test 16 Jan 4 12:59 readelf lrwxrwxrwx 1 test test 17 Jan 4 12:59 readlink lrwxrwxrwx 1 test test 17 Jan 4 12:59 realpath lrwxrwxrwx 1 test test 11 Jan 4 12:59 rm lrwxrwxrwx 1 test test 14 Jan 4 12:59 rmdir lrwxrwxrwx 1 test test 15 Jan 4 12:59 rpcgen lrwxrwxrwx 1 test test 12 Jan 4 13:00 scp lrwxrwxrwx 1 test test 12 Jan 4 12:59 sed lrwxrwxrwx 1 test test 12 Jan 4 12:59 seq lrwxrwxrwx 1 test test 13 Jan 4 13:00 sftp lrwxrwxrwx 1 test test 11 Jan 4 12:59 sh lrwxrwxrwx 1 test test 16 Jan 4 12:59 sha1sum lrwxrwxrwx 1 test test 18 Jan 4 12:59 sha224sum lrwxrwxrwx 1 test test 18 Jan 4 12:59 sha256sum lrwxrwxrwx 1 test test 18 Jan 4 12:59 sha384sum lrwxrwxrwx 1 test test 18 Jan 4 12:59 sha512sum lrwxrwxrwx 1 test test 13 Jan 4 13:00 size lrwxrwxrwx 1 test test 14 Jan 4 12:59 sleep lrwxrwxrwx 1 test test 14 Jan 4 13:00 socat lrwxrwxrwx 1 test test 13 Jan 4 12:59 sort lrwxrwxrwx 1 test test 14 Jan 4 12:59 split lrwxrwxrwx 1 test test 12 Jan 4 13:00 ssh lrwxrwxrwx 1 test test 13 Jan 4 12:59 stat lrwxrwxrwx 1 test test 16 Jan 4 12:59 strings lrwxrwxrwx 1 test test 14 Jan 4 12:59 strip lrwxrwxrwx 1 test test 13 Jan 4 13:00 sudo lrwxrwxrwx 1 test test 13 Jan 4 12:59 tail lrwxrwxrwx 1 test test 12 Jan 4 12:59 tar lrwxrwxrwx 1 test test 12 Jan 4 12:59 tee lrwxrwxrwx 1 test test 13 Jan 4 12:59 test lrwxrwxrwx 1 test test 14 Jan 4 12:59 touch lrwxrwxrwx 1 test test 11 Jan 4 12:59 tr lrwxrwxrwx 1 test test 13 Jan 4 12:59 true lrwxrwxrwx 1 test test 14 Jan 4 12:59 uname lrwxrwxrwx 1 test test 13 Jan 4 12:59 uniq lrwxrwxrwx 1 test test 11 Jan 4 12:59 wc lrwxrwxrwx 1 test test 13 Jan 4 12:59 wget lrwxrwxrwx 1 test test 14 Jan 4 12:59 which lrwxrwxrwx 1 test test 14 Jan 4 12:59 xargs lrwxrwxrwx 1 test test 12 Jan 4 13:00 yes lrwxrwxrwx 1 test test 13 Jan 4 13:00 zcat lrwxrwxrwx 1 test test 13 Jan 4 12:59 zstd
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 ?
See Answer
$ cd build/tmp/work/raspberrypi4-poky-linux-gnueabi/app/1.0-r0/image/usr/bin/ $ ls -l -rwxrwxr-x 1 test test 16016 Jan 4 19:20 app
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 ?
See Answer
-t: Displays the symbols of application binary file
What “objdump” command does ?
See Answer
objdump: Display information from object files
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 ?
See Answer
-S : Display source code intermixed with disassembly
What is the purpose of “objdump” command ?
See Answer
The main purpose of the objdump tool is to debug and understand the executable file
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 ?
See Answer
-s: Display the symbol table
What “readelf” command does ?
See Answer
readelf: Display information about ELF files
What is the purpose of “readelf” command ?
See Answer
The main purpose of the readelf tool is to display the headers of an ELF (Executable and Linkable Format) files
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 ?
See Answer
-S: Print both value and size of defined symbols for the “bsd” output style
What “nm” command does ?
See Answer
nm is used to dump the symbol table and their attributes from a binary executable file.
What is the purpose of “nm” command ?
See Answer
The main purpose of the nm tool is to display information about symbols in the specified File, which can be an object file, an executable file, or an object-file library.
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 ?
See Answer
-s: When listing symbols from archive members, include the index: a mapping of which modules contain definitions for which names.
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 strippedWhy “file” command is used ?
See Answer
file command is used to determine the file type.
size: List section sizes and total size of binary files
$ size app text data bss dec hex filename 1489 600 8 2097 831 appWhat “size” command does ?
See Answer
size command will display the output that will give you information on the size command in 5 values like data, text, dec, bss, and hex
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 libraryWhat “strings” command does ?
See Answer
strings command is used to return the string characters into files.
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
Other topics of linux yocto rpi
Current Module
Next Module
Other Modules