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

How to structure an OpenWrt package for a simple C application?

How OpenWrt applies code patches automatically using Build/Patch?

How to compile an application using OpenWrt’s cross-toolchain?

How to install and run the patched application on OpenWrt?

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.

  • 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.

Hello world application source:

package/my/helloworld/src/app_main.c

#include <stdio.h>

int main(void) {
    printf("Hello World from OpenWrt base version!\n");
    return 0;
}
  • Program prints default message before patching.

  • Output binary is installed as /usr/bin/helloworld.

Patch file that modifies runtime message:

package/my/helloworld/patches/0001-hellow-world-app.patch

--- a/app_main.c
+++ b/app_main.c
@@ -1,6 +1,6 @@
 #include <stdio.h>

 int main(void) {
-    printf("Hello World from OpenWrt base version!\n");
+    printf("Hello World — patched version from OpenWrt!\n");
     return 0;
 }
  • Patch is automatically applied via Build/Patch.

  • Patching occurs inside $(PKG_BUILD_DIR) ensuring original code is untouched.

package/my/helloworld/Makefile:

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))
  • Build/Prepare copies sources + applies patches.

  • Build/Compile performs cross-compilation using TARGET_CC.

  • /usr/bin/helloworld becomes final installed binary.

Build using OpenWrt build system:

make package/my/helloworld/compile V=s

Output package appears under:

bin/targets/<arch>/<subtarget>/packages/helloworld*.ipk
  • V=s prints verbose compiler commands.

  • The build uses OpenWrt’s cross-toolchain.

Copy IPK into OpenWrt VM or device:

scp -P <PORT> helloworld*.ipk root@<IP>:/tmp/
  • /tmp is writable even on read‑only OpenWrt images.

  • Works for QEMU, hardware, LXCs, or Docker-based OpenWrt builds.

Inside OpenWrt:

opkg install /tmp/helloworld*.ipk
  • Installs /usr/bin/helloworld.

  • --force-reinstall may be used for repeated tests.

Execute:

helloworld

Expected Output:

Hello World — patched version from OpenWrt!
  • Verifies patch was applied and compiled successfully.

  • Confirms installation path and runtime correctness.