Cross-building LibGTop

LibGTop is a library used to get system specific data such as CPU, memory usage and info about running processes.
Since it’s part of the GNOME desktop environment, it’s used by some system monitor applets, but it’s main interface is completely independent, so it can be used as a standalone library even for embedded system that already use GLib.

Normally, you should debug your system before deployment and be sure that there are no processes with memory leaks or that are consuming more CPU than they should, but sometimes there could be strange conditions in a process that at certain point start to eat too much CPU or just Valgrind doesn’t support your processor.

In these cases, the system needs to be closely monitored and a library like LibGTop with an API that you can easily use could be quite handy.

I normally use Buildroot, but it doesn’t include LibGTop, it seems that Yocto doesn’t have a recipe neither. I’ll try to explain briefly how to cross-build it for an ARM processor that I’m using with the Linaro hard-float toolchain.


First, let’s export common environment variables that make our life easier:

export HOST=arm-linux
export BUILD=i386-linux
export PREFIX=/home/paguilar/rootfs

Configure remove unneeded things for an embedded system:

CC=arm-linux-gnueabihf-gcc ./configure --host=$HOST --build=$BUILD --prefix=$PREFIX --with-sysroot=$PREFIX --disable-gtk-doc-html --without-examples --without-libiconv-prefix --without-libintl-prefix --without-x 

Edit lib/Makefile and set the following variables:

GLIB_CFLAGS = -I/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/sysroot/usr/include 
GLIB_LIBS = -L/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/sysroot/usr/lib -lgobject-2.0 -lglib-2.0 

Compile and install:

make DESTDIR=/home/paguilar/rootfs install

You can have a look at the GLibTop API here.
That’s it.

Skipping incompatible /lib/ when searching for /lib/

When cross-building a program (but this could also happen when building natively), it’s normal that we don’t have the environment variables and building flags set with the right paths that indicate where the toolchain and the sysroot are.

The wrong paths can lead to many types of building errors at different stages. This one happened to me recently:

arm-linux-gnueabi-gcc -L/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabi/qt5/arm-buildroot-linux-gnueabi/sysroot/lib -L/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabi/qt5/arm-buildroot-linux-gnueabi/sysroot/lib32 -L/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabi/qt5/arm-buildroot-linux-gnueabi/sysroot/usr/lib -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lz myfile.o -o myfile
/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabi/4.9.3/../../../../arm-linux-gnueabi/bin/ld: skipping incompatible /lib/ when searching for /lib/
collect2: error: ld returned 1 exit status

This linking error says that it is skipping an incompatible library that is searching in my host’s filesystem even though I explicitly indicated in the Makefile the paths to use in the environment variable LDFLAGS with the -L:

LDFLAGS = -L$(SYSROOT)/lib -L$(SYSROOT)/lib32 -L$(SYSROOT)/usr/lib -pthread -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lz 

The $SYSROOT environment variable was set correctly

To indicate the linker to use the right path you have to add the -Xlinker -rpath-link=/your/sysroot/path directives.

For adding the /lib and /usr/lib path that are in my sysroot, the previous setting of LDFLAGS becomes:

LDFLAGS = -L$(SYSROOT)/lib -L$(SYSROOT)/lib32 -L$(SYSROOT)/usr/lib -Xlinker -rpath-link=$(SYSROOT)/lib -Xlinker -rpath-link=$(SYSROOT)/usr/lib -pthread -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lz 

Now the linker does not complain anymore.

Failed to map segment from shared object

Recently, I was working with an AMD Geode LX800 with Debian 7.2 installed on it. I had a small CF and was running out of space, so I used an USB stick where I copied the binary to test (a Qt5 app) and when executing it as a normal user and as root I was getting the following error:

my_app: error while loading shared libraries: :Failed to map segment from shared object: Operation not permitted...

I play around with file ownership (chown) and access permissions (chmod), but nothing changed.

Later I realized that the problem was that the USB stick was mounted with the noexec flag.
Mounting it without this flag allows the shared library to be properly loaded.

Searching around I found that this issue can happen under other similar scenarios like network mounted drives that contain shared libraries that were mounted with the noexec option or simply the /tmp partition that is normally mounted in memory but without execution permissions.