OpenWrt Forum Archive

Topic: [Howto] Write and compile a simple program for OpenWrt

The content of this topic has been archived on 3 May 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I recently found myself in the position of wanting to cross-compile a simple program to run on a router running OpenWrt.  Unfortunately, I found the existing documentation, especially the existing wiki entry, very frustrating to follow.  After considerable time wading through multiple previous forum posts and going though a lengthy process of trial-and-error I finally got my code compiling.  It occurred to me that someone else might be having similar difficulties, so I wrote a short tutorial on how to cross-compile code for OpenWrt.  This tutorial can be found here: http://people.bu.edu/ebishop/openwrt-programming.html

I hope this benefits someone who is having similar difficulties to what I ran into.

Excellent tutorial. That is how it should be done - even a newbie like me can follow this. Thanks.

I have just updated my tutorial with a new section.  The url of the tutorial is the same as before, and is listed above.

The first (older) part of the tutorial describes how to write and compile a simple C application for OpenWrt.  The second (newer) part describes how to write and compile a small C++ application that uses the C++ standard template library (STL).  In order to make such a program work on OpenWrt linking with uClibc++ (an implementation of the STL for embedded systems) is required.  A detailed explanation of how to do this is covered in the new section of my tutorial.

excellent!!!

ebishop wrote:

I recently found myself in the position of wanting to cross-compile a simple program to run on a router running OpenWrt.  Unfortunately, I found the existing documentation, especially the existing wiki entry, very frustrating to follow.  After considerable time wading through multiple previous forum posts and going though a lengthy process of trial-and-error I finally got my code compiling.  It occurred to me that someone else might be having similar difficulties, so I wrote a short tutorial on how to cross-compile code for OpenWrt.  This tutorial can be found here: http://people.bu.edu/ebishop/openwrt-programming.html

I hope this benefits someone who is having similar difficulties to what I ran into.

Please add a SUBMENU entry in the Package/helloworld macro and split the DESCRIPTION into a separate macro.

define Package/helloworld
    SECTION:=utils
    CATEGORY:=Utilities
    TITLE:=Helloworld -- prints a snarky message
    DESCRIPTION:=\
    If you can't figure out what this program does, \\\
    you're probably brain-dead and need immediate \\\
    medical attention.
endef

to

define Package/helloworld
  SUBMENU:=foobar
  SECTION:=utils
  CATEGORY:=Utilities
  TITLE:=Helloworld -- prints a snarky message
endef

define Package/Helloworld/description
 define Package/Helloworld/description
 If you can't figure out what this program does, you're probably
 brain-dead and need immediate medical attention.
endef

The Build/Prepare and Build/Compile macro only needs to be specified if your application does not use the standard way for compiling. If you need to add extra configure args or flags and make flags use CONFIGURE_ARGS, CONFIGURE_VARS and MAKE_FLAGS.

define Build/Compile
    $(MAKE) -C $(PKG_BUILD_DIR) \
        LIBS="-nodefaultlibs -lgcc -lc -luClibc++" \
        LDFLAGS="$(EXTRA_LDFLAGS)" \
        CXXFLAGS="$(TARGET_CFLAGS) $(EXTRA_CPPFLAGS) -nostdinc++" \
        $(TARGET_CONFIGURE_OPTS) \
        CROSS="$(TARGET_CROSS)" \
        ARCH="$(ARCH)" \
        $(1);
endef

This could look like:

MAKE_FLAGS += \
    LIBS="-nodefaultlibs -lgcc -lc -luClibc++" \
    LDFLAGS="$(EXTRA_LDFLAGS)" \
    CXXFLAGS="$(TARGET_CFLAGS) $(EXTRA_CPPFLAGS) -nostdinc++" \
    $(TARGET_CONFIGURE_OPTS) \
    CROSS="$(TARGET_CROSS)" \
    ARCH="$(ARCH)" \
    $(1) \

(Last edited by forum2006 on 11 Oct 2007, 12:40)

It is true that adjusting the MAKE_FLAGS, as you suggest is a more elegant solution.  However, this only works in Kamikaze.  In order to make the code work with White Russian, you need to redefine the whole Build/Compile directive.

Also, I recently discovered that if you are running Kamikaze, the best solution is to just install the libstdcpp package, which is unavailable for White Russian.  If you are running Kamikaze and have the libstdcpp package installed, the above-mentioned flags are unnecessary since you can just link to the standard library.  Therefore, it's rather important that the code listed here works in White Russian -- it's the only instance when it's really necessary!

I have updated my tutorial to reflect this simpler solution for those running Kamikaze.

WR is obsolete and no longer developed. Not only the Makefiles (e.g. MAKE_FLAGS) but also the configuration is changed to UCI. Backporting /packages with the WR SDK is already broken for a longer time...

Just because White Russian is no longer being developed doesn't mean there aren't plenty of us still running it.  My goal in writing this tutorial is to demonstrate how to write a SIMPLE program for OpenWrt, not how to port large complex programs or do serious development.  I'd imagine there are still people who either A) are using White Russian and want to compile small, simple programs for their own use or B) want to make sure their new package is backwards compatible.

Im one of those people - I got going with my OpenWRT adventure only a week and a half ago wondering about finally getting to that home automation project, so far I've done over a Siemens SE505, upgraded the ram to 32MB and booting off the USB Flash plus 2 USB serial adaptors and everything seems to be running very well. White Russian is the supported platform and that's fine for me as I dont need to be pioneering, I just need a stable platform to accomplish a simple application for now. Send a few X10 commands, read a few, throw a few packets over the network, send an SMS etc etc.

I did get through the SDK how to, and got it compiling but I have to admit it took me a good few hours and I havent even stopped to think about what standard libraries I might need to include and how, so its REALLY good to see this tutorial!!

Ive set up a dev machine running ubuntu and eclipse cdt, though eclipse is just working as a fancy text editor, would be nice to see a guide on getting eclipse to produce an ipkg when you hit build.

Must go and read that tutorial now, I only got as far as the last post, opened the link in the background and thought I d confess I am using white russian, getting to grips with c++ again after some years, and totally appreciating the existance of that tutorial and its backward compatibility...

I try to go trough this tutorial ( http://people.bu.edu/ebishop/openwrt-programming.html ) but without success. The result always at ipkg "An error occured, return value: 4." I got the same result with Kamikaze 7.07 and with OpenSlug-3.10 with NSLU2 hardware.  Any idea?

When ipkg exits with a return value of 4 it means that it couldn't find a valid .ipk file.  Are you sure you properly copied the file to the router and that the file path you passed ipkg is the right one? (e.g. make sure you're typing "ipkg install helloworld_1_mipsel.ipk" vs "ipkg install helloworld.ipk")

If this is definitely not the problem, send me (ericpaulbishop at gmail.com) a copy of the OpenWrt Makefile as well as the code you are trying to compile.  I realize the code is in the tutorial, but if you have changed it in any way a small detail may be the problem.  However, I should mention that I do not have access to a linksys NSLU2, so if the problem is hardware specific (though I really doubt this is the case) I probably won't be able to help.

"I realize the code is in the tutorial"
Lot of thank you for it.

"Are you sure you properly copied the file to the router "

The copy problem was my first think too. I try'd copy the .ipk to NSLU2 with scp and back and finally compare with diff --binary, and not found any difference. 

Next I try'd ipkg install with relative and absolute path. The result are same. If I specify wrong filename or wrong path I got a "No such file" message.

" send me... "
I forward you the package, build_mipsel directory and the .ipk file.

"if the problem is hardware specific "
I'm sure not. The difference only I use Kamikaze 7.07 and with OpenSlug-3.10, you try'd with White Russian 0.9 .

Some result. Tahk's to ebishop.

The src directory must not contain any compiled binary file! Remove it before do any make.

The OpenWrt-SDK-Linux-i686-1 is only for mips32 traget processors like the LinkSys WRT54xxx hardver use Broadcom processor based on MIPS32 core. So you never make executable binary for arm or ixp4 based hardver (eg. for nslu2).
But if you have for example LinkSys WAG54xx or NSLU2 then you must use OpenWrt-SDK-[TargetProcessor]-[KernelVersion]-for-Linux-[HostProcessor] SDK from http://downloads.openwrt.org pages. Unfortunately there no compiled i686 host pocessor version only x86_64.  This mean you need 64bit processor and linux to make package for.
To identify the processor of the hardware see http://wiki.openwrt.org/TableOfHardware pages.

I have once again updated my tutorial.  I made a few minor tweaks to the first two parts including emphasizing the necessity of removing any i686 object file generated from testing locally before copying the code to the SDK directory for cross-compiling.  I have also added a third section about how to compile your own Kamikaze SDK since, as kzsolt correctly points out above, the only binaries available for download are for the x86_64 architecture.

Woder full, excellent howto!!!
Thanks very, very much ebishop

(Last edited by fofware on 8 Jan 2008, 20:34)

My tutorial has moved.  I recently released a new web interface for OpenWrt called Gargoyle, and I've moved my programming tutorial to the official Gargoyle website.  You can now find the tutorial at: http://www.gargoyle-router.com/openwrt-coding.html

It works, great!!!

Your tutorial make my  learning proccess faster.
thx ebishop...

link is dead sad

is it possible to post the tutorial in this forum? or into the wiki?

Hi, I am trying to compile the simple C example.
I have Ubuntu 12.04, OpenWrt Backfire, the OpenWrt-SDK-brcm-2.4-for-Linux-i686-gcc-3.4.6_uClibc-0.9.30.1, and Wrt54GSv4.
I have done all the gargoyle tutorial says but I'll have this result when the make V=99 action is made,

victor@vip:~/OpenWrt-SDK-brcm-2.4-for-Linux-i686-gcc-3.4.6_uClibc-0.9.30.1$ make V=99
ERROR: please fix package/helloworld/Makefile
Collecting package info: done
make[1]: Entering directory `/home/victor/OpenWrt-SDK-brcm-2.4-for-Linux-i686-gcc-3.4.6_uClibc-0.9.30.1'
make[2]: Entering directory `/home/victor/OpenWrt-SDK-brcm-2.4-for-Linux-i686-gcc-3.4.6_uClibc-0.9.30.1'
make[2]: Nothing to be done for `package/compile'.
make[2]: Leaving directory `/home/victor/OpenWrt-SDK-brcm-2.4-for-Linux-i686-gcc-3.4.6_uClibc-0.9.30.1'
make[2]: Entering directory `/home/victor/OpenWrt-SDK-brcm-2.4-for-Linux-i686-gcc-3.4.6_uClibc-0.9.30.1'
make[2]: Leaving directory `/home/victor/OpenWrt-SDK-brcm-2.4-for-Linux-i686-gcc-3.4.6_uClibc-0.9.30.1'
make[1]: Leaving directory `/home/victor/OpenWrt-SDK-brcm-2.4-for-Linux-i686-gcc-3.4.6_uClibc-0.9.30.1'

Does anyone have this problem before? I cant find a solution.

Please help!!!

The discussion might have continued from here.