OpenWrt: Adding Patches to an Application ========================================= This document describes the complete steps to build, patch, compile, package, install, and run a simple Hello World application inside OpenWrt. The workflow matches OpenWrt’s standard package framework, including directory layout, patching via ``Build/Patch``, cross-compilation, packaging, and execution on an OpenWrt target. In this section, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to structure an OpenWrt package for a simple C application? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How OpenWrt applies code patches automatically using ``Build/Patch``? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to compile an application using OpenWrt’s cross-toolchain? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to install and run the patched application on OpenWrt? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Step 1: Directory Layout ` * :ref:`Step 1.1: Technical Notes ` * :ref:`Step 2: Source File ` * :ref:`Step 2.1: Technical Notes ` * :ref:`Step 3: Patch File ` * :ref:`Step 3.1: Technical Notes ` * :ref:`Step 4: Makefile ` * :ref:`Step 4.1: Technical Notes ` * :ref:`Step 5: Build Application ` * :ref:`Step 5.1: Technical Notes ` * :ref:`Step 6: Copy IPK to OpenWrt Target ` * :ref:`Step 6.1: Technical Notes ` * :ref:`Step 7: Install Application ` * :ref:`Step 7.1: Technical Notes ` * :ref:`Step 8: Run Application ` * :ref:`Step 8.1: Technical Notes ` .. _openwrt_app_step1: .. _openwrt_app_step1_1: .. tab-set:: .. tab-item:: Step 1: Directory Layout The following directory layout is used for the Hello World application: :: package/my/helloworld/ ├── Makefile ├── patches/ │ └── 0001-hellow-world-app.patch └── src/ └── app_main.c This structure follows the standard OpenWrt packaging format. .. tab-item:: Step 1.1: Technical Notes - ``patches/`` contains all quilt-style patches applied during ``Build/Prepare``. - ``src/`` contains upstream source; OpenWrt never builds directly from this directory. - The package name ``helloworld`` determines the IPK naming. .. _openwrt_app_step2: .. _openwrt_app_step2_1: .. tab-set:: .. tab-item:: Step 2: Source File Hello world application source: ``package/my/helloworld/src/app_main.c`` .. code-block:: c #include int main(void) { printf("Hello World from OpenWrt base version!\n"); return 0; } .. tab-item:: Step 2.1: Technical Notes - Program prints default message before patching. - Output binary is installed as ``/usr/bin/helloworld``. .. _openwrt_app_step3: .. _openwrt_app_step3_1: .. tab-set:: .. tab-item:: Step 3: Patch File Patch file that modifies runtime message: ``package/my/helloworld/patches/0001-hellow-world-app.patch`` .. code-block:: diff --- a/app_main.c +++ b/app_main.c @@ -1,6 +1,6 @@ #include int main(void) { - printf("Hello World from OpenWrt base version!\n"); + printf("Hello World — patched version from OpenWrt!\n"); return 0; } .. tab-item:: Step 3.1: Technical Notes - Patch is automatically applied via ``Build/Patch``. - Patching occurs inside ``$(PKG_BUILD_DIR)`` ensuring original code is untouched. .. _openwrt_app_step4: .. _openwrt_app_step4_1: .. tab-set:: .. tab-item:: Step 4: Makefile ``package/my/helloworld/Makefile``: .. code-block:: make include $(TOPDIR)/rules.mk PKG_NAME:=helloworld PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define Package/helloworld SECTION:=utils CATEGORY:=Utilities TITLE:=Simple Hello World App (patched) 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) \ -o $(PKG_BUILD_DIR)/app_main \ $(PKG_BUILD_DIR)/app_main.c endef define Package/helloworld/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/app_main $(1)/usr/bin/helloworld endef $(eval $(call BuildPackage,helloworld)) .. tab-item:: Step 4.1: Technical Notes - ``Build/Prepare`` copies sources + applies patches. - ``Build/Compile`` performs cross-compilation using ``TARGET_CC``. - ``/usr/bin/helloworld`` becomes final installed binary. .. _openwrt_app_step5: .. _openwrt_app_step5_1: .. tab-set:: .. tab-item:: Step 5: Build Application Build using OpenWrt build system: .. code-block:: bash make package/my/helloworld/compile V=s Output package appears under: :: bin/targets///packages/helloworld*.ipk .. tab-item:: Step 5.1: Technical Notes - ``V=s`` prints verbose compiler commands. - The build uses OpenWrt’s cross-toolchain. .. _openwrt_app_step6: .. _openwrt_app_step6_1: .. tab-set:: .. tab-item:: Step 6: Copy IPK to OpenWrt Target Copy IPK into OpenWrt VM or device: .. code-block:: bash scp -P helloworld*.ipk root@:/tmp/ .. tab-item:: Step 6.1: Technical Notes - ``/tmp`` is writable even on read‑only OpenWrt images. - Works for QEMU, hardware, LXCs, or Docker-based OpenWrt builds. .. _openwrt_app_step7: .. _openwrt_app_step7_1: .. tab-set:: .. tab-item:: Step 7: Install Application Inside OpenWrt: .. code-block:: bash opkg install /tmp/helloworld*.ipk .. tab-item:: Step 7.1: Technical Notes - Installs ``/usr/bin/helloworld``. - ``--force-reinstall`` may be used for repeated tests. .. _openwrt_app_step8: .. _openwrt_app_step8_1: .. tab-set:: .. tab-item:: Step 8: Run Application Execute: .. code-block:: bash helloworld Expected Output: :: Hello World — patched version from OpenWrt! .. tab-item:: Step 8.1: Technical Notes - Verifies patch was applied and compiled successfully. - Confirms installation path and runtime correctness.