I am trying to cross compile a hello world C program on a CentOS 7 64-bit machine to the Raspberry Pi 2B 32-bit target machine.
I downloaded the buster cross compiler cross-gcc-8.3.0-pi_2-3.tar.gz
My hello world C file is the standard hello world program that we all use.
When I inch up on my compile first just trying to compile
arm-linux-gnueabihf-gcc -o helloworld.exe helloworld.c
gives me:
/home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by /home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld)
collect2: error: ld returned 1 exit status
The libc version is different on my CentOS machine from the target. The libc.so.6
file is in the cross compile path, so when I use the --sysroot
option, I get over the libc problem, but get an inability to find the stdio.h
file.
arm-linux-gnueabihf-gcc -o helloworld.exe helloworld.c --sysroot=/home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf/libc/lib
helloworld.c:1:10: fatal error: stdio.h: No such file or directory
#include <stdio.h>
^~~~~~~~~
compilation terminated.
The stdio.h file is in the cross compile path, but I can't determine way to add that path to the gcc
command without destroying my link to the libc world. I tried -I, -isystem, .... but when I do that, I get the original GLIBC error
I am not inventing the wheel here, so there must be something I am missing. I am just getting into this cross compiling thing, and need help to build up my knowledge. I read may sites, but haven't quite found the answer.
Thanks for your help.
Not a total solution, but some explanation ...
The TL;DR: Unfortunately, we don't have all the files we need.
I downloaded and extracted the tar file from the link you provided.
It creates a subdirectory: cross-pi-gcc-8.3.0-1
Under that directory, we have subdirectories. Of note [some] are:
arm-linux-gnueabihf
bin
lib
To use a given cross-development utility (e.g. ld
but similar for gcc
, ar
, etc.) they are located:
./bin/arm-linux-gnueabihf-ld
./arm-linux-gnueabihf/bin/ld
These files are identical. Also, [again] they are x86_64
binaries that cross build for arm.
So, to be able to use the cross build there are two methods:
PATH
variable: export PATH=/home/redacted/cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf
. Then, if we type the command ld <something>
, we are not using the native x86_64 version but the x86_64 to arm cross version.ld
, we can use arm-linux-gnueabihf-ld
. Here, in our Makefile
, we'd do something like: LD = arm-linux-gnueabihf-ld
at the top. This works if we install the cross compiler so that the package bin
is extracted into a standard bin
directory (such as /usr/local/bin
export PATH=/home/redacted/cross-pi-gcc-8.3.0-1/bin
and setting LD
as above.Either way, we can now cross-build for arm ... Sort of ...
Under the lib
directory, we have libcc1*
files. These are build for x86_64.
The problem is that we do not have an aarch64/arm
version of a library. So, if we do:
arm-linux-gnueabihf-gcc -o hello hello.c
There is no aarch64
(arm) version of (e.g.) libc
.
In other words, the package you downloaded has [just] the cross-compiler but no target system libraries.
In other words, we'd need to add --sysroot=/path_to_sysroot
to the gcc
command.
But, we do not have the sysroot
files.
With --sysroot
, we'd expect to find:
/path_to_sysroot/bin/ls
/path_to_sysroot/lib/libc*
And, the ls
would be the aarch64/arm
binary and the libc
would have the library code compiled for aarch64/arm
So, to remedy this, we have to find and download suitable packages that do have pre-built aarch64/arm
binaries and have --sysroot=
point to the top directory for these.
Just to recap ... The sysroot
directory should have the exact file hierarchy that the target system (e.g. the RPi) will have starting from its root /
directory.
Again, what you have is just the cross-compiler. But, no target libraries or binaries (e.g. ls
, vim
, etc.)
You may want to consider a more full featured, one stop approach, such as linaro
: