Registered a URL and setup a forum as the IPCam stuff really needed its own site vs my irregular blog posts about IPCam hacking at

Author Topic: Building opkg (and other programs that don't have Makefiles)  (Read 7400 times)

  • No avatar
  • *****
February 26, 2011, 06:26:22 pm
I'd like to use a package management system so that I can add / remove features as needed for the camera.

We'll need a writable file system for this, JFFS2 is suitable, and compiles in quite easily.
I've already compiled up a kernel with suitable support for the hardware, and jffs2 support for the romfs, so its really just a matter of compiling up ipkg/opkg for our device.

ipkg, which is now called opkg is a  small package management tool suited for small embedded devices like ours.

Unfortunately it doesn't have a build script, so we have to configure it ourselves.
Before we start, lets go over some basics -

We can't use shared libraries.
We have to tell their installer that we're cross compiling.
Lastly the gcc 3.0 compiler is too old, so we'll need to use the 3.3.4 version.

With those noted, lets have a look.

First, we'll need to go get opkg. 

Change to your user folder, and download in there, as its a suitable location.
Opkg can be downloaded here -

Current version is 0.1.8

Download and unzip within your uClinux-dist/user folder

Code: [Select]
tar -zxvf opkg-0.1.8.tar.gz
cd opkg-0.1.8

We'll need to configure the build now, remember that we can't use the gcc 3.0 toolset, as it borks during the build process, so you need to use the 3.3.4 tools.

I usually do this by temporarily renaming the /usr/local/arm_tools folder to /usr/local/arm_tools3.0
and renaming my /usr/local/arm_tools_3.3 folder as /usr/local/arm_tools

(You can find the 3.3.4 gcc toolkit in the BSP install folder)


Lets setup all the configuration options we'll need to use for our build.

Code: [Select]

CC=arm-elf-gcc \
CXX=arm-elf-g++ \
AR=arm-elf-ar \
STRIP=arm-elf-strip \
ARCH=armnommu  \
CROSS_COMPILE=arm-elf- \
CFLAGS='-march=armv4 -mtune=arm7tdmi -mshort-load-bytes -mapcs-32' \
LDFLAGS='-elf2flt=-z' \
 ./configure --host=arm-linux --build=i686-pc-linux --enable-curl=false --enable-gpg=false --enable-shared=false --enable-static

Looks complicated doesn't it!
Lets take a closer look at whats happening in each of the sections within.

First, we specify our compiler file locations.  Strictly speaking we should be able to just specify CROSS_COMPILE=arm-elf-  but I prefer to make sure that the configure gets the options from us manually just in case it decides on a whim to use the system compiler.
Code: [Select]
CC=arm-elf-gcc \
CXX=arm-elf-g++ \
AR=arm-elf-ar \
STRIP=arm-elf-strip \
ARCH=armnommu  \
CROSS_COMPILE=arm-elf- \

CFLAGS is where we setup all the juicy compile options.
Here we tell the compiler to build an optimized exe for our arm model and architecture.
Code: [Select]
CFLAGS='-march=armv4 -mtune=arm7tdmi -mshort-load-bytes -mapcs-32'

LDFLAGS is where we tell the linker to compress our final executable.  We could do this later with flthdr -z filename, but why not do it in the build.
Code: [Select]

Lastly, we run configure with the various options for opkg.
We tell it again that we're cross compiling.  We disable curl and gpg (space is an issue), and lastly tell it not to use shared libraries, just use static ones.
Code: [Select]
./configure --host=arm-linux --build=i686-pc-linux --enable-curl=false --enable-gpg=false --enable-shared=false --enable-static

It should trundle along and come up with a Makefile configured with those options.

If we run make, it should compile cleanly without issue.
Where is the output though?

opkg sticks its output in the src folder, so lets change to that folder, and take a look at the compiled executable.

Code: [Select]
#cd src
ls -al
total 712
drwxrwxrwx  4 1005 1005   4096 2011-02-26 16:58 .
drwxrwxrwx 10 1005 1005   4096 2011-02-26 16:57 ..
drwxr-xr-x  2 root root   4096 2011-02-26 16:58 .deps
drwxr-xr-x  2 root root   4096 2011-02-26 16:58 .libs
-rw-r--r--  1 root root  15307 2011-02-26 16:57 Makefile
-rw-r--r--  1 1005 1005    203 2009-12-20 18:02
-rw-r--r--  1 1005 1005  14787 2010-02-21 16:39
-rwxr--r--  1 root root 105149 2011-02-26 16:58 opkg-cl
-rw-r--r--  1 1005 1005  10504 2010-01-11 18:49 opkg-cl.c
-rwxr-xr-x  1 root root 564837 2011-02-26 16:58 opkg-cl.gdb
-rw-r--r--  1 root root  11572 2011-02-26 16:58 opkg-cl.o
# file opkg-cl
opkg-cl: BFLT executable - version 4 ram gzip

As you can see, the compiled version is already compressed, and configured correctly for our platform (v4 arm, runs in ram, and is gzipped).

Filesize is a little large at 105kb, but thats because we have it compiled as a static library. The takes up most of that.

We should test this on our device to make sure it actually works, but it now looks like we have a package management system we can use.

We can also use these configure environment settings in other builds.  You'll need to amend the ./configure for the options in the program you're using, but otherwise its ok.

Next I need to setup an opkg repository for my executables (and others), so that we can create a common platform for the device, and install additional packages or modules (device drivers) on demand.

Cool stuff!