OpenWrt: Cross-compiling libmicrohttpd for TL-WR703N

Recently, I’ve been developing embedded webapps using node.js. Unfortunately, node.js is a bit bloated for resource-constrained platforms, such as the TL-WR703N running OpenWrt. Not only is it too large to fit into flash memory, requiring an external USB drive to run EXTROOT, but I’ve even encountered circumstances where I’ve been running out of RAM. Thus, I’ve been looking for a lean & mean HTTP library written in C. Right now, my top two candidates are axTLS and libmicrohttpd. Since it’s impractical to host a toolchain on the TL-WR703N, we have to cross-compile everything, which can be a bit of a chore to set up. The first step is to download and unpack the source code:

% wget http://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.38.tar.gz
% tar xzvf libmicrohttpd-0.9.38.tar.gz

If you don’t already have an OpenWrt toolchain set up, you can download and install it as follows:

% wget http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/OpenWrt-Toolchain-ar71xx-for-mips_r2-gcc-4.6-linaro_uClibc-0.9.33.2.tar.bz2
% bzip2 -dc OpenWrt-Toolchain-ar71xx-for-mips_r2-gcc-4.6-linaro_uClibc-0.9.33.2.tar.bz2 | tar xvf –

Next, we need a build script. Save the bash script below as build_libmicrohttpd_mipsbe.sh:

[code language=”bash”]
#!/bin/bash
#
# compile libmicrohttpd for ar71xx (mipsbe)
#

export BASEDIR=$(pwd)

### begin configuration

# node src directory
export SRCDIR=libmicrohttpd-0.9.38

#adjust STAGING_DIR and TOOLDIR below based on location of your toolchain
#ToolChain
export STAGING_DIR=${BASEDIR}/OpenWrt-Toolchain-ar71xx-for-mips_r2-gcc-4.6-linaro_uClibc-0.9.33.2/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2
#export STAGING_DIR=${BASEDIR}/openwrt/attitude_adjustment/staging_dir

export TOOLDIR=${STAGING_DIR}/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2

### end configuration

export TARGET_PATH=${BASEDIR}/${SRCDIR}-mipsbe
export PREFIX=${TOOLDIR}/bin/mips-openwrt-linux-
export LIBPATH=${TOOLDIR}/lib/

# MIPS cross-compile exports
export CC=${PREFIX}gcc
export CXX=${PREFIX}g++
export AR=${PREFIX}ar
export RANLIB=${PREFIX}ranlib
export LINK=${PREFIX}g++
export CPP="${PREFIX}gcc -E"
export STRIP=${PREFIX}strip
export OBJCOPY=${PREFIX}objcopy
export LD=${PREFIX}g++
export OBJDUMP=${PREFIX}objdump
export NM=${PREFIX}nm
export AS=${PREFIX}as
export PS1="[${PREFIX}] \w$ "
export LDFLAGS=’-Wl,-rpath-link ‘${LIBPATH}

rm -rf ${TARGET_PATH}
mkdir ${TARGET_PATH}
cd ${SRCDIR}
make clean
make distclean
./configure –prefix=${TARGET_PATH} –host=mips-openwrt-linux-uclibc –without-snapshot –with-mips-float-abi=soft
make
make install
[/code]

If your toolchain is in a different place from the STAGING_DIR specified in the script, adjust it to point to the proper location. Finally, execute the build script:

% sh build_libmicrohttpd_mipsbe.sh

After the build is complete, you can test it out by transferring one of the example files to your TL-WR703N running OpenWrt. A good candidate would be src/examples/fileserver_example. In addition to the executable, you also need to get the shared library onto your OpenWrt machine. It is built into a strange location: src/examples/microhttpd/.libs/libmicrohttpd.so.10. Put the file in /usr/lib/libmicrohttpd.so.10 on your target machine. Finally, you should be able to execute fileserver_example on the target machine.