1

I'm just doing my first steps with Buildroot and Raspberry Pi (running Raspbian). But somehow I seem to do something wrong with the cross compilation. The application is a most simple Hello World program written in C. This is what I did:

  1. Downloaded and installed buildroot
  2. make raspberrypi2_defconfig
  3. make toolchain

Then I wrote the tiny application and the following Makefile:

CROSS_BIN := /home/me/raspi/buildroot-2016.05/output/host/usr/bin
SYSROOT := /home/me/raspi/buildroot-2016.05/output/host/usr/arm-buildroot-linux-uclibcgnueabihf/sysroot
PATH := $(CROSS_BIN):$(PATH)

CC := arm-linux-gcc
CFLAGS := --sysroot=$(SYSROOT)

app: app.c
   $(CC) $(CFLAGS) -o $@ $<

Compiled the app and copied it to the Raspberry. When I tried to run it, RPI complains that it can't find the file (though it's there and executable for sure). The binary type seems ok to me and should fit to the CPU:

pi@raspberrypi:~ $ ./app
-bash: ./app: No such file or directory

pi@raspberrypi:~ $ ls -l app
-rwxr-xr-x 1 pi pi 4916 Jul 10 11:07 app

pi@raspberrypi:~ $ file app
app: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, not stripped

pi@raspberrypi:~ $ lscpu
Architecture:          armv7l
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    1
Core(s) per socket:    4
Socket(s):             1
Model name:            ARMv7 Processor rev 5 (v7l)
CPU max MHz:           900.0000
CPU min MHz:           600.0000

Can somebody tell me what I'm doing wrong? If I compile the app natively and run it on the development host, it runs without a problem.

Georg P.
  • 2,785
  • 2
  • 27
  • 53
  • 1
    Try `ldd ./app` and `readelf -l ./app |grep interpreter` and check that required program interpreter is here on your Ri OS. – osgx Jul 10 '16 at 12:54
  • Very useful commands, thanks for the hint. As Ishay guessed, uClibc is missing: `[Requesting program interpreter: /lib/ld-uClibc.so.0]` – Georg P. Jul 10 '16 at 13:10
  • Thank you @sawdust. That was the solution, it works fine with `glibc`. After all the other hints I actually figured that out myself - just didn't post yet. – Georg P. Jul 11 '16 at 20:52

2 Answers2

4

My money is on /lib/ld-uClibc.so.0 missing from your Rasperry pi. Am I right?

Okay, this library is your dynamic loader, it is responsible for loading your dynamic libraries at runtime. It will load the required shared libraries into the process address space and set the appropriate permissions on the memory (read only, read write and executable).

Your cross-compiler requires a loader that does not exist, probably due to mismatch between the installed image on the RPi and the cross-compilation environment (your sysroot).

There are several ways to fix it, let's start by examining a binary that works, try file /bin/ls and post the dynamic loader here.

For example:

$ file /bin/ls
/bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=5e052e8de057d379ab51d4af510ad9318fe77b46, stripped
Ishay Peled
  • 2,783
  • 1
  • 23
  • 37
  • 100% right, thanks a lot. Now, what's the "best practice" on how to install this library? I found it compiled in output/build/uclibc-1.0.14/lib and I could just copy all files that seem needed manually to the board. But I guess there is a better way? Does Buildroot offer something? – Georg P. Jul 10 '16 at 13:07
  • Don't copy anything, the problem is the wrong loader, I'll guide you through it – Ishay Peled Jul 10 '16 at 13:46
  • Thanks for your effort. As written in another comment, I got it to work by changing `uClibc` to `glibc`. – Georg P. Jul 11 '16 at 20:55
1

When I tried to run it, RPI complains that it can't find the file (though it's there and executable for sure).

The shell is complaining that it cannot find a file in order to execute your program, not that it cannot find your file.
If it's installed use the strace command to determine what file cannot be found.
Most likely you have a dynamic library issue, e.g. you built with a uClibc toolchain, but your rootfilesystem has glibc.

Two common solutions:

(A) build your program with static linking (so that it no longer depends on the installed libraries of the target system).

 $(CC) $(CFLAGS) -o -static $@ $< 

(B) rebuild the Buildroot toolchain to match the library that is already installed on your RPi. i.e. instead of a uClibc toolchain, build a glibc toolchain of matching version number.

sawdust
  • 16,103
  • 3
  • 40
  • 50