OpenWrt: Adding Patches to a Shared Library ========================================================== This document explains how to: - Create a shared library (``libbar.so``) - Apply patches to modify its behavior - Export the library + headers to OpenWrt - Build a test application that dynamically links against the patched library - Install and run these components on OpenWrt This demonstrates how OpenWrt’s patching system, shared library workflow, and dynamic linking infrastructure operate. In this section, you are going to learn: .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to patch and build 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 into staging & rootfs? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to build dynamic applications that link against patched libraries? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section: * Step 1: Directory Layout * Step 1.1: Technical Notes * Step 2: Source Files * Step 2.1: Technical Notes * Step 3: Patch File * Step 3.1: Technical Notes * Step 4: Shared Library Makefile * Step 4.1: Technical Notes * Step 5: Build Shared Library * Step 5.1: Technical Notes * Step 6: Install Shared Library on OpenWrt VM * Step 6.1: Technical Notes * Step 7: Test Application Directory Structure * Step 7.1: Technical Notes * Step 8: Test Application Patch * Step 8.1: Technical Notes * Step 9: Test Application Makefile * Step 9.1: Technical Notes * Step 10: Build & Install Test Application * Step 10.1: Technical Notes .. _owrt_libbar_step1: .. _owrt_libbar_step1_1: .. tab-set:: .. tab-item:: Step 1: Directory Layout :: package/my/libbar/ ├── Makefile ├── patches/ │ └── 0001-modify-behavior.patch └── src/ ├── bar.c └── bar.h .. tab-item:: Step 1.1: Technical Notes - ``patches/`` contains quilt-formatted patches. - All patches applied automatically via ``Build/Patch``. - Shared library objects must be built with ``-fPIC``. .. _owrt_libbar_step2: .. _owrt_libbar_step2_1: .. tab-set:: .. tab-item:: Step 2: Source Files ``bar.h`` .. code-block:: c int bar_mul(int a, int b); ``bar.c`` .. code-block:: c #include "bar.h" int bar_mul(int a, int b) { return a * b; } .. tab-item:: Step 2.1: Technical Notes - ``bar.h`` exported to ``/usr/include``. - ``bar.c`` patched before compile. .. _owrt_libbar_step3: .. _owrt_libbar_step3_1: .. tab-set:: .. tab-item:: Step 3: Patch File ``0001-modify-behavior.patch`` .. code-block:: diff --- a/bar.c +++ b/bar.c @@ -1,5 +1,5 @@ int bar_mul(int a, int b) { - return a * b; + return (a * b) + 2; } .. tab-item:: Step 3.1: Technical Notes - Patch modifies computation. - Applied before ``Build/Compile``. .. _owrt_libbar_step4: .. _owrt_libbar_step4_1: .. tab-set:: .. tab-item:: Step 4: Shared Library Makefile .. code-block:: make include $(TOPDIR)/rules.mk PKG_NAME:=libbar PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define Package/libbar SECTION:=libs CATEGORY:=Libraries TITLE:=Simple shared bar library endef define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ $(call Build/Patch,$(PKG_BUILD_DIR)) endef define Build/Compile $(TARGET_CC) $(TARGET_CFLAGS) -fPIC -c \ $(PKG_BUILD_DIR)/bar.c \ -o $(PKG_BUILD_DIR)/bar.o $(TARGET_CC) -shared -o $(PKG_BUILD_DIR)/libbar.so \ $(PKG_BUILD_DIR)/bar.o endef define Build/InstallDev $(INSTALL_DIR) $(1)/usr/include $(INSTALL_DATA) $(PKG_BUILD_DIR)/bar.h $(1)/usr/include/ $(INSTALL_DIR) $(1)/usr/lib $(INSTALL_DATA) $(PKG_BUILD_DIR)/libbar.so $(1)/usr.lib/ endef define Package/libbar/install $(INSTALL_DIR) $(1)/usr/include $(INSTALL_DATA) $(PKG_BUILD_DIR)/bar.h $(1)/usr/include/ $(INSTALL_DIR) $(1)/usr/lib $(INSTALL_DATA) $(PKG_BUILD_DIR)/libbar.so $(1)/usr/lib/ endef $(eval $(call BuildPackage,libbar)) .. tab-item:: Step 4.1: Technical Notes - ``Build/Patch`` transforms code before compile. - ``-fPIC`` ensures relocatable shared object. - Headers + library exported to staging + rootfs. .. _owrt_libbar_step5: .. _owrt_libbar_step5_1: .. tab-set:: .. tab-item:: Step 5: Build Shared Library .. code-block:: bash make package/my/libbar/compile V=s .. tab-item:: Step 5.1: Technical Notes - Result contains patched ``libbar.so``. - Output placed in ``bin/packages/...``. .. _owrt_libbar_step6: .. _owrt_libbar_step6_1: .. tab-set:: .. tab-item:: Step 6: Install Shared Library on OpenWrt VM .. code-block:: bash scp -P libbar*.apk root@127.0.0.1:/tmp/ apk add --allow-untrusted /tmp/libbar*.apk .. tab-item:: Step 6.1: Technical Notes - ``libbar.so`` lands in ``/usr/lib``. - Patched math logic immediately active. .. _owrt_libbar_step7: .. _owrt_libbar_step7_1: .. tab-set:: .. tab-item:: Step 7: Test Application Directory Structure :: package/my/bar-test/ ├── Makefile ├── patches/ │ └── 0001-change-message.patch └── src/main.c .. code-block:: c printf("bar_mul(3,5) returned %d\n", bar_mul(3,5)); .. tab-item:: Step 7.1: Technical Notes - Test program verifies shared library patching. .. _owrt_libbar_step8: .. _owrt_libbar_step8_1: .. tab-set:: .. tab-item:: Step 8: Test Application Patch .. code-block:: diff --- a/main.c +++ b/main.c @@ -5,6 +5,6 @@ int main() { int result = bar_mul(3,5); - printf("bar_mul(3,5) returned %d\n", result); + printf("Patched: bar_mul(3,5) = %d\n", result); return 0; } .. tab-item:: Step 8.1: Technical Notes - Demonstrates userland patching. - Logic unchanged; output modified. .. _owrt_libbar_step9: .. _owrt_libbar_step9_1: .. tab-set:: .. tab-item:: Step 9: Test Application Makefile .. code-block:: make DEPENDS:=+libbar define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ $(call Build/Patch,$(PKG_BUILD_DIR)) endef define Build/Compile $(TARGET_CC) -I$(STAGING_DIR)/usr/include \ -L$(STAGING_DIR)/usr/lib \ $(PKG_BUILD_DIR)/main.c \ -lbar \ -o $(PKG_BUILD_DIR)/bar-test endef .. tab-item:: Step 9.1: Technical Notes - ``DEPENDS`` ensures libbar installed first. - Dynamically links against patched library. .. _owrt_libbar_step10: .. _owrt_libbar_step10_1: .. tab-set:: .. tab-item:: Step 10: Build & Install Test Application .. code-block:: bash make package/my/bar-test/compile V=s scp -P bar-test*.apk root@127.0.0.1:/tmp/ apk add --allow-untrusted /tmp/bar-test*.apk bar-test Expected: :: Patched: bar_mul(3,5) = 17 .. tab-item:: Step 10.1: Technical Notes - ``bar_mul`` normally returns ``15`` → patched to ``17``. - Dynamic linking picks up patched library without recompiling.