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: .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to organize and structure a shared library in OpenWrt? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to export headers and shared objects to staging and rootfs? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to build and link applications dynamically using OpenWrt’s toolchain? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow 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 .. tab-set:: .. tab-item:: Step 1: Create Shared Library Directory .. code-block:: bash mkdir -p package/custom_sharedlib/src .. tab-item:: Step 1.1: Technical Notes - Package folder detected automatically. - ``src/`` contains clean upstream-like code. .. tab-set:: .. tab-item:: Step 2: Add Library Source Files ``custom_math.c`` .. code-block:: 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`` .. code-block:: c int multiply(int a, int b); int divide(int a, int b); .. tab-item:: Step 2.1: Technical Notes - Library functions exposed via header. - Header will be installed under ``/usr/include/custom_math``. .. tab-set:: .. tab-item:: Step 3: Create Shared Library Makefile .. code-block:: make 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)) .. tab-item:: Step 3.1: Technical Notes - Shared library must use ``-fPIC``. - ``InstallDev`` exports headers + libs to staging_dir. .. tab-set:: .. tab-item:: Step 4: Build the Shared Library .. code-block:: bash make package/custom_sharedlib/{clean,compile} V=s .. tab-item:: Step 4.1: Technical Notes - ``clean`` resets previous builds. - ``compile`` produces ``.so.1`` + symlink. .. tab-set:: .. tab-item:: Step 5: Verify Build Output Expected output: :: libcustom_math.so.1 libcustom_math.so custom_math.h .. tab-item:: Step 5.1: Technical Notes - Header and library included in APK. .. tab-set:: .. tab-item:: Step 6: Install Shared Library on VM .. code-block:: bash scp -P 2223 custom_sharedlib-1.apk root@127.0.0.1:/tmp/ apk add --allow-untrusted /tmp/custom_sharedlib-1.apk .. tab-item:: Step 6.1: Technical Notes - Installed into ``/usr/lib`` and ``/usr/include``. .. tab-set:: .. tab-item:: Step 7: Create the Test Application ``test.c`` .. code-block:: c #include int main(){ printf("%d %d", multiply(12,3), divide(12,3)); return 0; } .. tab-item:: Step 7.1: Technical Notes - Test program dynamically links to ``libcustom_math.so``. .. tab-set:: .. tab-item:: Step 8: Test Application Makefile .. code-block:: make 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 .. tab-item:: Step 8.1: Technical Notes - ``-lcustom_math`` pulls shared library. .. tab-set:: .. tab-item:: Step 9: Build the Test Application .. code-block:: bash make package/custom_sharedlib-test/{clean,compile} V=s .. tab-item:: Step 9.1: Technical Notes - Output: ``custom_sharedlib-test-1.apk``. .. tab-set:: .. tab-item:: Step 10: Install & Run It on OpenWrt .. code-block:: bash apk add --allow-untrusted /tmp/custom_sharedlib-test-1.apk test_math Expected: :: multiply = 36 divide = 4 .. tab-item:: Step 10.1: Technical Notes - Confirms proper dynamic linking.