Open-Wrt: Add static library

In this section, you are going to learn

What is static library ?

How to create a static library in Open-WRT ?

How to link static library with object files for RPI-4B ?

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

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

Topics in this section,

PART A: CREATING STATIC LIBRARY

Topics in this section,

PART B: CREATING STATIC APPLICATION

Note

PART A: Creating Static Library

Note

Create 2 folders in alphabet order so that library side makefile should execute first and it will create .a static library file

In this section you will learn how to add custom built library in “Openwrt”

  • Make sure the current directory “openwrt”

    $ pwd
    
      /home/test/openwrt
    
  • Make sure the current directory “openwrt”

    $ cd package/libs/
    
    $ mkdir -p static_lib/my_static_lib
    
  • Make sure the current directory “my_static_lib”

    $ cd my_static_lib
    
    $ mkdir src obj inc
    
  • Make sure the current directory “my_static_lib/src”

  • In my_static_lib.c have “Function Definition”

  • Create my_static_lib.c file using vim command

vim my_static_lib.c
  • Content of src/my_static_lib.c

#include "my_static_lib.h"

void my_static_function(void)
{
       printf("Hello from my_static_function!\n");
}
  • Make sure the current directory “my_static_lib/inc”

  • In my_static_lib.h have “Function Prototype”

  • Create my_static_lib.h file using vim command

vim my_static_lib.h
  • Content of inc/my_static_lib.h

#include <stdio.h>

void my_static_function(void);

What is Static Library ?

What are the types of library ?

What is the use of library ?

  • Make sure the current directory “my_static_lib”

  • Create Makefile file using vim command

    vim Makefile
    
  • Content of Makefile

    include $(TOPDIR)/rules.mk
    
    PKG_NAME:=my_static_lib
    PKG_VERSION:=1.0
    PKG_RELEASE:=1
    
    SOURCE_DIR:=$(TOPDIR)/package/libs/static_lib/my_static_lib
    
    include $(INCLUDE_DIR)/package.mk
    
    define Package/my_static_lib
    SECTION:=examples
    CATEGORY:=Examples
    TITLE:=My Static Library
    endef
    
    define Package/my_static_lib/description
            A simple static library example
    endef
    
    define Build/Prepare
            mkdir -p $(PKG_BUILD_DIR)
            cp -r $(SOURCE_DIR)/src $(PKG_BUILD_DIR)
            cp -r $(SOURCE_DIR)/inc $(PKG_BUILD_DIR)
            cp -r $(SOURCE_DIR)/obj $(PKG_BUILD_DIR)
            cp $(SOURCE_DIR)/Makefile $(PKG_BUILD_DIR)
            $(Build/Patch)
    endef
    
    define Build/Compile
            $(TARGET_CC) $(TARGET_CFLAGS) -I$(PKG_BUILD_DIR)/inc -o $(PKG_BUILD_DIR)/obj/my_static_lib.o -c $(PKG_BUILD_DIR)/src/my_static_lib.c
            $(TARGET_AR) -rc $(PKG_BUILD_DIR)/obj/libmy_static_lib.a $(PKG_BUILD_DIR)/obj/my_static_lib.o
    endef
    
    define Package/my_static_lib/install
            $(INSTALL_DIR) $(1)/usr/lib
            $(INSTALL_BIN) $(PKG_BUILD_DIR)/obj/libmy_static_lib.a $(1)/usr/lib/
    endef
    
    $(eval $(call BuildPackage,my_static_lib))
    
  • Explanation of include $(TOPDIR)/rules.mk

    include $(TOPDIR)/rules.mk
    
  • The $(TOPDIR) is expected to be the top-level directory

  • /rules.mk - The path to the file included

What is $(TOPDIR) ?

  • Explanation of Package Name, Version and Release number Block

PKG_NAME:=my_static_lib
PKG_VERSION:=1.0
PKG_RELEASE:=1
  • The name and version of your package are used to define the variable to point to the build directory of your package (Ex: my_static_lib-1.0)

  • Explanation of SOURCE_DIR

SOURCE_DIR:=$(TOPDIR)/package/libs/static_lib/my_static_lib

What is SOURCE_DIR ?

  • Give path of the source directory

  • SOURCE_DIR is used in Build/Prepare

  • Explanation of include $(INCLUDE_DIR)/package.mk

include $(INCLUDE_DIR)/package.mk
  • $(INCLUDE_DIR) - Directory containing include files

  • /package.mk: The path to the file included

What is $(INCLUDE_DIR) ?

  • Explanation of Package Information

define Package/my_static_lib
SECTION:=examples
CATEGORY:=Examples
TITLE:=My Static Library
endef
  • This block defines the package information as section, category, and title

  • SECTION: examples: This line tells the section to which the package belongs. In this case, the package will come under the “examples” section.

  • CATEGORY: Examples: This line tells the category to which the package belongs. In this case, the category is set to “Examples

  • TITLE: My Static Library This line tells, title or name of the package. In this case, the title is set to “My Static Library”.

  • endef: This line will be the end of the define block.

What all information included in Package Information Block ?

  • Explanation of Package Description

define Package/my_static_lib/description
        A simple static library example
endef
  • This function defines of package.

What is Package Description Block ?

  • Explanation of Build/Prepare

define Build/Prepare
        mkdir -p $(PKG_BUILD_DIR)
        cp -r $(SOURCE_DIR)/src $(PKG_BUILD_DIR)
        cp -r $(SOURCE_DIR)/inc $(PKG_BUILD_DIR)
        cp -r $(SOURCE_DIR)/obj $(PKG_BUILD_DIR)
        cp $(SOURCE_DIR)/Makefile $(PKG_BUILD_DIR)
        $(Build/Patch)
endef
  • mkdir -p $(PKG_BUILD_DIR): This line creates the build directory

  • cp -r $(SOURCE_DIR)/src $(PKG_BUILD_DIR): This line copies the contents from SOURCE_DIR (source) to PKG_BUILD_DIR (destination)

  • cp -r $(SOURCE_DIR)/inc $(PKG_BUILD_DIR): This line copies the contents from SOURCE_DIR (source) to PKG_BUILD_DIR (destination)

  • cp -r $(SOURCE_DIR)/obj $(PKG_BUILD_DIR): This line copies the contents from SOURCE_DIR (source) to PKG_BUILD_DIR (destination)

  • cp -r $(SOURCE_DIR)Makefile $(PKG_BUILD_DIR): This line copies the contents from SOURCE_DIR (source) to PKG_BUILD_DIR (destination)

  • -r : -r is recursive copy.

  • $(Build/Patch): This line includes a call to $(Build/Patch), which is a variable or macro typically defined elsewhere in the Makefile. It is used to apply any necessary patches to the source code.

What is -r ?

Which path $(PKG_BUILD_DIR) ?

What is SOURCE_DIR ?

  • Explanation of Build/Compile

define Build/Compile
        $(TARGET_CC) $(TARGET_CFLAGS) -I$(PKG_BUILD_DIR)/inc -o $(PKG_BUILD_DIR)/obj/my_static_lib.o -c $(PKG_BUILD_DIR)/src/my_static_lib.c
        $(TARGET_AR) -rc $(PKG_BUILD_DIR)/obj/libmy_static_lib.a $(PKG_BUILD_DIR)/obj/my_static_lib.o
endef
  • This block defines the compilation process.

  • $(TARGET_CC): It is said to arm cross compiler and it is defined globally

  • $(TARGET_CFLAGS): It is used for additional flags

  • -I$(PKG_BUILD_DIR)/inc : It will include prototype path

  • -o $(PKG_BUILD_DIR)/obj/my_static_lib.o : Takes .c input file and generates .o output file in location $(PKG_BUILD_DIR)/obj

  • $(TARGET_AR): It is used as archive tool.

  • $(TARGET_AR): aarch64-openwrt-linux-musl-gcc-ar

  • In this case path of $(TARGET_AR) $HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/bin/aarch64-openwrt-linux-musl-gcc-ar

  • $(PKG_BUILD_DIR)/obj/libmy_static_lib.a : Takes .o input file and generates .a output file in location $(PKG_BUILD_DIR)/obj

What is $(TARGET_CC) ?

What is $(TARGET_CFLAGS) ?

What is $(TARGET_AR) ?

  • Explanation of Package Install

define Package/my_static_lib/install
        $(INSTALL_DIR) $(1)/usr/lib
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/obj/libmy_static_lib.a $(1)/usr/lib/
endef
  • $(INSTALL_DIR): It used for creating a directory and it is commonly used in build systems like OpenWrt.

  • $(INSTALL_BIN): It used for copying an executable file.

  • In this case path of $(PKG_BUILD_DIR) $HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0

  • /usr/bin: It is the destination directory, .a file will be installed.

What is $(INSTALL_DIR) ?

What is $(INSTALL_BIN) ?

What is $(1)/usr/bin ?

  • Explanation of Package Build

$(eval $(call BuildPackage,my_static_lib))
  • BuildPackage: It is function call with my_static_lib as parameter.

In this section you will learn how to add menuconfig

  • Make sure the current directory is “openwrt”

  • Create new feeds.conf file using vim command in openwrt directory

$ vim feeds.conf
  • Inside feeds.conf

src-link <name> <path>
  • Make sure the current directory is “openwrt”

  • Create new feeds.conf file using vim command in openwrt directory

src-link libs /home/test/openwrt/package/libs

In this section you will learn how to install and update feeds

  • Installs the most recent packages, replacing any earlier versions that were already on your system

$ ./scripts/feeds update -a

$ ./scripts/feeds install -a -f

In this section you will learn how to enable in menuconfig

  • Select your category that reflects in menuconfig

  • Go inside examples and select my_static_lib

Diagram Diagram
Diagram
Diagram

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

  • In .config file package should be enabled in ‘y’

  • Below line should be present in .config file

    CONFIG_PACKAGE_my_static_lib=y
    
  • Make sure the current directory “openwrt”

    $HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl
    
    $ ls -l
    
     drwxr-xr-x 2 sysadmin sysadmin 4096 Dec 23 02:58 bin
     drwxr-xr-x 3 sysadmin sysadmin 4096 Dec 23 03:39 include
     lrwxrwxrwx 1 sysadmin sysadmin    6 Dec 23 03:39 lib -> ../lib
     lrwxrwxrwx 1 sysadmin sysadmin    8 Dec 23 03:20 lib64 -> ../lib64
     lrwxrwxrwx 1 sysadmin sysadmin   10 Dec 23 03:39 sys-include -> ../include
    
  • Make sure the current directory is “openwrt”

    $HOME/openwrt
    
    $ make package/my_static_lib/compile
    

In this section you will learn about post build checks

  • Make sure the current directory is ‘my_static_lib-1.0’

    $HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0
    
    $ ls -l
    
    drwxr-xr-x 2 sysadmin sysadmin 4096 Jan  5 21:27 inc
    drwxr-xr-x 3 sysadmin sysadmin 4096 Jan  5 21:27 ipkg-aarch64_cortex-a72
    -rw-r--r-- 1 sysadmin sysadmin 2576 Jan  5 21:27 Makefile
    drwxr-xr-x 2 sysadmin sysadmin 4096 Jan  5 21:27 obj
    drwxr-xr-x 2 sysadmin sysadmin 4096 Jan  5 21:27 src
    
$ cd src

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 139 Jan  5 21:27 my_static_lib.c
$ cd inc

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 50 Jan  5 21:27 my_static_lib.h
$ cd obj

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 1756 Jan  5 21:27 libmy_static_lib.a
-rw-r--r-- 1 sysadmin sysadmin 1600 Jan  5 21:27 my_static_lib.o

See that object file called my_static_lib.o is present inside directory ?

See that .a file called libmy_static_lib.a is present inside directory ?

  • Let check objdump” output of the static library file

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

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0/obj

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 1756 Jan  7 10:04 libmy_static_lib.a
-rw-r--r-- 1 sysadmin sysadmin 1600 Jan  7 10:04 my_static_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/objdump libmy_static_lib.a -t | grep -i my_static_function

0000000000000000 g     F .text     000000000000000c my_static_function
  • objdump -S : Display source code intermixed with disassembly

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0/obj

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 1756 Jan  7 10:04 libmy_static_lib.a
-rw-r--r-- 1 sysadmin sysadmin 1600 Jan  7 10:04 my_static_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/objdump libmy_static_lib.a -S | grep -i my_static_function

0000000000000000 <my_static_function>:
0:      90000000        adrp    x0, 0 <my_static_function>

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

What “objdump” command does ?

  • Symbols “my_static_function” are present in .a static library file

  • Hence we can confirm application is compiled successfully

  • readelf -s: Display the symbol table

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0/obj

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 1756 Jan  7 10:04 libmy_static_lib.a
-rw-r--r-- 1 sysadmin sysadmin 1600 Jan  7 10:04 my_static_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/readelf libmy_static_lib.a -s | grep -i my_static_function

11: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 my_static_function

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

What “readelf” command does ?

What is the purpose of “readelf” command ?

  • Symbols “my_static_function” are present in .a static library file

  • Hence we can confirm application is compiled successfully

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

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0/obj

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 1756 Jan  7 10:04 libmy_static_lib.a
-rw-r--r-- 1 sysadmin sysadmin 1600 Jan  7 10:04 my_static_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/nm libmy_static_lib.a -S | grep -i my_static_function

0000000000000000 000000000000000c T my_static_function

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

What “nm” command does ?

What is the purpose of “nm” command ?

  • Symbols “my_static_function” are present in .a static library file

  • Hence we can confirm application is compiled successfully

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

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0/obj

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 1756 Jan  7 10:04 libmy_static_lib.a
-rw-r--r-- 1 sysadmin sysadmin 1600 Jan  7 10:04 my_static_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/nm libmy_static_lib.a -s | grep -i my_static_function

my_static_function in my_static_lib.o
0000000000000000 T my_static_function
  • Symbols “my_static_function” are present in .a static library file

  • Hence we can confirm application is compiled successfully

  • file: Determine file type

$ file libmy_static_lib.a

libmy_static_lib.a: current ar archive

Why “file” command is used ?

$ file my_static_lib.o

my_static_lib.o: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), not stripped
  • size: List section sizes and total size of binary files

$ size libmy_static_lib.a

  text    data     bss     dec     hex filename
  85         0       0      85      55 my_static_lib.o (ex libmy_static_lib.a)

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 libmy_static_lib.a | grep -i Hello

  Hello from my_static_function!

What “strings” command does ?

  • Make sure the current directory “openwrt”

$HOME/openwrt/staging_dir/packages/bcm27xx
$ ls -l | grep -i "my_static_lib"

 lrwxrwxrwx 1 sysadmin sysadmin 123 Jan  5 19:30 my_static_lib_1.0-1_aarch64_cortex-a72.ipk -> /home/test/openwrt/bin/packages/aarch64_cortex-a72/libs/my_static_lib_1.0-1_aarch64_cortex-a72.ipk
  • ipk file: It is compressed archive format derived from the Debian package (. DEB) format

What is “IPK” file ?

  • Make sure the current directory “openwrt”

$HOME/openwrt/staging_dir/packages/bcm27xx
  • Command to extract .ipk file is below

$ tar -xzf my_static_lib_1.0-1_aarch64_cortex-a72.ipk
$ ls

  control.tar.gz
  data.tar.gz
  debian-binary

what is the command to extract IPK file ?

  • First extract control.tar.gz and data.tar.gz

  • Command to check content for control.tar.gz file is below

$ tar -xzvf control.tar.gz

./control
./postinst
./prerm
  • Check ./control using “vim command”

$ vim ./control
  • Content of ./control

Package: my_static_lib
Version: 1.0-1
Depends: libc
Source: package/libs/static_lib/my_static_lib
SourceName: my_static_lib
Section: examples
SourceDateEpoch: 1703276774
Architecture: aarch64_cortex-a72
Installed-Size: 684
Description:  A simple static library example
  • Check inside for other files ./postinst and ./prerm using “vim” command

  • Command to check content for control.tar.gz file is below

$ tar -xzvf data.tar.gz

 ./usr/
 ./usr/lib/
 ./usr/lib/libmy_static_lib.a
  • Check ./usr/lib/libmy_static_lib.a is a static library file

In this section you will learn how to build full openwrt

  • Make sure the current directory “openwrt”

$HOME/openwrt
$ make -j1 V=s
  • It compile all packages

  • -j1: This option tells the build system work on one task at a time.

  • V=s: This sets the verbosity level to ‘s’, which means “silent” or “verbose.” When set to ‘s’, it makes the build system display more detailed information about what it’s doing. You’ll see the commands it’s running and the files it’s working on. This verbose output is helpful for understanding and debugging the build process.

  • Make sure the current directory “openwrt”

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

$HOME/openwrt/bin/targets/bcm27xx/bcm2711
  • To check the image file is present or not

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin      1655 Jan  5 19:29 config.buildinfo
-rw-r--r-- 1 sysadmin sysadmin        71 Jan  5 19:29 feeds.buildinfo
-rw-r--r-- 1 sysadmin sysadmin 184549376 Jan  5 16:04 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img
-rw-r--r-- 1 sysadmin sysadmin  17114759 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
-rw-r--r-- 1 sysadmin sysadmin  17115606 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4-ext4-sysupgrade.img.gz
-rw-r--r-- 1 sysadmin sysadmin      4210 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4.manifest
-rw-r--r-- 1 sysadmin sysadmin  15351510 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz
-rw-r--r-- 1 sysadmin sysadmin  15352357 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-sysupgrade.img.gz
drwxr-xr-x 2 sysadmin sysadmin      4096 Jan  5 19:30 packages
-rw-r--r-- 1 sysadmin sysadmin      2141 Jan  5 19:30 profiles.json
-rw-r--r-- 1 sysadmin sysadmin      1025 Jan  5 19:31 sha256sums
-rw-r--r-- 1 sysadmin sysadmin        18 Jan  5 19:29 version.buildinfo
  • As we can see “image” is present then it is confirmed that fully image is successfull

  • Image file is openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz

  • To extract image file command and pathis below

  • Make sure the current directory “openwrt”

$HOME/openwrt/bin/targets/bcm27xx/bcm2711
$ ls -l

-rw-r--r-- 1 sysadmin sysadmin      1655 Jan  5 19:29 config.buildinfo
-rw-r--r-- 1 sysadmin sysadmin        71 Jan  5 19:29 feeds.buildinfo
-rw-r--r-- 1 sysadmin sysadmin  17114759 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
-rw-r--r-- 1 sysadmin sysadmin  17115606 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4-ext4-sysupgrade.img.gz
-rw-r--r-- 1 sysadmin sysadmin      4210 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4.manifest
-rw-r--r-- 1 sysadmin sysadmin  15351510 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz
-rw-r--r-- 1 sysadmin sysadmin  15352357 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-sysupgrade.img.gz
drwxr-xr-x 2 sysadmin sysadmin      4096 Jan  5 19:30 packages
-rw-r--r-- 1 sysadmin sysadmin      2141 Jan  5 19:30 profiles.json
-rw-r--r-- 1 sysadmin sysadmin      1025 Jan  5 19:31 sha256sums
-rw-r--r-- 1 sysadmin sysadmin        18 Jan  5 19:29 version.buildinfo
  • Command to extract full image file

$ gunzip -d openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
  • After extracting image file check with ls command it will display below file

$ ls -l

 -rw-r--r-- 1 sysadmin sysadmin 184549376 Jan  5 19:30 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img
  • Content of full image file

  • The du (disk usage) that allows users to analyze and report on disk usage within directories and files.

  • Displays sizes in human-readable format, using units such as KB, MB, GB, etc.

$ du -h openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz

17M     openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
  • As we can see size of image file is around 17M

Note

PART B: Creating Static Application

In this section you will learn how to add custom built library in “Openwrt”

  • Make sure the current directory “openwrt”

    $ pwd
    
      /home/test/openwrt
    
  • Make sure the current directory “openwrt”

    $ cd package/libs/static_lib
    
    $ mkdir x_static_app
    
  • Make sure the current directory “x_static_app”

    $ cd x_static_app
    
    $ mkdir src obj inc
    
  • Make sure the current directory “x_static_app/src”

  • In app.c have “Function calling”

  • Create app.c file using vim command

vim app.c
  • Content of src/app.c

#include <stdio.h>
#include "my_static_lib.h"

extern void my_static_function(void);

int main(void)
{
       my_static_function();

       return 0;
}
  • Make sure the current directory “x_static_app/inc”

  • In my_static_lib.h have “Function Prototype”

  • Create my_static_lib.h file using vim command

vim my_static_lib.h
  • Content of inc/my_static_lib.h

#include <stdio.h>

void my_static_function(void);
  • Make sure the current directory “x_static_app”

  • Create Makefile file using vim command

    vim Makefile
    
  • Content of Makefile

    include $(TOPDIR)/rules.mk
    
    PKG_NAME:=x_static_app
    PKG_VERSION:=1.0
    PKG_RELEASE:=1
    
    SOURCE_DIR:=$(TOPDIR)/package/libs/static_lib/x_static_app
    
    include $(INCLUDE_DIR)/package.mk
    
    define Package/x_static_app
            SECTION:=examples
            CATEGORY:=Examples
            TITLE:=My Static Library
            DEPENDS:=+my_static_lib
    endef
    
    define Package/x_static_app/description
            A simple static library example
    endef
    
    define Build/Prepare
            mkdir -p $(PKG_BUILD_DIR)
            cp -r $(SOURCE_DIR)/src $(PKG_BUILD_DIR)
            cp -r $(SOURCE_DIR)/inc $(PKG_BUILD_DIR)
            cp -r $(SOURCE_DIR)/obj $(PKG_BUILD_DIR)
            cp $(SOURCE_DIR)/Makefile $(PKG_BUILD_DIR)
            $(Build/Patch)
    endef
    
    define Build/Compile
            $(TARGET_CC) -I$(PKG_BUILD_DIR)/inc $(PKG_BUILD_DIR)/src/app.c -L/home/test/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0/obj -l my_static_lib -o $(PKG_BUILD_DIR)/obj/app
    endef
    
    define Package/x_static_app/install
            $(INSTALL_DIR) $(1)/usr/bin
            $(INSTALL_BIN) $(PKG_BUILD_DIR)/obj/app $(1)/usr/bin/
    endef
    
    $(eval $(call BuildPackage,x_static_app))
    
  • Explanation of include $(TOPDIR)/rules.mk

    include $(TOPDIR)/rules.mk
    
  • The $(TOPDIR) is expected to be the top-level directory

  • /rules.mk - The path to the file included

What is $(TOPDIR) ?

  • Explanation of Package Name, Version and Release number Block

PKG_NAME:=x_static_app
PKG_VERSION:=1.0
PKG_RELEASE:=1
  • The name and version of your package are used to define the variable to point to the build directory of your package (Ex: a_static_app-1.0)

  • Explanation of SOURCE_DIR

SOURCE_DIR:=$(TOPDIR)/package/libs/static_lib/x_static_app

What is SOURCE_DIR ?

  • Give path of the source directory

  • SOURCE_DIR is used in Build/Prepare

  • Explanation of include $(INCLUDE_DIR)/package.mk

include $(INCLUDE_DIR)/package.mk
  • $(INCLUDE_DIR) - Directory containing include files

  • /package.mk: The path to the file included

What is $(INCLUDE_DIR) ?

  • Explanation of Package Information

define Package/x_static_app
   SECTION:=examples
   CATEGORY:=Examples
   TITLE:=My Static Library
   DEPENDS:=+my_static_lib
endef
  • This block defines the package information as section, category, and title

  • SECTION: examples: This line tells the section to which the package belongs. In this case, the package will come under the “examples” section.

  • CATEGORY: Examples: This line tells the category to which the package belongs. In this case, the category is set to “Examples

  • TITLE: My Static Library This line tells, title or name of the package. In this case, the title is set to “My Static Library”.

  • DEPENDS: =+my_static_lib: It is the library dependencies of the package.

  • endef: This line will be the end of the define block.

What all information included in Package Information Block ?

  • Explanation of Package Description

define Package/x_static_app/description
        A simple static library example
endef
  • This function defines of package.

What is Package Description Block ?

  • Explanation of Build/Prepare

define Build/Prepare
        mkdir -p $(PKG_BUILD_DIR)
        cp -r $(SOURCE_DIR)/src $(PKG_BUILD_DIR)
        cp -r $(SOURCE_DIR)/inc $(PKG_BUILD_DIR)
        cp -r $(SOURCE_DIR)/obj $(PKG_BUILD_DIR)
        cp $(SOURCE_DIR)/Makefile $(PKG_BUILD_DIR)
        $(Build/Patch)
endef
  • mkdir -p $(PKG_BUILD_DIR): This line creates the build directory

  • cp -r $(SOURCE_DIR)/src $(PKG_BUILD_DIR): This line copies the contents from SOURCE_DIR (source) to PKG_BUILD_DIR (destination)

  • cp -r $(SOURCE_DIR)/inc $(PKG_BUILD_DIR): This line copies the contents from SOURCE_DIR (source) to PKG_BUILD_DIR (destination)

  • cp -r $(SOURCE_DIR)/obj $(PKG_BUILD_DIR): This line copies the contents from SOURCE_DIR (source) to PKG_BUILD_DIR (destination)

  • cp -r $(SOURCE_DIR)Makefile $(PKG_BUILD_DIR): This line copies the contents from SOURCE_DIR (source) to PKG_BUILD_DIR (destination)

  • -r : -r is recursive copy.

  • $(Build/Patch): This line includes a call to $(Build/Patch), which is a variable or macro typically defined elsewhere in the Makefile. It is used to apply any necessary patches to the source code.

What is -r ?

Which path $(PKG_BUILD_DIR) ?

What is SOURCE_DIR ?

  • Explanation of Build/Compile

define Build/Compile
        $(TARGET_CC) -I$(PKG_BUILD_DIR)/inc $(PKG_BUILD_DIR)/src/app.c -L/home/test/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0/obj -l my_static_lib -o $(PKG_BUILD_DIR)/obj/app
endef
  • This block defines the compilation process.

  • $(TARGET_CC): It is said to arm cross compiler and it is defined globally

  • -I$(PKG_BUILD_DIR)/inc : It will include prototype path

  • $(PKG_BUILD_DIR)/src/app.c : .c file path

  • -L/home/test/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0/obj : Giving the path of .a file which already generated at “Static Library” side

  • l my_static_lib : It will link during the compilation process (should give 1 space after –l)

  • How to give path for -L

  • It is most important to check before giving path in “Static Application”

  • Before copying path to –L first we need to check objdump xxxxx.a (in this case libmy_static_lib.a) with –t or –dSs it will reflect with the symbol table if not symbol table reflect then this path should not be used in –L.

  • Check table of static library file

  • Make sure the current directory “openwrt”

    $HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_static_lib-1.0/obj
    
    $ ls -l
    
    -rw-r--r-- 1 sysadmin sysadmin 1756 Jan  5 21:27 libmy_static_lib.a
    -rw-r--r-- 1 sysadmin sysadmin 1600 Jan  5 21:27 my_static_lib.o
    
  • Check static library for table

    $HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/objdump libmy_static_lib.a -dSs | grep -i my_static_function
    
    0000000000000000 <my_static_function>:
    0:      90000000        adrp    x0, 0 <my_static_function>
    
  • We got the table so should give this path(.a file) to -L path in “Static Application”

What is -L ?

What is -l ?

  • Explanation of Package Install

define Package/x_static_app/install
        $(INSTALL_DIR) $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/obj/app $(1)/usr/bin/
endef
  • $(INSTALL_DIR): It used for creating a directory and it is commonly used in build systems like OpenWrt.

  • $(INSTALL_BIN): It used for copying an executable file.

  • In this case path of $(PKG_BUILD_DIR) $HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/x_static_app-1.0

  • /usr/bin: It is the destination directory, binary file will be installed.

What is $(INSTALL_DIR) ?

What is $(INSTALL_BIN) ?

What is $(1)/usr/bin ?

  • Explanation of Package Build

$(eval $(call BuildPackage,x_static_app))
  • BuildPackage: It is function call with x_static_app as parameter.

In this section you will learn how to add menuconfig

  • Make sure the current directory is “openwrt”

  • Create new feeds.conf file using vim command in openwrt directory

$ vim feeds.conf
  • Inside feeds.conf

src-link <name> <path>
  • Make sure the current directory is “openwrt”

  • Create new feeds.conf file using vim command in openwrt directory

src-link libs /home/test/openwrt/package/libs

In this section you will learn how to install and update feeds

  • Installs the most recent packages, replacing any earlier versions that were already on your system

$ ./scripts/feeds update -a

$ ./scripts/feeds install -a -f

In this section you will learn how to enable in menuconfig

  • Select your category that reflects in menuconfig

  • Go inside examples and select x_static_app

Diagram Diagram
Diagram
Diagram

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

  • In .config file package should be enabled in ‘y’

  • Below line should be present in .config file

    CONFIG_PACKAGE_x_static_app=y
    
  • Make sure the current directory “openwrt”

    $HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl
    
    $ ls -l
    
     drwxr-xr-x 2 sysadmin sysadmin 4096 Dec 23 02:58 bin
     drwxr-xr-x 3 sysadmin sysadmin 4096 Dec 23 03:39 include
     lrwxrwxrwx 1 sysadmin sysadmin    6 Dec 23 03:39 lib -> ../lib
     lrwxrwxrwx 1 sysadmin sysadmin    8 Dec 23 03:20 lib64 -> ../lib64
     lrwxrwxrwx 1 sysadmin sysadmin   10 Dec 23 03:39 sys-include -> ../include
    
  • Make sure the current directory is “openwrt”

    $HOME/openwrt
    
    $ make package/x_static_app/compile
    

In this section you will learn about post build checks

  • Make sure the current directory is ‘x_static_app-1.0’

    $HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/x_static_app-1.0
    
    $ ls -l
    
    drwxr-xr-x 2 sysadmin sysadmin 4096 Jan  6 01:09 inc
    drwxr-xr-x 3 sysadmin sysadmin 4096 Jan  6 01:09 ipkg-aarch64_cortex-a72
    -rw-r--r-- 1 sysadmin sysadmin 1700 Jan  6 01:09 Makefile
    drwxr-xr-x 2 sysadmin sysadmin 4096 Jan  6 01:09 obj
    drwxr-xr-x 2 sysadmin sysadmin 4096 Jan  6 01:09 src
    
$ cd src

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 140 Jan  6 01:09 app.c
$ cd inc

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin 50 Jan  6 01:09 my_static_lib.h
$ cd obj

$ ls -l

-rwxr-xr-x 1 sysadmin sysadmin 73080 Jan  6 01:09 app
  • Let check objdump” output of the static application file

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

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/x_static_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 sysadmin sysadmin 73080 Jan  7 10:04 app
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/objdump app -t | grep -i my_static_function

00000000004005b4 g     F .text     000000000000000c              my_static_function
  • objdump -S : Display source code intermixed with disassembly

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/x_static_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 sysadmin sysadmin 73080 Jan  7 10:04 app
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/objdump app -S | grep -i my_static_function

4005a4: 94000004        bl      4005b4 <my_static_function>
00000000004005b4 <my_static_function>:

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

What “objdump” command does ?

  • Symbols “my_static_function” are present in app binary file

  • Hence we can confirm application is compiled successfully

  • readelf -s: Display the symbol table

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/x_static_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 sysadmin sysadmin 73080 Jan  7 10:04 app
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/readelf app -s | grep -i my_static_function

76: 00000000004005b4    12 FUNC    GLOBAL DEFAULT   12 my_static_function

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

What “readelf” command does ?

What is the purpose of “readelf” command ?

  • Symbols “my_static_function” are present in app binary file

  • Hence we can confirm application is compiled successfully

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

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/x_static_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 sysadmin sysadmin 73080 Jan  7 10:04 app
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/nm app -S | grep -i my_static_function

00000000004005b4 000000000000000c T my_static_function

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

What “nm” command does ?

What is the purpose of “nm” command ?

  • Symbols “my_static_function” are present in binary file

  • Hence we can confirm application is compiled successfully

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

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

  • Make sure the current directory “obj”

$ pwd

$HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/x_static_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 sysadmin sysadmin 73080 Jan  7 10:04 app
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/nm app -s | grep -i my_static_function

00000000004005b4 T my_static_function
  • Symbols “my_static_function” are present in binary application file

  • Hence we can confirm application is compiled successfully

  • file: Determine file type

$ file app

app: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, with debug_info, 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
  1183     616      56    1855     73f 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 my_static_function

  Hello from my_static_function!
  my_static_function

What “strings” command does ?

  • Make sure the current directory “openwrt”

$HOME/openwrt/staging_dir/packages/bcm27xx
$ ls -l | grep -i "x_static_app"

 lrwxrwxrwx 1 sysadmin sysadmin 122 Jan  6 01:05 x_static_app_1.0-1_aarch64_cortex-a72.ipk -> /home/test/openwrt/bin/packages/aarch64_cortex-a72/libs/x_static_app_1.0-1_aarch64_cortex-a72.ipk
  • ipk file: It is compressed archive format derived from the Debian package (. DEB) format

What is “IPK” file ?

  • Make sure the current directory “openwrt”

$HOME/openwrt/staging_dir/packages/bcm27xx
  • Command to extract .ipk file is below

$ tar -xzf x_static_app_1.0-1_aarch64_cortex-a72.ipk
$ ls

  control.tar.gz
  data.tar.gz
  debian-binary

what is the command to extract IPK file ?

  • First extract control.tar.gz and data.tar.gz

  • Command to check content for control.tar.gz file is below

$ tar -xzvf control.tar.gz

./control
./postinst
./prerm
  • Check ./control using “vim command”

$ vim ./control
  • Content of ./control

Package: x_static_app
Version: 1.0-1
Depends: libc, my_static_lib
Source: package/libs/static_lib/x_static_app
SourceName: x_static_app
Section: examples
SourceDateEpoch: 1703276774
Architecture: aarch64_cortex-a72
Installed-Size: 1219
Description:  A simple static library example.
  • Check inside for other files ./postinst and ./prerm using “vim” command

  • Command to check content for control.tar.gz file is below

$ tar -xzvf data.tar.gz

 ./usr/
 ./usr/bin/
 ./usr/bin/app
  • Check ./usr/bin/app is a static application binary file

In this section you will learn how to build full openwrt

  • Make sure the current directory “openwrt”

$HOME/openwrt
$ make -j1 V=s
  • It compile all packages

  • -j1: This option tells the build system work on one task at a time.

  • V=s: This sets the verbosity level to ‘s’, which means “silent” or “verbose.” When set to ‘s’, it makes the build system display more detailed information about what it’s doing. You’ll see the commands it’s running and the files it’s working on. This verbose output is helpful for understanding and debugging the build process.

  • Make sure the current directory “openwrt”

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

$HOME/openwrt/bin/targets/bcm27xx/bcm2711
  • To check the image file is present or not

$ ls -l

-rw-r--r-- 1 sysadmin sysadmin     1685 Jan  6 01:04 config.buildinfo
-rw-r--r-- 1 sysadmin sysadmin       71 Jan  6 01:04 feeds.buildinfo
-rw-r--r-- 1 sysadmin sysadmin 17118352 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
-rw-r--r-- 1 sysadmin sysadmin 17119199 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4-ext4-sysupgrade.img.gz
-rw-r--r-- 1 sysadmin sysadmin     4231 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4.manifest
-rw-r--r-- 1 sysadmin sysadmin 15352083 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz
-rw-r--r-- 1 sysadmin sysadmin 15352930 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-sysupgrade.img.gz
drwxr-xr-x 2 sysadmin sysadmin     4096 Jan  6 01:05 packages
-rw-r--r-- 1 sysadmin sysadmin     2141 Jan  6 01:06 profiles.json
-rw-r--r-- 1 sysadmin sysadmin      912 Jan  6 01:06 sha256sums
-rw-r--r-- 1 sysadmin sysadmin       18 Jan  6 01:04 version.buildinfo
  • As we can see “image” is present then it is confirmed that fully image is successfull

  • Image file is openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz

  • To extract image file command and pathis below

  • Make sure the current directory “openwrt”

$HOME/openwrt/bin/targets/bcm27xx/bcm2711
$ ls -l

-rw-r--r-- 1 sysadmin sysadmin     1685 Jan  6 01:04 config.buildinfo
-rw-r--r-- 1 sysadmin sysadmin       71 Jan  6 01:04 feeds.buildinfo
-rw-r--r-- 1 sysadmin sysadmin 17118352 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
-rw-r--r-- 1 sysadmin sysadmin 17119199 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4-ext4-sysupgrade.img.gz
-rw-r--r-- 1 sysadmin sysadmin     4231 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4.manifest
-rw-r--r-- 1 sysadmin sysadmin 15352083 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz
-rw-r--r-- 1 sysadmin sysadmin 15352930 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-sysupgrade.img.gz
drwxr-xr-x 2 sysadmin sysadmin     4096 Jan  6 01:05 packages
-rw-r--r-- 1 sysadmin sysadmin     2141 Jan  6 01:06 profiles.json
-rw-r--r-- 1 sysadmin sysadmin      912 Jan  6 01:06 sha256sums
-rw-r--r-- 1 sysadmin sysadmin       18 Jan  6 01:04 version.buildinfo
  • Command to extract full image file

$ gunzip -d openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
  • After extracting image file check with ls command it will display below file

$ ls -l

 -rw-r--r-- 1 sysadmin sysadmin 184549376 Jan  6 01:05 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img
  • Content of full image file

  • The du (disk usage) that allows users to analyze and report on disk usage within directories and files.

  • Displays sizes in human-readable format, using units such as KB, MB, GB, etc.

    $ du -h openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
    
    17M     openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
    
  • As we can see size of image file is around 17M