OpenWrt: Adding a Shared Library

This document explains how to create, build, package, install, and test a shared library (libcustom_math.so) inside the OpenWrt build system.

In this section, you are going to learn:

How to organize and structure a shared library in OpenWrt?

How to export headers and shared objects to staging and rootfs?

How to build and link applications dynamically using OpenWrt’s toolchain?

Topics in this section:

  • Step 1: Create Shared Library Directory

  • Step 1.1: Technical Notes

  • Step 2: Add Library Source Files

  • Step 2.1: Technical Notes

  • Step 3: Create Shared Library Makefile

  • Step 3.1: Technical Notes

  • Step 4: Build the Shared Library

  • Step 4.1: Technical Notes

  • Step 5: Verify Build Output

  • Step 5.1: Technical Notes

  • Step 6: Install Shared Library on OpenWrt VM

  • Step 6.1: Technical Notes

  • Step 7: Create the Test Application

  • Step 7.1: Technical Notes

  • Step 8: Test Application Makefile

  • Step 8.1: Technical Notes

  • Step 9: Build the Test Application

  • Step 9.1: Technical Notes

  • Step 10: Install & Run the Test Application

  • Step 10.1: Technical Notes

mkdir -p package/custom_sharedlib/src
  • Package folder detected automatically.

  • src/ contains clean upstream-like code.

custom_math.c

int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return (b != 0) ? (a/b) : 0; }

custom_math.h

int multiply(int a, int b);
int divide(int a, int b);
  • Library functions exposed via header.

  • Header will be installed under /usr/include/custom_math.

include $(TOPDIR)/rules.mk
PKG_NAME:=custom_sharedlib
include $(INCLUDE_DIR)/package.mk

define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    $(CP) ./src/* $(PKG_BUILD_DIR)/
endef

define Build/Compile
    $(TARGET_CC) $(TARGET_CFLAGS) -fPIC \
        -c $(PKG_BUILD_DIR)/custom_math.c \
        -o $(PKG_BUILD_DIR)/custom_math.o

    $(TARGET_CC) -shared -Wl,-soname,libcustom_math.so.1 \
        $(PKG_BUILD_DIR)/custom_math.o \
        -o $(PKG_BUILD_DIR)/libcustom_math.so.1
endef

define Build/InstallDev
    $(INSTALL_DIR) $(1)/usr/lib
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/libcustom_math.so.1 $(1)/usr/lib/
    $(LN) libcustom_math.so.1 $(1)/usr/lib/libcustom_math.so
    $(INSTALL_DIR) $(1)/usr/include/custom_math
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/custom_math.h $(1)/usr/include/custom_math/
endef

define Package/custom_sharedlib/install
    $(INSTALL_DIR) $(1)/usr/lib
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/libcustom_math.so.1 $(1)/usr/lib/
    $(LN) libcustom_math.so.1 $(1)/usr/lib/libcustom_math.so
    $(INSTALL_DIR) $(1)/usr/include/custom_math
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/custom_math.h $(1)/usr/include/custom_math/
endef

$(eval $(call BuildPackage,custom_sharedlib))
  • Shared library must use -fPIC.

  • InstallDev exports headers + libs to staging_dir.

make package/custom_sharedlib/{clean,compile} V=s
  • clean resets previous builds.

  • compile produces .so.1 + symlink.

Expected output:

libcustom_math.so.1
libcustom_math.so
custom_math.h
  • Header and library included in APK.

scp -P 2223 custom_sharedlib-1.apk root@127.0.0.1:/tmp/
apk add --allow-untrusted /tmp/custom_sharedlib-1.apk
  • Installed into /usr/lib and /usr/include.

test.c

#include <custom_math/custom_math.h>
int main(){
    printf("%d %d", multiply(12,3), divide(12,3));
    return 0;
}
  • Test program dynamically links to libcustom_math.so.

DEPENDS:=+custom_sharedlib

define Build/Compile
    $(TARGET_CC) -I$(STAGING_DIR)/usr/include/custom_math \
        -L$(STAGING_DIR)/usr/lib \
        test.c -lcustom_math -o test_math
endef
  • -lcustom_math pulls shared library.

make package/custom_sharedlib-test/{clean,compile} V=s
  • Output: custom_sharedlib-test-1.apk.

apk add --allow-untrusted /tmp/custom_sharedlib-test-1.apk
test_math

Expected:

multiply = 36
divide   = 4
  • Confirms proper dynamic linking.