Open-Wrt: Add shared library

What is Shared Library ?

How to create a shared library in Open-WRT ?

How to link shared 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 SHARED LIBRARY

Topics in this section,

PART B: CREATING SHARED APPLICATION

Note

PART A: Creating Shared Library

Note

Create 2 folders in alphabet order so that library side makefile should execute first and it will create .so shared 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 shared_lib/my_shared_lib
    
  • Make sure the current directory “my_shared_lib”

    $ cd my_shared_lib
    
  • Make sure the current directory “my_shared_lib/src”

  • In my_shared_lib.c have “Function Definition”

  • Create my_shared_lib.c file using vim command

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

#include "my_shared_lib.h"

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

  • In my_shared_lib.h have “Function Prototype”

  • Create my_shared_lib.h file using vim command

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

#include <stdio.h>

void my_shared_function(void);

What is Shared Library ?

What are the types of library ?

What is the use of library ?

  • Make sure the current directory “my_shared_lib”

  • Create Makefile file using vim command

    vim Makefile
    
  • Content of Makefile

    include $(TOPDIR)/rules.mk
    
    PKG_NAME:=my_shared_lib
    PKG_VERSION:=1.0
    PKG_RELEASE:=1
    
    SOURCE_DIR:=/home/test/openwrt_src/openwrt/package/libs/shared_lib/my_shared_lib
    
    include $(INCLUDE_DIR)/package.mk
    
    define Package/my_shared_lib
            SECTION:=examples
            CATEGORY:=Examples
            TITLE:=My Shared Library
    endef
    
    define Package/my_shared_lib/description
            A simple shared 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 -fPIC -o $(PKG_BUILD_DIR)/obj/my_shared_lib.o -c $(PKG_BUILD_DIR)/src/my_shared_lib.c
            $(TARGET_CC) $(TARGET_CFLAGS) -shared -fPIC -g -o $(PKG_BUILD_DIR)/obj/libmy_shared_lib.so $(PKG_BUILD_DIR)/obj/my_shared_lib.o
    
    endef
    
    
    define Package/my_shared_lib/install
            $(INSTALL_DIR) $(1)/usr/lib
            $(INSTALL_BIN) $(PKG_BUILD_DIR)/obj/libmy_shared_lib.so $(1)/usr/lib/
    endef
    
    $(eval $(call BuildPackage,my_shared_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_shared_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_shared_lib-1.0)

  • Explanation of SOURCE_DIR

SOURCE_DIR:=$(TOPDIR)/package/libs/shared_lib/my_shared_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_shared_lib
   SECTION:=examples
   CATEGORY:=Examples
   TITLE:=My Shared 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 Shared Library This line tells, title or name of the package. In this case, the title is set to “My Shared 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_shared_lib/description
        A simple shared 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 -fPIC -o $(PKG_BUILD_DIR)/obj/my_shared_lib.o -c $(PKG_BUILD_DIR)/src/my_shared_lib.c
        $(TARGET_CC) $(TARGET_CFLAGS) -shared -fPIC -g -o $(PKG_BUILD_DIR)/obj/libmy_shared_lib.so $(PKG_BUILD_DIR)/obj/my_shared_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

  • -fPIC: fPIC is to generate position-independent code

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

  • -shared: -shared instructs the compiler that we are building a shared library

  • -g: -g is to leave debugging information in the output file

  • $(PKG_BUILD_DIR)/obj/libmy_shared_lib.so : Takes .o input file location $(PKG_BUILD_DIR)/obj/my_shared_lib.o and generates .so output file in location $(PKG_BUILD_DIR)/obj

What is $(TARGET_CC) ?

What is $(TARGET_CFLAGS) ?

  • Explanation of Package Install

define Package/my_shared_lib/install
        $(INSTALL_DIR) $(1)/usr/lib
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/obj/libmy_shared_lib.so $(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_shared_lib-1.0

  • /usr/bin: It is the destination directory, .so 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_shared_lib))
  • BuildPackage: It is function call with my_shared_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_shared_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_shared_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 test test 4096 Dec 23 02:58 bin
     drwxr-xr-x 3 test test 4096 Dec 23 03:39 include
     lrwxrwxrwx 1 test test    6 Dec 23 03:39 lib -> ../lib
     lrwxrwxrwx 1 test test    8 Dec 23 03:20 lib64 -> ../lib64
     lrwxrwxrwx 1 test test   10 Dec 23 03:39 sys-include -> ../include
    
  • Make sure the current directory is “openwrt”

    $HOME/openwrt
    
    $ make package/my_shared_lib/compile
    

In this section you will learn about post build checks

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

    $HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_shared_lib-1.0
    
    $ ls -l
    
    drwxr-xr-x 2 test test 4096 Jan  8 21:36 inc
    drwxr-xr-x 3 test test 4096 Jan  8 21:36 ipkg-aarch64_cortex-a72
    -rw-r--r-- 1 test test 1794 Jan  8 21:36 Makefile
    drwxr-xr-x 2 test test 4096 Jan  8 21:36 obj
    drwxr-xr-x 2 test test 4096 Jan  8 21:36 src
    
$ cd src

$ ls -l

-rw-r--r-- 1 test test 128 Jan  8 21:36 my_shared_lib.c
$ cd inc

$ ls -l

-rw-r--r-- 1 test test 47 Jan  8 21:36 my_shared_lib.h
$ cd obj

$ ls -l

-rwxr-xr-x 1 test test 70648 Jan  8 21:36 libmy_shared_lib.so
-rw-r--r-- 1 test test  1624 Jan  8 21:36 my_shared_lib.o

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

See that .so file called libmy_shared_lib.so is present inside directory ?

  • Let check objdump” output of the shared library file

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

  • Check if “my_shared_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_shared_lib-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 70648 Jan  8 21:36 libmy_shared_lib.so
-rw-r--r-- 1 test test  1624 Jan  8 21:36 my_shared_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/objdump libmy_shared_lib.so -t | grep -i my_shared_function

00000000000004e4 g     F .text     0000000000000014              my_shared_function
  • objdump -S : Display source code intermixed with disassembly

  • Check if “my_shared_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_shared_lib-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 70648 Jan  8 21:36 libmy_shared_lib.so
-rw-r--r-- 1 test test  1624 Jan  8 21:36 my_shared_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/objdump libmy_shared_lib.so -S | grep -i my_shared_function

00000000000004e4 <my_shared_function>:

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

What “objdump” command does ?

  • Symbols “my_shared_function” are present in .so shared library file

  • Hence we can confirm application is compiled successfully

  • readelf -s: Display the symbol table

  • Check if “my_shared_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_shared_lib-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 70648 Jan  8 21:36 libmy_shared_lib.so
-rw-r--r-- 1 test test  1624 Jan  8 21:36 my_shared_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/readelf libmy_shared_lib.so -s | grep -i my_shared_function

7: 00000000000004e4    20 FUNC    GLOBAL DEFAULT    9 my_shared_function
60: 00000000000004e4    20 FUNC    GLOBAL DEFAULT    9 my_shared_function

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

What “readelf” command does ?

What is the purpose of “readelf” command ?

  • Symbols “my_shared_function” are present in .so shared 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_shared_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_shared_lib-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 70648 Jan  8 21:36 libmy_shared_lib.so
-rw-r--r-- 1 test test  1624 Jan  8 21:36 my_shared_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/nm libmy_shared_lib.so -S | grep -i my_shared_function

00000000000004e4 0000000000000014 T my_shared_function

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

What “nm” command does ?

What is the purpose of “nm” command ?

  • Symbols “my_shared_function” are present in .so shared 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_shared_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_shared_lib-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 70648 Jan  8 21:36 libmy_shared_lib.so
-rw-r--r-- 1 test test  1624 Jan  8 21:36 my_shared_lib.o
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/nm libmy_shared_lib.so -s | grep -i my_shared_function

00000000000004e4 T my_shared_function
  • Symbols “my_shared_function” are present in .so shared library file

  • Hence we can confirm application is compiled successfully

  • file: Determine file type

$ file libmy_shared_lib.so

libmy_shared_lib.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, with debug_info, not stripped

Why “file” command is used ?

$ file my_shared_lib.o

my_shared_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_shared_lib.a

  text    data     bss     dec     hex filename
  1053     536      56    1645     66d libmy_shared_lib.so

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_shared_lib.so | grep -i Hello

  Hello from my_shared_function!

What “strings” command does ?

  • Make sure the current directory “openwrt”

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

lrwxrwxrwx 1 test test 123 Jan  8 21:36 my_shared_lib_1.0-1_aarch64_cortex-a72.ipk -> /home/test/openwrt/bin/packages/aarch64_cortex-a72/libs/my_shared_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_shared_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_shared_lib
Version: 1.0-1
Depends: libc
Source: package/libs/shared_lib/my_shared_lib
SourceName: my_shared_lib
Section: examples
SourceDateEpoch: 1703276774
Architecture: aarch64_cortex-a72
Installed-Size: 1056
Description:  A simple shared 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_shared_lib.so
  • Check ./usr/lib/libmy_shared_lib.so is a shared 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 test test     1655 Jan  8 21:35 config.buildinfo
-rw-r--r-- 1 test test       71 Jan  8 21:35 feeds.buildinfo
-rw-r--r-- 1 test test 17116537 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
-rw-r--r-- 1 test test 17117384 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4-ext4-sysupgrade.img.gz
-rw-r--r-- 1 test test     4210 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4.manifest
-rw-r--r-- 1 test test 15351092 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz
-rw-r--r-- 1 test test 15351939 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-sysupgrade.img.gz
drwxr-xr-x 2 test test     4096 Jan  8 21:37 packages
-rw-r--r-- 1 test test     2141 Jan  8 21:37 profiles.json
-rw-r--r-- 1 test test      912 Jan  8 21:37 sha256sums
-rw-r--r-- 1 test test       18 Jan  8 21:35 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 test test     1655 Jan  8 21:35 config.buildinfo
-rw-r--r-- 1 test test       71 Jan  8 21:35 feeds.buildinfo
-rw-r--r-- 1 test test 17116537 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
-rw-r--r-- 1 test test 17117384 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4-ext4-sysupgrade.img.gz
-rw-r--r-- 1 test test     4210 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4.manifest
-rw-r--r-- 1 test test 15351092 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz
-rw-r--r-- 1 test test 15351939 Jan  8 21:37 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-sysupgrade.img.gz
drwxr-xr-x 2 test test     4096 Jan  8 21:37 packages
-rw-r--r-- 1 test test     2141 Jan  8 21:37 profiles.json
-rw-r--r-- 1 test test      912 Jan  8 21:37 sha256sums
-rw-r--r-- 1 test test       18 Jan  8 21:35 version.buildinfo
  • Command to extract full image file

$ gunzip -d openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
  • 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 Shared 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/shared_lib
    
    $ mkdir x_shared_app
    
  • Make sure the current directory “x_shared_app”

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

  • In app.c have “Function Definition”

  • Create app.c file using vim command

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

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

extern void my_shared_function(void);

int main(void)
{
       my_shared_function();

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

  • In my_shared_lib.h have “Function Prototype”

  • Create my_shared_lib.h file using vim command

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

#include <stdio.h>

void my_shared_function(void);
  • Make sure the current directory “x_shared_app”

  • Create Makefile file using vim command

    vim Makefile
    
  • Content of Makefile

    
    

    include $(TOPDIR)/rules.mk

    PKG_NAME:=x_shared_app PKG_VERSION:=1.0 PKG_RELEASE:=1

    SOURCE_DIR:=$(TOPDIR)/package/libs/shared_lib/x_shared_app

    include $(INCLUDE_DIR)/package.mk

    define Package/x_shared_app SECTION:=examples CATEGORY:=Examples TITLE:=My Shared Library DEPENDS:=+my_shared_lib endef

    define Package/x_shared_app/description A simple shared 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 -L/home/test/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_shared_lib-1.0/obj -o $(PKG_BUILD_DIR)/obj/app $(PKG_BUILD_DIR)/src/app.c -l my_shared_lib endef

    define Package/x_shared_app/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/obj/app $(1)/usr/bin/ endef

    $(eval $(call BuildPackage,x_shared_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_shared_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: x_shared_app-1.0)

  • Explanation of SOURCE_DIR

SOURCE_DIR:=$(TOPDIR)/package/libs/shared_lib/x_shared_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_shared_app
   SECTION:=examples
   CATEGORY:=Examples
   TITLE:=My Shared Library
   DEPENDS:=+my_shared_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 Shared Library This line tells, title or name of the package. In this case, the title is set to “My Shared Library”.

  • DEPENDS: =+my_shared_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_shared_app/description
        A simple shared 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 -L/home/test/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_shared_lib-1.0/obj -o $(PKG_BUILD_DIR)/obj/app $(PKG_BUILD_DIR)/src/app.c -l my_shared_lib
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_shared_lib-1.0/obj : Giving the path of .so file which already generated at “Shared Library” side

  • l my_shared_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 “Shared Application”

  • Before copying path to –L first we need to check objdump xxxxx.so (in this case libmy_shared_lib.so) 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 shared library file

  • Make sure the current directory “openwrt”

    $HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/my_shared_lib-1.0/obj
    
    $ ls -l
    
    -rwxr-xr-x 1 test test 70648 Jan  8 21:36 libmy_shared_lib.so
    -rw-r--r-- 1 test test  1624 Jan  8 21:36 my_shared_lib.o
    
  • Check shared library for table

    $HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/objdump libmy_shared_lib.so -dSs | grep -i my_shared_function
    
    00000000000004e4 <my_shared_function>:
    
  • We got the table so should give this path(.so file) to -L path in “Shared Application”

What is -L ?

What is -l ?

  • Explanation of Package Install

define Package/x_shared_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_shared_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_shared_app))
  • BuildPackage: It is function call with x_shared_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_shared_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_shared_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 test test 4096 Dec 23 02:58 bin
     drwxr-xr-x 3 test test 4096 Dec 23 03:39 include
     lrwxrwxrwx 1 test test    6 Dec 23 03:39 lib -> ../lib
     lrwxrwxrwx 1 test test    8 Dec 23 03:20 lib64 -> ../lib64
     lrwxrwxrwx 1 test test   10 Dec 23 03:39 sys-include -> ../include
    
  • Make sure the current directory is “openwrt”

    $HOME/openwrt
    
    $ make package/x_shared_app/compile
    

In this section you will learn about post build checks

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

    $HOME/openwrt/build_dir/target-aarch64_cortex-a72_musl/x_shared_app-1.0
    
    $ ls -l
    
    drwxr-xr-x 2 test test 4096 Jan  8 23:03 inc
    drwxr-xr-x 3 test test 4096 Jan  8 23:03 ipkg-aarch64_cortex-a72
    -rw-r--r-- 1 test test 1280 Jan  8 23:03 Makefile
    drwxr-xr-x 2 test test 4096 Jan  8 23:03 obj
    drwxr-xr-x 2 test test 4096 Jan  8 23:03 src
    
$ cd src

$ ls -l

-rw-r--r-- 1 test test 141 Jan  8 23:03 app.c
$ cd inc

$ ls -l

-rw-r--r-- 1 test test 46 Jan  8 23:03 my_shared_lib.h
$ cd obj

$ ls -l

-rwxr-xr-x 1 test test 72736 Jan  8 23:03 app
  • Let check objdump” output of the shared application file

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

  • Check if “my_shared_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_shared_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 72736 Jan  8 23:03 app
$HOME/openwrt/staging_dir/toolchain-aarch64_cortex-a72_gcc-12.3.0_musl/aarch64-openwrt-linux-musl/bin/objdump app -t | grep my_shared_function

0000000000000000       F *UND*     0000000000000000              my_shared_function
  • objdump -S : Display source code intermixed with disassembly

  • Check if “my_shared_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_shared_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 72736 Jan  8 23:03 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_shared_function

00000000004004f0 <my_shared_functionplt>:
400528: 97fffff2        bl      4004f0 <my_shared_functionplt>

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

What “objdump” command does ?

  • Symbols “my_shared_function” are present in app binary file

  • Hence we can confirm application is compiled successfully

  • readelf -s: Display the symbol table

  • Check if “my_shared_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_shared_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 72736 Jan  8 23:03 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_shared_function

2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND my_shared_function
68: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND my_shared_function

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

What “readelf” command does ?

What is the purpose of “readelf” command ?

  • Symbols “my_shared_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_shared_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_shared_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 72736 Jan  8 23:03 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_shared_function

U my_shared_function

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

What “nm” command does ?

What is the purpose of “nm” command ?

  • Symbols “my_shared_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_shared_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_shared_app-1.0/obj

$ ls -l

-rwxr-xr-x 1 test test 72736 Jan  8 23:03 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_shared_function

U my_shared_function
  • Symbols “my_shared_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
  1144     664      56    1864     748 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_shared_function

  my_shared_function
  my_shared_function

What “strings” command does ?

  • Make sure the current directory “openwrt”

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

 lrwxrwxrwx 1 test test 122 Jan  8 22:45 x_shared_app_1.0-1_aarch64_cortex-a72.ipk -> /home/test/openwrt/bin/packages/aarch64_cortex-a72/libs/x_shared_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_shared_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_shared_app
Version: 1.0-1
Depends: libc, my_shared_lib
Source: package/libs/shared_lib/x_shared_app
SourceName: x_shared_app
Section: examples
SourceDateEpoch: 1703276774
Architecture: aarch64_cortex-a72
Installed-Size: 1201
Description:  A simple shared 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 shared 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 test test     1685 Jan  8 22:44 config.buildinfo
-rw-r--r-- 1 test test       71 Jan  8 22:44 feeds.buildinfo
-rw-r--r-- 1 test test 17118327 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
-rw-r--r-- 1 test test 17119174 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4-ext4-sysupgrade.img.gz
-rw-r--r-- 1 test test     4231 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4.manifest
-rw-r--r-- 1 test test 15351852 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz
-rw-r--r-- 1 test test 15352699 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-sysupgrade.img.gz
drwxr-xr-x 2 test test     4096 Jan  8 22:45 packages
-rw-r--r-- 1 test test     2141 Jan  8 22:45 profiles.json
-rw-r--r-- 1 test test      912 Jan  8 22:46 sha256sums
-rw-r--r-- 1 test test       18 Jan  8 22:44 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 test test     1685 Jan  8 22:44 config.buildinfo
-rw-r--r-- 1 test test       71 Jan  8 22:44 feeds.buildinfo
-rw-r--r-- 1 test test 17118327 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
-rw-r--r-- 1 test test 17119174 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4-ext4-sysupgrade.img.gz
-rw-r--r-- 1 test test     4231 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4.manifest
-rw-r--r-- 1 test test 15351852 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz
-rw-r--r-- 1 test test 15352699 Jan  8 22:45 openwrt-bcm27xx-bcm2711-rpi-4-squashfs-sysupgrade.img.gz
drwxr-xr-x 2 test test     4096 Jan  8 22:45 packages
-rw-r--r-- 1 test test     2141 Jan  8 22:45 profiles.json
-rw-r--r-- 1 test test      912 Jan  8 22:46 sha256sums
-rw-r--r-- 1 test test       18 Jan  8 22:44 version.buildinfo
  • Command to extract full image file

$ gunzip -d openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
  • 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