User Tools

Site Tools


doc:howto:obtain.firmware.sdk.old

Using the SDK Archive

Outdated Information!
This article contains information that is outdated or no longer valid. You can edit this page to update it.

current information available at: obtain.firmware.sdk

oldwiki: About the OpenWrt SDK

This howto is for people who would like to port/package applications to OpenWrt with the OpenWrt Software Development Kit (SDK).

When using the SDK you don't require a full buildroot. The SDK is a stripped down version of it, which includes the toolchain and all the required library and header files to cross-compile applications for OpenWrt.

Requirements

  • a recent GNU/Linux distribution
  • GNU Make (at least 3.80 with the Debian patch)
  • wget
  • patch

These packages suffice for the "Hello world" program described below

Using the OpenWrt SDK

TIP: Before you begin porting your own package to OpenWrt, check if it has not been already done by someone else. To check that browse the subversion repository of the development version in your web browser and see if the package is already there. Don't do the work twice.

Let's start with porting and packaging the well known "Hello world" program as an example.

Attitude Adjustment 12.09

  • ccache required
  • see BB

Ressources for 10.03 / Backfire

Obtaining and installing the SDK

The SDK can be downloaded from http://downloads.openwrt.org/whiterussian/newest/.

Download it into your home directory (don't use the root account) and untar the tarball. After that change into the new directory.

cd ~
wget http://downloads.openwrt.org/whiterussian/newest/OpenWrt-SDK-Linux-i686-1.tar.bz2
bzcat OpenWrt-SDK-Linux-i686-1.tar.bz2 | tar -xvf -
cd ~/OpenWrt-SDK-Linux-i686-1

Creating the directories

Create the following directories:

cd ~/OpenWrt-SDK-Linux-i686-1
mkdir -p package/helloworld/ipkg
mkdir -p package/helloworld/patches

Directories and their contents:

#!CSV
Directory; Description
ipkg; Control file which contains information about your package
patches; Patch files for example 100-foo.patch

TIP: To compile more than one package in a special order do:

cd ~/OpenWrt-SDK-Linux-i686-1
mkdir -p package/100-packagename/ipkg
mkdir -p package/100-packagename/patches
mkdir -p package/200-packagename/ipkg
mkdir -p package/200-packagename/patches

Creating the required files

TIP: If you intend to 'copy & paste' the text from this Wiki to create files on your system, then use the Unix command

unexpand
to translate the leading spaces into tabs.

unexpand --first-only - >package/helloworld/Config.in

After pasting it into a text editor, press

ENTER
and then
CTRL-D
keys to save the file.

You can also create your own files in the

package/helloworld
directory (for example config files). That files you can access in your
package/helloworld/Makefile
with
./filename
and copy it to your
$(PKG_INSTALL_DIR)
directory.

package/helloworld/Config.in

config BR2_PACKAGE_HELLO
        prompt "hello............................. The classic greeting, and a good example"
        tristate
        default m if CONFIG_DEVEL
        help
              The GNU hello program produces a familiar, friendly greeting.  It
              allows non-programmers to use a classic computer science tool which
              would otherwise be unavailable to them.
               *
              Seriously, though: this is an example of how to do a Debian package.
              It is the Debian version of the GNU Project's `hello world' program
              (which is itself an example for the GNU Project).
              http://www.wheretofindpackage.tld

You need to create a Config.in file. It identifies the package name. In the above example BR2_PACKAGE_HELLO identifes that this is a 'BR2'(??) formatted 'PACKAGE' whose name is 'HELLO'. The final executable is 'hello'.

package/helloworld/Makefile

The Makefile determines the way the software package is shipped. Basically we can divide the software into 2 main categories :

  • C (or ANSI-C) programs
  • shipped with configure script
  • shipped with Makefile script (with references to gcc or $(CC) )
  • sources files only
  • C++ programs
  • potentially uClibc++ linkables
  • not uClibc++ linkables

TIP: Use the

md5sum
command to create the
PKG_MD5SUM
from the original tarball. Use
@SF/hello
(choose a and expanded random SourceForge mirror) for the
PKG_SOURCE_URL
when your program has a download location on SourceForge.

If PKG_SOURCE_URL and PKG_SOURCE are correctly identified, then the file will be downloaded into the ~/OpenWrt-SDK-Linux-i686-1/dl/ directory. It will be expanded into the ~/OpenWrt-SDK-Linux-i686-1/build_mipsel/ directory for compilation and processing.

Sample Makefile for C/C++ programs shipped with configure script

include $(TOPDIR)/rules.mk
PKG_NAME:=hello
PKG_VERSION:=2.1.1
PKG_RELEASE:=1
PKG_MD5SUM:=70c9ccf9fac07f762c24f2df2290784d
PKG_SOURCE_URL:=ftp://ftp.cs.tu-berlin.de/pub/gnu/hello \
        http://mirrors.sunsite.dk/gnu/hello \
        http://ftp.gnu.org/gnu/hello
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_CAT:=zcat
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
include $(TOPDIR)/package/rules.mk
$(eval $(call PKG_template,HELLO,$(PKG_NAME),$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
$(PKG_BUILD_DIR)/.configured: $(PKG_BUILD_DIR)/.prepared
        (cd $(PKG_BUILD_DIR); \
                $(TARGET_CONFIGURE_OPTS) \
                CFLAGS="$(TARGET_CFLAGS)" \
                CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \
                LDFLAGS="-L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \
                 */configure \
                        --target=$(GNU_TARGET_NAME) \
                        --host=$(GNU_TARGET_NAME) \
                        --build=$(GNU_HOST_NAME) \
                        --prefix=/usr \
                        --without-libiconv-prefix \
                        --without-libintl-prefix \
                        --disable-nls \
        );
        ## Add software specific configurable options above
        ## See : ./configure --help
        touch $@
$(PKG_BUILD_DIR)/.built:
        rm -rf $(PKG_INSTALL_DIR)
        mkdir -p $(PKG_INSTALL_DIR)/usr/bin
        $(MAKE) -C $(PKG_BUILD_DIR)/src \
                $(TARGET_CONFIGURE_OPTS) \
                prefix="$(PKG_INSTALL_DIR)/usr"
        $(CP) $(PKG_BUILD_DIR)/src/hello $(PKG_INSTALL_DIR)/usr/bin
        touch $@
$(IPKG_HELLO):
        install -d -m0755 $(IDIR_HELLO)/usr/bin
        $(CP) $(PKG_INSTALL_DIR)/usr/bin/hello $(IDIR_HELLO)/usr/bin
        $(RSTRIP) $(IDIR_HELLO)
        $(IPKG_BUILD) $(IDIR_HELLO) $(PACKAGE_DIR)
mostlyclean:
        make -C $(PKG_BUILD_DIR) clean
        rm $(PKG_BUILD_DIR)/.built

Sample Makefile for C/C++ software shipped with a Makefile containing references to gcc or $(CC)

If you Makefile contains harcoded "gcc" commands, then you will have to patch the makefile and replace gcc with $(CC) in order to define at "make time" the cross-compiler to use.

/!\ Note this Makefile is provided as an example only; it will not compile

include $(TOPDIR)/rules.mk
PKG_NAME:=hello
PKG_VERSION:=2.1.1
PKG_RELEASE:=1
PKG_MD5SUM:=70c9ccf9fac07f762c24f2df2290784d
PKG_SOURCE_URL:=ftp://ftp.cs.tu-berlin.de/pub/gnu/hello \
        http://mirrors.sunsite.dk/gnu/hello \
        http://ftp.gnu.org/gnu/hello
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_CAT:=zcat
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
include $(TOPDIR)/package/rules.mk
$(eval $(call PKG_template,HELLO,$(PKG_NAME),$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
$(PKG_BUILD_DIR)/.configured: $(PKG_BUILD_DIR)/.prepared
        #Since there is no configure script, we can directly go to the building step
        touch $@
$(PKG_BUILD_DIR)/.built:
        rm -rf $(PKG_INSTALL_DIR)
        mkdir -p $(PKG_INSTALL_DIR)/usr/bin
        #Note here that we pass cross-compiler as default compiler to use
        $(MAKE) -C $(PKG_BUILD_DIR)/src \
                CC=$(TARGET_CC) \
                $(TARGET_CONFIGURE_OPTS) \
                prefix="$(PKG_INSTALL_DIR)/usr"
        $(CP) $(PKG_BUILD_DIR)/src/hello $(PKG_INSTALL_DIR)/usr/bin
        touch $@
$(IPKG_HELLO):
        install -d -m0755 $(IDIR_HELLO)/usr/bin
        $(CP) $(PKG_INSTALL_DIR)/usr/bin/hello $(IDIR_HELLO)/usr/bin
        $(RSTRIP) $(IDIR_HELLO)
        $(IPKG_BUILD) $(IDIR_HELLO) $(PACKAGE_DIR)
mostlyclean:
        make -C $(PKG_BUILD_DIR) clean
        rm $(PKG_BUILD_DIR)/.built

Sample Makefile for C/C++ programs without makefiles (usually one or two source files)

/!\ Note this Makefile is provided as an example only; it will not compile

include $(TOPDIR)/rules.mk
PKG_NAME:=hello
PKG_VERSION:=2.1.1
PKG_RELEASE:=1
PKG_MD5SUM:=70c9ccf9fac07f762c24f2df2290784d
PKG_SOURCE_URL:=ftp://ftp.cs.tu-berlin.de/pub/gnu/hello \
        http://mirrors.sunsite.dk/gnu/hello \
        http://ftp.gnu.org/gnu/hello
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_CAT:=zcat
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
include $(TOPDIR)/package/rules.mk
$(eval $(call PKG_template,HELLO,$(PKG_NAME),$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
$(PKG_BUILD_DIR)/.configured: $(PKG_BUILD_DIR)/.prepared
        #Since there is no configure script, we can directly go to the building step
        touch $@
$(PKG_BUILD_DIR)/.built:
        rm -rf $(PKG_INSTALL_DIR)
        mkdir -p $(PKG_INSTALL_DIR)/usr/bin
        $(TARGET_CC) $(PKG_BUILD_DIR)/src/$(PKG_NAME).c -o $(PKG_BUILD_DIR)/$(PKG_NAME) ## -lyourlib #Note we directly call the cross-compiler and define its output
        $(CP) $(PKG_BUILD_DIR)/src/hello $(PKG_INSTALL_DIR)/usr/bin
        touch $@
$(IPKG_HELLO):
        install -d -m0755 $(IDIR_HELLO)/usr/bin
        $(CP) $(PKG_INSTALL_DIR)/usr/bin/hello $(IDIR_HELLO)/usr/bin
        $(RSTRIP) $(IDIR_HELLO)
        $(IPKG_BUILD) $(IDIR_HELLO) $(PACKAGE_DIR)
mostlyclean:
        make -C $(PKG_BUILD_DIR) clean
        rm $(PKG_BUILD_DIR)/.built

Sample Makefile for C++ shipped with configure script, and uClibc++ linkables

/!\ Note this Makefile is provided as an example only; it will not compile

include $(TOPDIR)/rules.mk
PKG_NAME:=hello
PKG_VERSION:=2.1.1
PKG_RELEASE:=1
PKG_MD5SUM:=70c9ccf9fac07f762c24f2df2290784d
PKG_SOURCE_URL:=ftp://ftp.cs.tu-berlin.de/pub/gnu/hello \
        http://mirrors.sunsite.dk/gnu/hello \
        http://ftp.gnu.org/gnu/hello
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_CAT:=zcat
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
include $(TOPDIR)/package/rules.mk
$(eval $(call PKG_template,HELLO,$(PKG_NAME),$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
$(PKG_BUILD_DIR)/.configured: $(PKG_BUILD_DIR)/.prepared
        (cd $(PKG_BUILD_DIR); \
                $(TARGET_CONFIGURE_OPTS) \
                CFLAGS="$(TARGET_CFLAGS)" \
                CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \
                LDFLAGS="-L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \
                 */configure \
                        CXXFLAGS="$(TARGET_CFLAGS) -fno-builtin -fno-rtti -nostdinc++" \
                        CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \
                        LDFLAGS="-nodefaultlibs -L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \ #do not use default libraries since we want uClibc++ linking
                        LIBS="-luClibc++ -lc -lm -lgcc" \ # You may need to add other libraries : lpcap, lssl ... #
                        --target=$(GNU_TARGET_NAME) \
                        --host=$(GNU_TARGET_NAME) \
                        --build=$(GNU_HOST_NAME) \
                        --prefix=/usr \
                        --without-libiconv-prefix \
                        --without-libintl-prefix \
                        --disable-nls \
        );
        ## Add software specific configurable options above
        ## See : ./configure --help
        touch $@
$(PKG_BUILD_DIR)/.built:
        rm -rf $(PKG_INSTALL_DIR)
        mkdir -p $(PKG_INSTALL_DIR)/usr/bin
        $(MAKE) -C $(PKG_BUILD_DIR)/src \
                $(TARGET_CONFIGURE_OPTS) \
                prefix="$(PKG_INSTALL_DIR)/usr"
        $(CC) $(PKG_BUILD_DIR)/src/hello $(PKG_INSTALL_DIR)/usr/bin
        touch $@
$(IPKG_HELLO):
        install -d -m0755 $(IDIR_HELLO)/usr/bin
        $(CP) $(PKG_INSTALL_DIR)/usr/bin/hello $(IDIR_HELLO)/usr/bin
        $(RSTRIP) $(IDIR_HELLO)
        $(IPKG_BUILD) $(IDIR_HELLO) $(PACKAGE_DIR)
mostlyclean:
        make -C $(PKG_BUILD_DIR) clean
        rm $(PKG_BUILD_DIR)/.built

package/helloworld/ipkg/hello.control

The control file, as you might have guessed, controls the package information reported by ipkg.

Anyone familiar with Debian packaging will be aware of the format - a deeper description than provided here is available in the ipkg documentation.

Package: hello
Priority: optional
Section: misc
Description: The GNU hello world program

The following fields are available:

  • Package - should be the package name, as in the Makefile.

Priority - should be set to optional for almost all packages. Section - indicates the type of package - useful sections include comm, editors, graphics, libs, net, text, web, or if you can't decide, misc. Description - a short description of the package. (You can include a longer description here in a similar manner to the help text in Config.in. Start a new line after the short description, and use a line containing a single full stop ('.') as a replacement for blank lines. Depends (not in the example above) - a list of package names that this package requires to operate. Use package names without versions here where possible (e.g. openssh-client).

Note: had to modify package/rules.mk changing ./ipkg/$(2) to the real directory ./ did not work for me

package/helloworld/patches/100-hello.patch

This example applies a Debian patch, which isn't essential for (so you can skip this point).

Other Linux and free UNIX distributions are often an excellent source of patches for non-portable programs. You might like to try searching for packages from Ubuntu, Gentoo, or FreeBSD's Ports.

cd package/helloworld/patches
wget http://ftp.debian.org/debian/pool/main/h/hello/hello_2.1.1-4.diff.gz
gunzip hello_2.1.1-4.diff.gz
mv hello_2.1.1-4.diff 100-hello.patch

TIP: You can apply as many patches as you like. To apply them in a special order name them like:

100-xxx.patch
200-xxx.patch

Compile the package

The make command below compiles every package that you have created in the package directory.

cd ~/OpenWrt-SDK-Linux-i686-1
make clean && make world

Note that there is a fault in the default package/rules.mk file. There is ".." following the "$(PKG_BUILD_DIR)/" which causes the files to be extracted to the wrong directory. Here is the corrected version:

ifneq ($(strip $(PKG_CAT)),)
$(PKG_BUILD_DIR)/.prepared: $(DL_DIR)/$(PKG_SOURCE)
	rm -rf $(PKG_BUILD_DIR)
	mkdir -p $(PKG_BUILD_DIR)
	$(PKG_CAT) $(DL_DIR)/$(PKG_SOURCE) | tar -C $(PKG_BUILD_DIR)/ $(TAR_OPTIONS)
	if [ -d ./patches ]; then \
		$(PATCH) $(PKG_BUILD_DIR) ./patches ; \
	fi
	touch $(PKG_BUILD_DIR)/.prepared
endif

NOTE: If you are using GNU make 3.80 (current "latest") and get a "virtual memory exhausted" message while making, see this page.

For Slackware users there is a fixed make package here and sources + patch are here.

When the compiling is finished you have a ready to use ipkg package for OpenWrt in the

~/OpenWrt-SDK-Linux-i686-1/bin/packages
directory.

cd bin/packages; ls -al hello_2.1.1-1_mipsel.ipk
-rw-r--r--  1 openwrt-dev openwrt-dev 3976 Sep 14 13:03 hello_2.1.1-1_mipsel.ipk

Contribute your new ported program

When you like you can contribute your program/package to the OpenWrt community. It may be included in further versions of OpenWrt.

To do this create a patch from your

package/
directory with:

cd ~/OpenWrt-SDK-Linux-i686-1
diff -ruN package/.orig package/ > -.patch

Once you have created a patch open a ticket and submit your new package (the patch).

Native Development

You need 150Mb storage unit (USB or SD Card)

- Download the file Native Mipsel Toolchain (24Mb)

- Bunzip2 (120mb) it to the storage unit in a ext2 partition.

- unmount partition

- Execute this script, I have it at /sbin/devel.sh

#!/bin/sh
# Kill unusefull tasks (uncoment it) we need memory
#killall logger
#killall syslogd
#killall telnetd
#killall crond
#killall klogd
#killall udhcpc
#killall httpd
#rmmod ext3
#rmmod jbd
#My SD card have 2 partitions 1.ext2  2.swap
mount /dev/mmc/disc0/part1 /mnt -o noatime async
# Swap for large sources. I have 30Mb
#swapoff -a
#mkswap  /dev/mmc/disc0/part2
#swapon  /dev/mmc/disc0/part2
mount -o move /tmp /mnt/tmp
echo " *** exit *** to back - Para volver al sistema"
chroot /mnt/ /bin/ash -
echo " *** Me are here again - De vuelta al sistema original ***"
mount -o move /mnt/tmp/ /tmp/
umount /mnt

- Go /home

- download the source. Example: Didiwiki-0.5.tar.gz from http://www.didiwiki.org

- tar -xvzf didiwiki-0.5.tar.gz

- cd didiwiki-0.5

- configure (1 minute)

- make (1 minute)

- You have your new Binary in the SRC directory (didiwiki)

- copy it to the /tmp directori

- type exit

You have the binary in /tmp directory. copy it to /usr/bin

The result didiwiki.mipsel.binary.gz a small wiki for our router at 8000 port. If you don't use storage unit, you must create /home to store new pages. /home/.didiwiki/*

Links

You can find an useful reference for the packaging process in nbd's paper to the 'OpenWrt Hacking' talk on the 22C3:
- http://events.ccc.de/congress/2005/fahrplan/attachments/567-Paper_HackingOpenWRT.pdf

Full buildroot documentation (for compiling kernel modules and such things, for the rest the SDK should be used)
- http://downloads.openwrt.org/docs/buildroot-documentation.html

doc/howto/obtain.firmware.sdk.old.txt · Last modified: 2015/05/05 09:29 by theoradicus