Building Software against EGLIBC
Some software like numpy doesn't build against uClibc, which is the C library used in the default software image - see below for details. Embedded GLIBC (EGLIBC) offers a potential solution because it provides the missing floating point-related functionality, but it appears that OpenWrt is not routinely or, at least, widely used with that particularly C library, currently.
 Configuring OpenWrt for EGLIBC
To build the software using EGLIBC, it is necessary to run
make menuconfig and choose...
Advanced configuration options (for developers)
C Library implementation
- Then, choose
eglibcfrom the list.
- Now, in the
Toolchain Optionsmenu, choose a library version.
- Finally, disable
Use setjump()/longjump() exceptions. (See below for the consequences of this option being left enabled.)
(If available, the OpenWrt "trunk" build of EGLIBC doesn't seem to work:
toolchain/eglibc/Makefile happily puts
trunk into its configuration but doesn't tell EGLIBC, so it then seems to invent its own identifier (
libc/Makeconfig that the installation operation of
base-packages isn't aware of. To summarise: don't bother with the "trunk" option; choose a real version if a choice exists.)
 Building the Toolchain
It seems possible to be able to make just the toolchain as follows:
make tools/install make toolchain/install
 Building Packages
Once the toolchain is available, the configuration can be changed to add packages like
numpy. If this is done using the
make menuconfig command, it should be possible to then perform a build; otherwise, having edited the
.config directly, try running
make oldconfig first.
To compile individual packages and their dependencies - for example,
numpy - issue a command like the following:
This should put the package files in the
 Building EGLIBC Packages
It appears possible to build the necessary
libc and related packages by building the
However, since we will test these packages in a
chroot environment as described below, it is also necessary to compile busybox and its dependencies:
 Installing the Packages
You can now copy the packages to a location on your NanoNote, perhaps using Ethernet over USB.
Since we do not want to install the packages to their normal locations - doing so will overwrite existing files and may make your NanoNote unusable - you must create a special configuration file for the package manager.
On the NanoNote, copy the following into a new file called
eglibc_opkg.conf (for example):
dest root /root/eglibc dest ram /usr/share/opkg/tmp lists_dir ext /usr/share/opkg option overlay_root /overlay
This should resemble your system's
/etc/opkg.conf file but use a different
dest root setting. Here, we define a root in
/root/eglibc, so this means that we should also set up such a directory to hold our test packages:
You can now install the packages by issuing a command like the following:
opkg -f eglibc_opkg.conf install packages/*.ipk
packages is a directory containing all the packages built against EGLIBC. It is essential that you use the
-f option and that the specified file contains a modified
dest root setting; otherwise, you could overwrite various critical libraries and end up with an unbootable NanoNote.
 Testing the Packages
To test the packages, you now need to enter the package area using the
This should start a shell and everything you see should originate from the package area but appear as if it were a system of its own. If this works it means that the software is using EGLIBC instead of uClibc. Exiting this shell will release you from the chroot environment.
Some packages will need to see devices, and an easy way to make them available is to bind mount the necessary filesystems. Do this before running
mount -o bind /dev /root/eglibc/dev mount -o bind /proc /root/eglibc/proc mount -o bind /sys /root/eglibc/sys
If you decide to remove the
/root/eglibc directory, it is essential that you unmount these filesystems first:
umount /root/eglibc/dev umount /root/eglibc/proc umount /root/eglibc/sys
Otherwise, you may end up removing important files.
 Test Results
Testing in a chroot as described above indicates that numpy and
pygame.surfarray work when EGLIBC is used, although numpy needs to be changed to import fewer subpackages with EGLIBC 2.15 in order to avoid exhausting the available memory on the NanoNote (without swap in use).
Pygame works with numpy built against EGLIBC: the
pygame.surfarray module works as intended.
 Possible Errors
Initially, when compiling with the default NanoNote configuration adjusted to use EGLIBC (2.14 or 2.15), Pygame/SDL didn't release the framebuffer upon exit due to an error:
libgcc_s.so.1 must be installed for pthread_cancel to work.
Although this appeared to be a linker search path issue - the linker apparently not finding the library file, and the absence of
--sysconfdir=/etc when configuring EGLIBC might have contributed to such a problem - in fact, the linker was finding the library, but was unable to find certain symbols.
 Missing Symbols in libgcc_s
LD_DEBUG=all gave the following details:
/lib/libgcc_s.so.1: error: symbol lookup error: undefined symbol: _Unwind_Resume (fatal)
It actually looks as if the given symbol is missing from
/lib/libgcc_s.so.1 which does itself seem to be found, so the original error is misleading.
There does seem to be a configuration option to indicate whether gcc will support SJLJ (set-jump, long-jump) exceptions or frame unwinding. This option is controlled in OpenWrt using the
SJLJ_EXCEPTIONS setting in the Config.in file for the gcc package. See also
--enable-sjlj-exceptions in the libstdc++ manual. The configuration and the build are connected via the Makefile for the final gcc build, in particular the following code:
ifneq ($(CONFIG_SJLJ_EXCEPTIONS),) GCC_CONFIGURE += \ --enable-sjlj-exceptions endif
This was added in the following commit: toolchain/gcc: add option SJLJ_EXCEPTIONS to select gcc's exception handling. There's also a related bug, #9185, in OpenWrt.
It looks like this option is set in the default configuration:
The solution to the error involves unsetting this option (and thus removing
--enable-sjlj-exceptions from the GCC-related configuration). With a rebuilt toolchain,
/lib/libgcc_s.so.1 gains the necessary symbols, and rebuilt packages then appear to work correctly, with SDL releasing the framebuffer successfully on exit (presumably because an exception is properly handled).
 uClibc Issues
The numpy code includes the
fenv.h header file, but this is not available for most architectures as of uClibc 0.9.33. Adding
UCLIBC_HAS_FENV to the OpenWrt configuration allows numpy to be built, but importing it causes a segmentation fault on the NanoNote.