Building OpenWrt
Pre-compiled images of the current OpenWrt release are always available, and easily found and downloaded from the OpenWrt website. These pre-compiled images are based on a default configuration, and only targeted at supported platforms/devices. There are several good reasons for why it is practical to build one's own images:
- Custom configurations
- Experimental platforms
- Participation in testing and development
- Or, simply keeping up-to-date
The best of it all is; that it in reality is quite simple to build an OpenWrt image.
Prerequisites
Before you get started with the actual building a few practical details have to be in place; as with any other process of building the correct tools and materials have to be ready and at hand.
- A system for building the OpenWrt image
- Ensure that the needed dependencies are installed
- Copy of the OpenWrt source-code
First of all, you need to have access to a system which supports the building of OpenWrt. It is recommended to use a Linux system, either as a standalone installation or as a separate system running in a virtual environment (Vmware or Qemu). It is potentially possible to build OpenWrt images directly on a *BSD or Mac OSX systems, but success is not guaranteed.
The following description assumes the use of a current Debian system which uses apt-get for package management. An alternative choice would be one of the (Debian-based) Ubuntu variants (Kubuntu, Xubuntu etc.).
In this step, the components upon which the OpenWRT build system depends will be installed. This includes compilers, unzip applications, specific libraries, etc. Simply type in the following command (which normally requires root or sudo privileges) in your shell of choice:
32 bit (x86) installs:
# apt-get install build-essential asciidoc autoconf binutils bison bzip2 \ flex gawk gettext libncurses5-dev libz-dev patch unzip zlib1g-dev |
64 bit (x86_64) installs will need multilib packages also:
# apt-get install build-essential asciidoc autoconf binutils bison bzip2 \ flex gawk gettext libncurses5-dev libz-dev patch unzip zlib1g-dev \ ia32-libs lib32gcc1 libc6-dev-i386 |
Consult this Table of Correspondence in order to find your prerequisites on platforms other than Debian/Ubuntu.
Some of these dependencies might already be installed on the system, in which case apt-get will respond and ask what to do (ignore, re-install etc.).
Downloading Sources
Finally, download a copy of the complete OpenWrt source code to your build system. You have two choices: Downloading the latest stable release or downloading the bleeding edge development snapshot (called "trunk").
To download either, you must have Subversion installed. Subversion, or SVN, is the current version control system used by the OpenWrt project, and it is quite similar to CVS in terms of interface and use. Again, this dependency is easily installed:
# apt-get install subversion |
When Subversion is installed, the simplest way to confirm that everything works as assumed is to fetch a clean copy of the OpenWrt source. First you create a new directory in which to store the source-code, then move to this new directory and download ('check out' in svn parlance) the source by issuing the required Subversion command.
Using Release Sources
As of this writing, the latest stable release is OpenWrt 10.03 "backfire". As an example, this will check out the source code that the backfire release is built from (plus the latest backported fixes from trunk):
# mkdir OpenWrt/ # cd OpenWrt/ # svn co svn://svn.openwrt.org/openwrt/branches/backfire |
If you insist on using the pristine release sources (no backported fixes applied):
# svn co svn://svn.openwrt.org/openwrt/tags/backfire_10.03 |
Using Development Sources
The current development branch (trunk) contains everything from documentation to experimental patches.
# mkdir OpenWrt/ # cd OpenWrt/ # svn co svn://svn.openwrt.org/openwrt/trunk/ |
Before going ahead with the actual build process when building from trunk, it is a good idea to take a look at the contents of the trunk/ directory, as it is often convenient to be able to compare the contents of the directory before and after the actual build.
More information on checking out sources can be found here: https://dev.openwrt.org/wiki/GetSource.
Building In Practice
The process of creating the correct image for your specific device consists of six simple steps:
- New check-out of trunk via Subversion
- Update package feeds - ./scripts/feeds update
- Build configuration – make defconfig
- Symlink packages and the build environment
- Configure the image(s) to build – make menuconfig
- Build command - make
Updating Sources
Since the OpenWrt development branch changes quickly over time, it is recommended to use the latest sources. This is done with a short Subversion command:
# cd trunk # svn up |
Following this initial step it is needed to prepare and bring the build environment up-to-date. This first requires that the many package feeds are updated and made ready for use:
# ./scripts/feeds update |
Then the downloaded packages need to be installed. The installation step means they will be available during the 'make menuconfig' step later. Without this step the packages are not selectable in 'make menuconfig'. Please note that this step replaces the old method of creating symlinks, which can be still found on-line in many old forum and user-group entries
# ./scripts/feeds install -a |
The feeds configuration file makes it easy to add new or experimental packages sources to the build system. Just edit the file and run the update command.
Configuration
Next step, is to produce a general purpose configuration of the build system, this includes a check of dependencies etc.
# make defconfig |
Should the defconfig command report an error about a missing dependency, then the problem is easily solved with installing the missing package and then run the command again.
Configuration of the image(s) you wish to build, based on the target platform at hand, is invoked by the menuconfing command:
# make menuconfig |
As seen below, menuconfig is a text-based tool which handles the selection of target, packages to include in the build, kernel options etc. It has from the beginning on been the intention, with the development of 'menuconfig', to create a simple yet powerful environment for the configuration of individual OpenWrt images. Menuconfig is more or less self-explanatory, and even the most specialized configuration needs can be solved with its help. Depending on the the particular target platform, package requirements and kernel module needs, the standard process of configuration will include modifying:
- Target system
- Package selection
- Build system settings
- Kernel modules
Target system is selected from the extensive list of supported platforms, with the numerous target profiles – ranging from specific devices to generic profiles, all depending on the particular device at hand. Package selection has the option of either 'selecting all package', which might be un-practical in certain situation, or relying on the default set of packages will be adequate or make an individual selection. It is here needed to mention that some package combinations might break the build process, so it can take some experimentation before the expected result is reached. Added to this, the OpenWrt developers are themselves only maintaining a smaller set of packages – which includes all default packages – but, the feeds-script makes it very simple to handle a locally maintained set of packages and integrate them in the build-process.
Source Mirrors
The 'Build system settings' include some efficient options for changing package locations which makes it easy to handle a local package set:
- Local mirror for source packages
- Download folder
In the case of the first option, you simply enter a full URL to the web or ftp server on which the package sources are hosted. Download folder would in the same way be the path to a local folder on the build system (or network). If you have a web/ftp-server hosting the tarballs, the OpenWrt build system will try this one before trying to download from the location(s) mentioned in the Makefiles . Similar if a local 'download folder', residing on the build system, has been specified. The 'Kernel modules' option is required if you need specific (non-standard) drivers and so forth – this would typically be things like modules for USB or particular network interface drivers etc. The final step before the process of compiling the intended image(s) is to exit 'menuconfig' – this also includes the option to save a specific configuration or load an already existing, and pre-configured, version.
If you want to use LuCI, you'll need to go to the Administration menu, then LuCI Components sub-menu, and select the first 3 packages: luci-admin-core, luci-admin-full, and luci-admin-mini.
If you don't need PPP, you can remove it by deselecting it under the Network menu.
Make sure you mark these packages as a '*' instead of just an 'M'. If you mark with a '*', the package will be built into the firmware you create. If you mark it with just an 'M', the package will be built but not installed.
Exit and save.
Building Images
Everything is now ready for building the image(s), which is done with a single command:
# make |
Building on multicore systems
The build process can be speeded up by using more than 1 concurrent job process. The most common suggestion is to use <your number of CPUs + 1> – e.g. to use 3 concurrently building job processes (dualcore CPU), do:
# make -j 3 |
Building in the background
If you intend to use your system while building, you can have the build process only use idle I/O and CPU capacity like this (dualcore CPU):
# ionice -c 3 nice -n 20 make -j 2 |
Spotting build errors
If for some reason the build fails, the easiest way to spot the error is to do:
# make V=99 |tee build.log |grep -i error |
The above saves a full verbose copy of the build output in build.log and only shows errors on the screen.
Another example:
# ionice -c 3 nice -n 20 make -j 2 V=99 CONFIG_DEBUG_SECTION_MISMATCH=y \ |tee build.log |egrep -i '(warn|error)' |
The above saves a full verbose copy of the build output in build.log and outputs only warnings and errors while building using only background resources on a dual core CPU.
Locating Images
After a successful build, the freshly built image(s) can be found in the newly created bin/ directory.
# cd bin/ # ls */ |
Building Packages
When developing or packaging software for OpenWrt, it is convenient to be able to build only the package in question (e.g. with package cups):
# make package/cups/compile V=99 |
Cleaning Up
We need more explaination on clean targets (dirclean, target/linux/clean, package/name/clean, …)
Cleaning the trunk/ directory after the build process is simple and only requires:
# make clean |
Note: It might be obvious to most people, but make sure to move the binaries to another location before issuing this command since it erases the contents of the "bin" directory, at least in OS X 10.5.8.
If complete cleaning of the build environment is required, then all what is takes is:
# make distclean |
There a numerous of other functionalities in the OpenWrt build system, but the above should have covered some of the fundamentals.
Installing OpenWrt
In comparison to the actual building of the desired image(s), the installation of the OpenWrt image can sometimes be a little, or more, of a challenge. It can be as simple as using the tools supplied by the manufacturer of the hardware (web interface or recovery tools), over manually uploading a new firmware via tftp and rebooting, to doing extensive hardware modifications with the intent of enabling JTAG access. Though, generally installation is made possible via the bootloader (Redboot, Uboot etc.) or simple copying onto a CompactFlash-card – all depending on the specific device.
See http://wiki.openwrt.org/doc/howto/installing for the specifics.
doc/howto/build.txt · Last modified: 2010/07/25 12:27 by ermo

