Unfortunately after few tries of cross compiling eglibc using different source
for instructions I always end with hard to solve issues. Luckily, in the sources
of eglibc I noticed instructions for cross-compiling written long time ago by
Jim Blandy(I know i should start here). Lot of thanks to him for it. Below
I describe my experience which I gained during eglibc cross compilation for
arm-unknown-linux-gnueabi
and procedure that I used. Commands below contain
some constants that I used in previous works. See this post. Eglibc library
and the compiler itself is built with many various parameters this post is not
the place to explain their meaning, please RTFM.
Checkout eglibc from svn (as always I try to use a latest sources possible).
Version used r17815:
1
|
svn co http://www.eglibc.org/svn/trunk eglibc
|
Link working ports to GNU/Linux on some machine architectures. They are not
maintained in the official glibc source tree so we need to add it in this way:
1
|
ln -s ../ports eglibc/libc/ports/
|
Create eglibc-headers directory:
1
2
|
mkdir eglib-headers
cd eglib-headers
|
Configure eglibc and preliminary objects:
1
2
3
4
5
6
7
8
|
BUILD_CC=gcc
CC=arm-unknown-linux-gnueabi-gcc
CXX=arm-unknown-linux-gnueabi-cpp
AR=arm-unknown-linux-gnueabi-ar
RANLIB=arm-unknown-linux-gnueabi-ranlib
../eglibc/libc/configure --prefix=/usr --with-headers=$TARGET/usr/include
--build=x86_64-pc-linux-gnu --host=arm-unknown-linux-gnueabi --disable-profile
--without-gd --without-cvs --enable-add-ons
|
Install eglibc headers:
1
|
make install-headers install_root=$TARGET install-bootstrap-headers=yes
|
We need few object file to link shared libraries, which will be built and
installed by hand:
1
2
|
mkdir -p $TARGET/usr/lib
make csu/subdir_lib cp csu/crt1.o csu/crti.o csu/crtn.o $TARGET/usr/lib
|
To produce libgcc_s.so we need libc.so, but only need its dummy version because
we’ll never use it. It doesn’t matter what we will point as a libc.so we use
/dev/null as C file.
1
2
|
arm-unknown-linux-gnueabi-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o
$TARGET/usr/lib/libc.so
|
Get latest gcc sources using git repository mirror. Latest commit while writing
this post was 5b9a8c3:
1
2
|
cd ..
git clone git://repo.or.cz/official-gcc.git
|
Now, we can build gcc which can compile eglibc.
1
2
3
4
5
6
7
8
9
10
11
12
|
mkdir eglibc-gcc
cd eglibc-gcc
../official-gcc/configure --target=arm-unknown-linux-gnueabi
--prefix=$TARGET/arm-x-tools --with-sysroot=$TARGET --disable-libssp
--disable-libgomp --disable-libmudflap --enable-languages=c
--with-gmp=$TARGET/arm-x-tools --with-mpfr=$TARGET/arm-x-tools
--with-mpc=$TARGET/arm-x-tools --disable-libquadmath --build=$MACHTYPE
--host=$MACHTYPE --with-local-prefix=$TARGET/arm-x-tools --disable-multilib
--with-float=soft --with-pkgversion="pietrushnic" --enable-threads=no
--enable-target-optspace --disable-nls --enable-c99 --enable-long-long
make -j4
make install
|
Configure and compile final version of eglibc.
1
2
3
4
5
6
7
8
9
10
|
mkdir eglibc-final
cd eglibc-final/
BUILD_CC=gcc CC=arm-unknown-linux-gnueabi-gcc CXX=arm-unknown-linux-gnueabi-cpp
AR=arm-unknown-linux-gnueabi-ar
RANLIB=arm-unknown-linux-gnueabi-ranlib
../eglibc/libc/configure --prefix=/usr --with-headers=$TARGET/usr/include
--build=x86_64-pc-linux-gnu --host=arm-unknown-linux-gnueabi --disable-profile
--without-gd --without-cvs --enable-add-ons
make
make install install_root=$TARGET
|
Install libelf library
1
2
3
4
5
6
|
wget http://www.mr511.de/software/libelf-0.8.13.tar.gz
tar zxvf libelf-0.8.13.tar.gz
cd libelf-0.8.13/
./configure --prefix=$TARGET/arm-x-tools --disable-shared --enable-static
make
make install
|
Prepare final version of gcc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
cd ..
mkdir final-gcc
cd final-gcc
../official-gcc/configure --target=arm-unknown-linux-gnueabi
--prefix=$TARGET/arm-x-tools --with-sysroot=$TARGET --disable-libssp
--disable-libgomp --disable-libmudflap --enable-languages=c,c++ --with-gmp=$TARGET/arm-x-tools
--with-mpfr=$TARGET/arm-x-tools --with-mpc=$TARGET/arm-x-tools --disable-libquadmath
--build=$MACHTYPE --host=$MACHTYPE --with-local-prefix=$TARGET/arm-x-tools --disable-multilib
--with-float=soft --with-pkgversion="pietrushnic" --enable-threads=posix
--enable-target-optspace --disable-nls --enable-c99 --enable-long-long
--enable-__cxa_atexit --enable-symvers=gnu --with-libelf=$TARGET/arm-x-tools
--enable-lto
make
make install
|
Few libraries should be copied manually
1
2
|
cp -d $TARGET/arm-x-tools/arm-unknown-linux-gnueabi/lib/libgcc_s.so* $TARGET/lib
cp -d $TARGET/arm-x-tools/arm-unknown-linux-gnueabi/lib/libstdc++.so* $TARGET/lib
|
Compile and install chrpath - this is useful tool to remove the rpath or runpath
setting from binary.
1
2
3
4
5
6
7
|
cd ..
sudo apt-get install libc6-i386 gcc-multilib
apt-get source chrpath
cd chrpath-0.13/ CFLAGS=-m32
./configure --prefix=$TARGET/arm-x-tools --program-prefix=arm-unknown-linux-gnueabi-
make
make install
|
Strip debug symbols
1
2
3
4
5
|
strip --strip-debug $TARGET/arm-x-tools/lib/*
$TARGET/arm-x-tools/arm-unknown-linux-gnueabi/lib/* $TARGET/arm-x-tools/libexec/*
strip --strip-unneeded $TARGET/arm-x-tools/bin/*
$TARGET/arm-x-tools/arm-unknown-linux-gnueabi/bin/*
arm-unknown-linux-gnueabi-strip --strip-debug $TARGET/lib/* $TARGET/usr/lib/*
|
At the end simple test to find out if basic functionality works:
1
2
3
4
5
6
7
8
9
|
cat > hello.c << EOF
> #include <stdio.h>
> int
> main (int argc, char **argv)
> {
> puts ("Hello, world!");
> return 0;
> }
> EOF
|
Try to cross compile C file:
1
|
$TARGET/arm-x-tools/bin/arm-unknown-linux-gnueabi-gcc -Wall hello.c -o hello
|
1
2
3
4
5
6
7
8
|
cat > c++-hello.cc <<EOF
> #include <iostream>
> int
> main (int argc, char **argv)
> {
> std::cout return 0;
> }
> EOF
|
Try to cross compile C++ file:
1
|
$TARGET/arm-x-tools/bin/arm-unknown-linux-gnueabi-g++ -Wall c++-hello.cc -o c++-hello
|
Displays the information contained in the ELF header and in the file’s segment
headers:
1
|
$TARGET/arm-x-tools/bin/arm-unknown-linux-gnueabi-readelf -hl hello $TARGET/arm-x-tools/bin/arm-unknown-linux-gnueabi-readelf -hl c++-hello
|
Result should look like that:
1
2
|
ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: ARM (...) Flags: 0x5000002, has entry point, Version5 EABI (...) Program Headers: (...) INTERP 0x000134 0x00008134 0x00008134 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.3] LOAD 0x000000 0x00008000 0x00008000 0x004b8 0x004b8 R E 0x8000 (...) \``\`
|
1
|
$TARGET/arm-x-tools/bin/arm-unknown-linux-gnueabi-readelf -d $TARGET/lib/libgcc_s.so.1
|
Result should look like that:
1
2
3
4
5
|
(...)
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000e (SONAME) Library soname: [libgcc_s.so.1]
0x0000000c (INIT) 0xcc2c (...)
|
I hope you find above manual useful. If you need more detailed descriptions it
can be found here.
Piotr Król
Founder of 3mdeb, a passionate advocate for open-source firmware solutions, driven by a belief in transparency, innovation, and trustworthiness. Every day is a new opportunity to embody the company's vision, emphasizing user liberty, simplicity, and privacy. Beyond business, a casual chess and bridge player, finding peace in nature and nourishment in theology, philosophy, and psychology. A person striving to foster a healthy community, grounded in collaboration and shared growth, while nurturing a lifelong curiosity and a desire to deeply understand the world.