Skip to main content
Before building, you must configure the build system to target a specific hardware platform and select the packages to include. OpenWrt uses the same Kconfig infrastructure as the Linux kernel. Run make menuconfig to open a curses-based interactive configuration interface:
make menuconfig
The interface lets you navigate categories with arrow keys, toggle options with the spacebar, and save your choices to a .config file.
If no .config file exists yet, make menuconfig will first run make defconfig to generate a minimal starting point, then open the interface.

Three-way toggle

Most package entries support three states, cycled with the spacebar:
SymbolStateMeaning
* (y)Built-inCompiled directly into the firmware image
M (m)ModuleBuilt as a separate .ipk / .apk package, not included in the image by default
(n)ExcludedNot compiled at all

Key configuration sections

When you first open menuconfig, the top-level categories include:
  • Target System — the CPU architecture (e.g. x86, ath79, ramips)
  • Subtarget — the specific chip family within the target
  • Target Profile — the board or device profile
  • Target Images — filesystem types and image formats to generate
  • Global build settings — security hardening, stripping, package manager selection
  • Base system — core OpenWrt utilities (busybox, procd, etc.)
  • Administration, Boot Loaders, Development, Firmware, Kernel modules, Languages, Libraries, LuCI, Mail, Multimedia, Network, Sound, Utilities — package categories

Example: enabling a package

To include curl in your firmware image:
  1. Open make menuconfig
  2. Navigate to Network
  3. Find curl and press spacebar until <*> appears
  4. Press S to save, then Q to quit
The next make invocation will compile and bundle curl into the image.

The .config file

All selections are stored in .config at the root of the source tree. You can view, copy, or version-control this file directly.
# View current configuration for a specific symbol
grep CONFIG_PACKAGE_curl .config
# CONFIG_PACKAGE_curl=y
You can also pre-populate .config by copying a known-good config file before running make menuconfig.

defconfig

make defconfig generates a minimal .config based on the current Kconfig defaults. It is useful as a clean starting point or to fill in missing symbols after a tree update:
make defconfig

Minimal diff configs with diffconfig.sh

A full .config contains thousands of lines — most of them defaults. The scripts/diffconfig.sh script extracts only the symbols that differ from defaults, producing a compact config fragment suitable for version control or sharing:
./scripts/diffconfig.sh > my-device.config
To restore from a diff config:
cp my-device.config .config
make defconfig   # expands fragment into a full .config
Store your diffconfig output in version control instead of the full .config. This makes it easy to rebase your configuration onto a new OpenWrt version.

Global build settings

The Global build settings menu (from config/Config-build.in) exposes additional build-time options:
  • Enable experimental features — opt in to bleeding-edge, potentially unstable features
  • Use APK instead of OPKG — switch the package manager used to assemble the image (APK is the new default)
  • Cryptographically signed package lists — enabled by default
  • Compile packages with debugging info — adds -g3 to CFLAGS
  • Binary stripping method — controls how binaries are stripped to reduce size
  • Stack-Smashing Protection, ASLR PIE, RELRO, FORTIFY_SOURCE — hardening options