Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Adding a Custom Package to the OpenWrt Build System

Tech Jun 5 1

Background

OpenWrt provides a well-structured build framework. To add a custom package, place a standard Makefile in the designated directory, and the build system will automatically parse it and compile the source using the appropriate toolchains.

Custom packages reside under the SDK root at the path openwrt/package.

The directory layout for each package follows a consistent pattern:

package
├── files
├── Makefile
└── src
    ├── main.c
    └── Makefile

This article focuses on the top-level Makefile.

Examples

You can compile both userspace applications and kernel modules. The sections below provide practical examples.

Userspace Application

#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

include $(TOPDIR)/rules.mk

PKG_NAME:=data-logger
PKG_VERSION:=1.0

include $(INCLUDE_DIR)/package.mk

define Package/data-logger
  SECTION:=utils
  CATEGORY:=Custom Utilities
  MAINTAINER:=Developer Team
  DEPENDS:=
  TITLE:=Data Logger Utility
endef

define Package/data-logger/Description
	A simple data logging utility for embedded devices.
endef

define Build/Prepare
	mkdir -p $(PKG_BUILD_DIR)
	$(CP) -u ./src/* $(PKG_BUILD_DIR)/
endef

define Package/data-logger/install
	$(INSTALL_DIR) $(1)/etc
	$(INSTALL_DATA) ./filesystem/etc/data-logger.config $(1)/etc

	$(INSTALL_DIR) $(1)/usr/bin
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/data-logger $(1)/usr/bin
endef

$(eval $(call BuildPackage,data-logger))

Kernel Module

#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=data-logger
PKG_VERSION:=0.1

define KernelPackage/data-logger
  SECTION:=kernel
  CATEGORY:=Kernel Modules
  MAINTAINER:=Developer Team
  DEPENDS:=
  TITLE:=Data Logger Kernel Module
  FILES:=$(PKG_BUILD_DIR)/data_logger.ko
  AUTOLOAD:=$(call AutoLoad,99,data_logger)
endef

define KernelPackage/data-logger/description
	Kernel module that intercepts and logs network data.
endef

define Build/Prepare
	mkdir -p $(PKG_BUILD_DIR)
	$(CP) -u ./src/* $(PKG_BUILD_DIR)/
endef

define Build/Compile
	$(MAKE) -C $(LINUX_DIR) M=$(PKG_BUILD_DIR) $(strip $(MAKE_OPTS))
endef

define Build/InstallDev
	$(INSTALL_DIR) $(1)/usr/include
	$(CP) $(PKG_BUILD_DIR)/data_logger.h $(1)/usr/include
endef

define KernelPackage/data-logger/install
	$(INSTALL_DIR) $(1)/etc
endef

$(eval $(call KernelPackage,$(PKG_NAME)))

Combined Package (Userspace + Kernel)

It is possible to define both a userspace aplication and a kernel module within the same package. The crucial difference lies in invoking both BuildPackage and KernelPackage at the end.

#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=data-guard
PKG_VERSION:=1.0

include $(INCLUDE_DIR)/package.mk

define KernelPackage/$(PKG_NAME)
  SECTION:=kernel
  CATEGORY:=Custom Security Modules
  MAINTAINER:=Security Team
  DEPENDS:=
  TITLE:=Data Guard Kernel Engine
  FILES:=$(PKG_BUILD_DIR)/ipt/data-guard.ko
  AUTOLOAD:=$(call AutoLoad,99,data-guard)
endef

TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib
TARGET_LDFLAGS += -L$(STAGING_DIR)/lib

CORE_DEPENDS:=+libc

GUARD_MAKE_OPTS:=

ifeq ($(CONFIG_CUSTOM_FEATURE), y)
EXTRA_CFLAGS += -I$(LINUX_DIR)/../bcmkernel/include
EXTRA_CFLAGS += -DCONFIG_CUSTOM_FEATURE=1
endif

TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib 

GUARD_MAKE_OPTS+= \
        CROSS_COMPILE=$(KERNEL_CROSS) \
        ARCH=$(LINUX_KARCH) \
		KERNELPATH="$(LINUX_SRC_DIR)" \
        KBUILDPATH=$(LINUX_DIR) \
        EXTRA_CFLAGS="$(EXTRA_CFLAGS)"	\
        SUBDIRS=$(PKG_BUILD_DIR)

define Package/$(PKG_NAME)
  SECTION:=utils
  CATEGORY:=Custom Security Modules
  TITLE:=Data Guard Management Utility
  MAINTAINER:=Security Team
  DEPENDS:=$(CORE_DEPENDS)
endef

define KernelPackage/$(PKG_NAME)/description
	In-kernel filtering engine for the Data Guard framework.
endef

define Package/$(PKG_NAME)/Description
	Userspace configuration and logging tool for Data Guard.
endef

define Package/$(PKG_NAME)/config
	config PACKAGE_GUARD_VENDOR
		string "vendor identifier (required)"
		default security_vendor

	config PACKAGE_GUARD_VERSION
		string "guard version (required)"
		default A.B.C

	config PACKAGE_GUARD_USE_NF
		bool "Use Netfilter queue for packet inspection"
		default n
endef

CONFIG_PACKAGE_GUARD_USE_NF ?= y
ifeq ($(CONFIG_PACKAGE_GUARD_USE_NF), y)
SRC_PATH:=nf
CORE_DEPENDS+=+libnetfilter-queue +libpcap
else #CONFIG_PACKAGE_GUARD_USE_NF
SRC_PATH:=ipt
CORE_DEPENDS+=+iptables
endif #CONFIG_PACKAGE_GUARD_USE_NF

GUARD_VENDOR ?= $(CONFIG_PACKAGE_GUARD_VENDOR)
GUARD_VERSION ?= $(CONFIG_PACKAGE_GUARD_VERSION)
GUARD_USE_NF ?= $(CONFIG_PACKAGE_GUARD_USE_NF)

$(info $$GUARD_VENDOR is [${GUARD_VENDOR}])
$(info $$GUARD_VERSION is [${GUARD_VERSION}])
$(info $$GUARD_USE_NF is [${GUARD_USE_NF}])

INSTALL_BIN:=$(SRC_PATH)/data-guard
INSTALL_LIB:=$(SRC_PATH)/libxt_guard.so

define Build/Prepare
	mkdir -p $(PKG_BUILD_DIR)
	$(CP) -u ./src-$(GUARD_VENDOR)/* $(PKG_BUILD_DIR)/
endef

define Build/Compile
	$(MAKE) -C $(PKG_BUILD_DIR)/$(SRC_PATH) \
    $(TARGET_CONFIGURE_OPTS) \
	TARGET_LDFLAGS="$(TARGET_LDFLAGS)" \
	TARGET_CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
	GUARD_VERSION="$(GUARD_VERSION)" \
	CC="$(TARGET_CC)"
	$(MAKE) -C $(LINUX_DIR) M=$(PKG_BUILD_DIR)/$(SRC_PATH) GUARD_VERSION=$(GUARD_VERSION) $(strip $(GUARD_MAKE_OPTS))
endef

define Package/$(PKG_NAME)/install
	$(CP) -rf ./filesystem/* $(1)/

	$(INSTALL_DIR) $(1)/usr/lib/guard/
	$(CP) $(PKG_BUILD_DIR)/sdk-$(GUARD_VERSION)/lib/* $(1)/usr/lib/guard/

	$(INSTALL_DIR) $(1)/usr/bin
	$(if $(INSTALL_BIN),$(CP) $(foreach bin,$(INSTALL_BIN),$(PKG_BUILD_DIR)/$(bin)) $(1)/usr/bin/)

	$(INSTALL_DIR) $(1)/usr/lib/iptables
	$(if $(INSTALL_LIB),$(CP) $(foreach lib,$(INSTALL_LIB),$(PKG_BUILD_DIR)/$(lib)) $(1)/usr/lib/iptables/)
endef

define Build/InstallDev

endef

define KernelPackage/$(PKG_NAME)/install
	$(INSTALL_DIR) $(1)/etc
endef

$(eval $(call KernelPackage,$(PKG_NAME)))

$(eval $(call BuildPackage,$(PKG_NAME)))

Inside the src directory, the userspace application still uses a regular Makefile, while the kernel module relies on the Kbuild system:

MODULE_NAME = data-guard
$(MODULE_NAME)-objs := data-guard-kmod.o component.o
obj-m += $(MODULE_NAME).o
Tags: OpenWrt

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.