OpenWrt is an open source firmware project targeting routers and systems of almost any architecture. Knowing how to build from source is important for developers and others that want to change the default installation image. For example we can change the QoS algorithms, include LuCI by default, or create an openflow switch (using Open vSwitch or CPqD's OpenFlow). The purpose of this article is to show you how.

The compilation process is involved and a mistake (or a bug) can soft brick your router. I haven't encountered an issue yet, but you should know how to debrick just in case.

Prerequisites for Compiling OpenWrt

The first step is look at the OpenWrt Source Repositories page for your preferred version of OpenWrt. I'll be using the latest binary release, currently Chaos Calmer 15.05, but definitely use a newer version if it exists and adapt the following instructions to your version (or trunk).

Next you'll need to find your router's configuration (config.diff or config_generic) at the OpenWrt Downloads page. I'm compiling OpenWrt 15.05 for the TP-LINK TL-WR1043NDv2.1 router (ar71xx board), and here is that config. If you have a different board: save the link, we'll use it later. Note that you don't need this file but it makes the process easier since usb and things are typically included.

The last required item is an Ubuntu build machine. A simple VM works fine, or use DigitalOcean droplets or AWS EC2 spot requests (just be sure to delete the instance...).

Compiling the Source

We're ready to begin our journey. Install some required tools, make the build directory, and clone the source:

sudo apt-get -y install git openssl python libssl-dev unzip build-essential binutils flex bison autoconf gettext texinfo sharutils subversion libncurses5-dev ncurses-term zlib1g-dev gawk;
mkdir ~/openwrt-chaoscalmer/ && cd ~/openwrt-chaoscalmer/;
git clone git://;
cd openwrt;

Now for some background on the configuration and feeds...

Background on Configuration

The build configuration (.config file) controls the target platform, packages to compile into firmware, packages to compile for opkg install, and many other options.

In the .config, a package is in one of three states:

  • y means it is compiled and included in firmware
  • m means it is compiled and not included in firmware
  • n means the package is not compiled

Since we can download and install packages post-flash using opkg, we'll transition all m packages to n. NOTE: DO NOT USE SPACEBAR to disable packages, use the n on the keyboard; spacebar switches the inclusion state which can unintentionally include (many) other packages. Disabling these makes the build MUCH faster. Read more about configuration at OpenWrt's build wiki here.

Background on Feeds

OpenWrt describes feeds as "additional predefined package build recipes for OpenWrt Buildroot", where each feed resides on a remote host and are downloaded (from, say, GitHub). The scripts/feeds script is used to fetch and enable ("install") the packages in menuconfig, making them visible for selection.

It's easy to enable custom feeds to make your own packages or include others. In a later post I'll use feeds to include CPqD's OpenFlow 1.3 userspace module or Open vSwitch (OVS) to talk to a controller (such as Floodlight or OpenDaylight). Those controllers let us manage lots of switches from a centralized location.

Enough about feeds here, and read OpenWrt's wiki on feeds if you need more information.

Configure. Build, Build, Build!!

Now it's time to actually configure the build. Install feeds, fetch the config file, select your target profile, disable compile-only packages, and verify that you have prereqs:

# Fetch feeds from remote repositories
# and make them visible to menuconfig
./scripts/feeds update -a
./scripts/feeds install -a

# Get the configuration for YOUR router if you found it
wget -O .config
make defconfig

# Select YOUR router's profile then save & quit 
# Mine is TP-LINK TL-WR1043N/ND
# Feel free to browse here. If you mess up,
# just redo the steps in this code block
make menuconfig

# Disable the compile-only packages AND disable the SDK (for fast builds)
# and make sure we have build prereqs
sed --in-place=.bak -e 's/=m$/=n/g' -e 's/^CONFIG_SDK=y$/CONFIG_SDK=n/' .config
make prereq

After the configuration, we're ready to build! Use -j to run parallel jobs and V=s to capture the output.

time make V=s -j20 2>&1 | tee build.log | grep -i error

Build issue tip: Just retry the build if it fails. If it continues to fail use V=s -j1 and check the active tickets; my build failed because the gdb-linaro download url changed so if you have that issue, look at this ticket for a workaround.

After the build is done, scp the file to your router and use sysupgrade <build>.bin (with -n to clear the config files). Read up on how to configure OpenWrt and have fun!

I'll make another post soon on how to include openflow in the build and configure for OpenDaylight or Floodlight controllers.