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.InstallDevexports headers + libs to staging_dir.
make package/custom_sharedlib/{clean,compile} V=s
cleanresets previous builds.compileproduces.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/liband/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_mathpulls 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.