Skip to main content
Every OpenWrt package Makefile begins with include $(TOPDIR)/rules.mk and ends with one or more $(eval $(call BuildPackage,<name>)) calls. Everything in between uses the variables and macros described here.
Variable values shown are defaults as defined in include/package.mk, include/package-defaults.mk, and related files. Individual packages override these as needed.
These variables tell the build system where to find and how to identify the upstream source.
VariableDescription
PKG_NAMEPackage name. Used as the $(PKG_BUILD_DIR) base and in BuildPackage calls.
PKG_VERSIONUpstream version string (e.g., 2.12.1). Becomes part of the package version.
PKG_RELEASEOpenWrt packaging revision. Appended as -r<N> to the version. Increment when the Makefile changes without a version bump.
PKG_SOURCEFilename of the source tarball to download.
PKG_SOURCE_URLSpace-separated list of URLs to download PKG_SOURCE from.
PKG_HASHSHA-256 hash of PKG_SOURCE. The build system verifies this before using the file.
PKG_MIRROR_HASHSHA-256 hash of the generated tarball (used with git/svn sources).
PKG_SOURCE_PROTOSource control protocol: git or svn. Omit for tarball downloads.
PKG_SOURCE_VERSIONGit commit hash or SVN revision. When set, PKG_VERSION is auto-derived.
PKG_SOURCE_DATEDate of the commit (YYYY-MM-DD). Used with PKG_SOURCE_VERSION to build PKG_VERSION.
PKG_SOURCE_SUBDIRSubdirectory name inside the archive. Defaults to $(PKG_NAME)-$(PKG_VERSION).
PKG_LICENSESPDX license expression (e.g., GPL-2.0-only, MIT). Propagated to Package/Default.
PKG_LICENSE_FILESPath(s) to license file(s) within the source tree.
PKG_CPE_IDCommon Platform Enumeration identifier for vulnerability tracking.
PKG_MAINTAINERMaintainer name and email. Shown in package metadata.
Tarball example:
PKG_NAME:=lua
PKG_VERSION:=5.1.5
PKG_RELEASE:=11

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.lua.org/ftp/
PKG_HASH:=2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333

PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=COPYRIGHT
Git source example:
PKG_NAME:=jsonfilter
PKG_RELEASE:=1

PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/jsonpath.git
PKG_SOURCE_DATE:=2026-03-16
PKG_SOURCE_VERSION:=b9034210bd331749673416c6bf389cccd4e23610
PKG_MIRROR_HASH:=e8616b3eee53c6dd3420a7d800337e13a61e1333dfbd8551b50ab15bafd94a0e
When PKG_SOURCE_VERSION is present, PKG_VERSION is automatically set to <PKG_SOURCE_DATE>~<abbrev-commit> by download.mk.
These variables control where and how the package is built.
VariableDefaultDescription
PKG_BUILD_DIR$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)Directory where the source is extracted and built.
PKG_INSTALL_DIR$(PKG_BUILD_DIR)/ipkg-installStaging directory for make install output (used when PKG_INSTALL:=1).
PKG_BUILD_PARALLEL(empty)Set to 1 to enable parallel make. Set to 0 to force -j1.
PKG_JOBS-j1 or $(MAKE_J)Derived from PKG_BUILD_PARALLEL. Passed to $(MAKE).
PKG_INSTALL(unset)Set to 1 to run make install DESTDIR=$(PKG_INSTALL_DIR) after compile.
PKG_BUILD_FLAGS(empty)Space-separated flags to tune compiler/linker options. See PKG_BUILD_FLAGS below.
PKG_CONFIG_DEPENDS(empty)List of CONFIG_* symbols that trigger a rebuild when changed.
PKG_FILE_DEPENDS(empty)List of files that trigger a rebuild when changed.
PKG_BUILD_DEPENDS(empty)Build-time-only package dependencies (not installed on target).
USE_SOURCE_DIR(unset)Set to a path to use a local directory instead of a downloaded tarball. Sets QUILT:=1.
PKG_SUBDIRS(unset)Passed as SUBDIRS= to make for packages with multiple subdirectories.
MAKE_PATH.Subdirectory within PKG_BUILD_DIR to run make in.
CONFIGURE_PATH.Subdirectory within PKG_BUILD_DIR to run ./configure in.
Build flag values (PKG_BUILD_FLAGS):
FlagEffect
no-mips16Disable MIPS16 instruction set even when CONFIG_USE_MIPS16 is set.
gc-sectionsAdd -ffunction-sections -fdata-sections and -Wl,--gc-sections to remove unused code.
no-gc-sectionsDisable gc-sections even when CONFIG_USE_GC_SECTIONS is set globally.
ltoEnable link-time optimization (-flto=auto).
no-ltoDisable LTO even when CONFIG_USE_LTO is set globally.
no-moldDisable mold linker for this package even when CONFIG_USE_MOLD is set.
# Disable LTO for a package that is incompatible with it
PKG_BUILD_FLAGS:=no-lto

# Enable gc-sections to reduce binary size
PKG_BUILD_FLAGS:=gc-sections
The build system provides default implementations for each build phase. Override only what differs from the defaults.

Standard build hooks

HookDefault implementationWhen to override
Build/PrepareUnpack source, apply patchesRarely; use PKG_UNPACK instead
Build/ConfigureRun ./configure with CONFIGURE_ARGSWhen extra flags are needed
Build/CompileRun $(MAKE) $(PKG_JOBS) with MAKE_FLAGSWhen non-standard targets are required
Build/InstallRun make install DESTDIR=$(PKG_INSTALL_DIR)When PKG_INSTALL:=1 is set
Build/InstallDev(empty)To install headers/libs to staging dir for other packages to link against
Build/Clean(empty)To add extra cleanup steps

Configure arguments

Build/Configure/Default passes CONFIGURE_ARGS to ./configure. Extend it:
CONFIGURE_ARGS += \
  --disable-nls \
  --enable-shared
Autoconf boolean helpers:
CONFIGURE_ARGS += $(call autoconf_bool,CONFIG_MYPACKAGE_FEATURE,my-feature)

Make variables

Build/Compile/Default passes MAKE_VARS and MAKE_FLAGS to $(MAKE).
# MAKE_FLAGS always includes:
# $(TARGET_CONFIGURE_OPTS) CROSS="$(TARGET_CROSS)" ARCH="$(ARCH)"

# MAKE_VARS always includes:
# CFLAGS CXXFLAGS LDFLAGS with target values

# Extend for package-specific needs:
MAKE_FLAGS += MY_EXTRA_FLAG=1

Include order

include $(TOPDIR)/rules.mk          # Always first

# ... PKG_* variable definitions ...

include $(INCLUDE_DIR)/package.mk   # Core package infrastructure
include $(INCLUDE_DIR)/cmake.mk     # Optional: use instead of autotools defaults
include $(INCLUDE_DIR)/host-build.mk  # Optional: also build a host tool
include $(INCLUDE_DIR)/cmake.mk must come after include $(INCLUDE_DIR)/package.mk. It sets PKG_BUILD_PARALLEL:=1 and PKG_INSTALL:=1 automatically.
BuildPackage is the entry point that registers a package with the build system. It must be called once per logical package, at the bottom of the Makefile.
$(eval $(call BuildPackage,pkgname))
When called, BuildPackage does the following:
  1. Evaluates Package/Default to set default field values.
  2. Evaluates Package/<pkgname> to apply package-specific overrides.
  3. Validates that TITLE, CATEGORY, SECTION, and VERSION are set.
  4. Adds the package to BUILD_PACKAGES.
  5. Wires up the build targets: prepare, configure, compile, install.
Multiple packages from one Makefile:A single Makefile may produce multiple packages by calling BuildPackage multiple times:
$(eval $(call BuildPackage,liblua))
$(eval $(call BuildPackage,lua))
$(eval $(call BuildPackage,luac))
$(eval $(call HostBuild))   # Build a host version for use during build
HostBuild macro:When the package needs to produce a tool used by the build system itself (e.g., a code generator), add:
include $(INCLUDE_DIR)/host-build.mk

define Host/Compile
  $(MAKE) -C $(HOST_BUILD_DIR) CC="$(HOSTCC)"
endef

define Host/Install
  $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
  $(INSTALL_BIN) $(HOST_BUILD_DIR)/mytool $(STAGING_DIR_HOST)/bin/
endef

$(eval $(call HostBuild))
Fields inside define Package/<name> ... endef control package metadata, menuconfig placement, and dependency resolution.
FieldDefaultDescription
SECTIONoptopkg section (e.g., base, libs, utils, net, lang).
CATEGORYExtra packagesTop-level menuconfig category.
SUBMENU(empty)Optional submenu within the category.
TITLE(empty, required)Short one-line description.
URL$(PKG_URL)Upstream project URL.
DEPENDS(empty)Runtime dependency list (see syntax below).
PROVIDES(empty)Virtual package names this package satisfies.
CONFLICTS(empty)Packages that conflict with this one.
EXTRA_DEPENDS(empty)Additional dependencies not resolved at build time.
MAINTAINER$(PKG_MAINTAINER)Maintainer name and email address.
LICENSE$(PKG_LICENSE)SPDX license expression.
LICENSE_FILES$(PKG_LICENSE_FILES)Paths to license files in the source.
VARIANT(empty)Build variant name, for packages built multiple times with different options.
DEFAULT_VARIANT(empty)Mark this variant as the default.
BUILDONLY(empty)Set to 1 to build the package but not include it in the package repository.
HIDDEN(empty)Set to 1 to hide from menuconfig.
PKGARCH$(ARCH_PACKAGES)Package architecture. Set to all for architecture-independent packages.
ABI_VERSION(empty)ABI version appended to library .so filename.
ALTERNATIVES(empty)Register alternative symlinks (update-alternatives).
USERID(empty)Create a user/group for this package (user:group syntax).

DEPENDS syntax

DEPENDS:=+libpthread +librt @TARGET_x86
PrefixMeaning
+pkgRuntime dependency; pkg is selected when this package is selected.
+CONFIG_FOO:pkgConditional dependency; only when CONFIG_FOO is set.
@SYMBOLConfig symbol condition; package only shown when SYMBOL is set.
@TARGET_fooOnly available for target foo.
define Package/mypackage
  SECTION:=utils
  CATEGORY:=Utilities
  TITLE:=My package
  DEPENDS:=+libubox +libuci @!TARGET_uml
  URL:=https://example.com/mypackage
endef

Stamp files and build phases

The build system uses stamp files in $(PKG_BUILD_DIR)/ to track build state. Understanding these helps when debugging:
StampBuild phaseCreated by
.preparedSource unpacked, patches appliedBuild/Prepare
.configuredConfigure step completeBuild/Configure
.builtCompile and install steps completeBuild/Compile + Build/Install
$(STAGING_DIR)/stamp/...Dev files installed to stagingBuild/InstallDev
Delete a stamp to force a phase to re-run:
rm build_dir/target-*/mypackage-*/.configured
make package/mypackage/compile V=s

Full Makefile example

The following is the actual package/utils/lua/Makefile, showing a real-world package with a custom Build/Compile, multiple sub-packages, and a host build:
include $(TOPDIR)/rules.mk

PKG_NAME:=lua
PKG_VERSION:=5.1.5
PKG_RELEASE:=11

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.lua.org/ftp/
PKG_HASH:=2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
PKG_BUILD_PARALLEL:=1

PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=COPYRIGHT
PKG_CPE_ID:=cpe:/a:lua:lua

PKG_BUILD_FLAGS:=no-lto

include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/host-build.mk

define Package/lua
  SECTION:=lang
  CATEGORY:=Languages
  SUBMENU:=Lua
  TITLE:=Lua programming language (interpreter)
  URL:=https://www.lua.org/
  DEPENDS:=+liblua
endef

define Build/Configure
endef

define Build/Compile
  $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
    CC="$(TARGET_CROSS)gcc" \
    CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
    MYLDFLAGS="$(TARGET_LDFLAGS)" \
    linux
endef

define Package/lua/install
  $(INSTALL_DIR) $(1)/usr/bin
  $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/lua5.1 $(1)/usr/bin/
  $(LN) lua5.1 $(1)/usr/bin/lua
endef

$(eval $(call BuildPackage,lua))
$(eval $(call HostBuild))