arm_linux Cross Compiler Development Environment - gcc 4.8.2

1. Environment

linux 16.04

2. Required source files

 binutils-2.23.1.tar.bz2
 glibc-2.18.tar.gz
 gcc-4.8.2.tar.bz2
 gmp-5.1.3.tar.bz2
 mpfr-3.1.2.tar.bz2
 mpc-1.0.1.tar.gz
 linux-2.6.34.14.tar.bz2

3. Setting environmental variables

export SRCDIR=~/workbench/gcc-4.8.2/xtools/src
export BUILDDIR=~/workbench/gcc-4.8.2/xtools/build
export TARGET=arm-linux-gnueabi
export PREFIX=/usr/local/arm/4.8.2
export TARGET_PREFIX=$PREFIX/$TARGET
export PATH=$PATH:$PREFIX/bin

4. Create workspaces

$mkdir -pv ~/workbench/gcc-4.8.2/xtools  
$mkdir $SRCDIR
$cd $SRCDIR

5. Download source code

5.1 binutils

$wget http://ftp.gnu.org/gnu/binutils/binutils-2.23.1.tar.bz2
$tar -pxjf binutils-2.23.1.tar.bz2

5.2 glibc

$wget http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz
$tar -pxzf glibc-2.18.tar.gz
$wget http://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.5.tar.bz2

5.3 gcc

$wget http://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.bz2
$wget http://ftp.gnu.org/gnu/gmp/gmp-5.1.3.tar.bz2
$wget http://ftp.gnu.org/gnu/mpfr/mpfr-3.1.2.tar.bz2
$wget ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.1.tar.gz
$tar -pxjf gcc-4.8.2.tar.bz2
$cd gcc-4.8.2/
$tar -pxjf ../gmp-5.1.3.tar.bz2
$tar -pxjf ../mpfr-3.1.2.tar.bz2
$tar -pxzf ../mpc-1.0.1.tar.gz
$cd $SRCDIR

5.4 kernel

cd $BINUTILS_SRC
$wget https://www.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.34/linux-2.6.34.14.tar.xz

$xz -d linux-2.6.34.14.tar.xz
$tar -xf linux-2.6.34.14.tar

6 build

6.1. Install gmp, mpfr, mpc for the host

6.1.1 build gmp

cd $ BUILDDIR
mkdir gmp
cd $BUILDDIR/gmp
$SRCDIR/gmp-5.1.3/configure --prefix=/usr/local/gmp --build=x86_64-linux-gnu
make
sudo make install
make check

6.1.2 build mpfr

cd $ BUILDDIR
mkdir mpfr
cd $BUILDDIR/mpfr
$SRCDIR/mpfr-3.1.2/configure --build=x86_64-linux-gnu --prefix=/usr/local/mpfr --with-gmp=/usr/local/gmp
make 
sudo make install

6.1.3 build mpc

cd $ BUILDDIR
mkdir mpc
cd $BUILDDIR/mpc
$SRCDIR/mpc-1.0.1/configure --build=x86_64-linux-gnu --prefix=/usr/local/mpc --with-gmp=/usr/local/gmp --with-mpfr=/usr/local/mpfr
make
sudo make install

6.2 Get the kernel header

These header files are required for compiling glibc.
cd $SRCDIR/linux-2.6.34.14
make menuconfig
Quit without modification.
sudo make include/linux/version.h
sudo cp -r ./include/linux/ $TARGET_PREFIX/include
sudo cp -r ./include/asm-generic/ $TARGET_PREFIX/include
sudo cp -r ./arch/arm/include/asm/ $TARGET_PREFIX/include

6.3 build binutils

6.3.1 build binutils

cd $ BUILDDIR
mkdir binutils
cd $BUILDDIR/binutils
$SRCDIR/binutils-2.23.1/configure --prefix=$PREFIX --target=$TARGET
make
sudo make install

When you're done, check the generated tools in $PREFIX.

# cd $PREFIX/bin
# ll
//The following documents are available:
arm-linux-addr2line*
arm-linux-ar*
arm-linux-as*
arm-linux-C++filt*
arm-linux-elfedit*
arm-linux-gprof*
arm-linux-ld*
arm-linux-ld.bfd*
arm-linux-nm*
arm-linux-objcopy*
arm-linux-objdump*
arm-linux-ranlib*
arm-linux-readelf*
arm-linux-size*
arm-linux-strings*
arm-linux-strip*

The functions of these generated files are as follows:
arm-linux-addr2line: Convert the address you are looking for to a file and line number, which uses debug information
arm-linux-ar: Generate, modify, and open an archive file
arm-linux-as: GNU assembler
arm-linux-c++filt: There is an overloaded function in C++ and Java. The overloaded function used will be compiled and transformed into assembly label. c++filt is to realize this reverse transformation, and get the function name according to label.
arm-linux-elfedit: Usage is temporarily unknown
arm-linux-gprof: GNU assembler precompiler
arm-linux-ld: GNU connector
arm-linux-ld.bfd: Usage is temporarily unknown
arm-linux-nm: lists the symbols and addresses of the target file
arm-linux-objcopy: converting a target file in one format into another
arm-linux-objdump: Display information about the target file
arm-linux-ranlib: Generate an index for an archive file and store the index in the archive file
arm-linux-readelf: Display information about the target file in elf format
arm-linux-size: Displays the size of each section of the target file and the size of the target file
arm-linux-strings: Print out a string that can be printed in the target file, with a default length of 4
arm-linux-strip: stripping all symbolic information from the target file

6.3.2 Common errors

(1) bfd error
Description:
bfd.h:529:65: error: right-hand operand of comma expression has no effect [-Werror=unused-value]
#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
^
opncls.c:261:5: note: in expansion of macro 'bfd_set_cacheable'
bfd_set_cacheable (nbfd, TRUE);
^
cc1: all warnings being treated as errors
Makefile:1312: recipe for target 'opncls.lo' failed
make[6]: *** [opncls.lo] Error 1
make[6]: Leaving directory '/srv/jenkins-slave/workspace/sid-goto-cc-sdcc/sdcc-3.4.0+dfsg/support/sdbinutils/bfd'
Makefile:1354: recipe for target 'all-recursive' failed
make[5]: *** [all-recursive] Error 1

Reason:
Source version is relatively old, compiling with gcc version 4.1 is not a problem, and the modified gcc version will report errors in the writing of this less standardized version.
Solution:
cd $BUILDDIR/bfd
vim Makefile
Find the - Werror option inside and delete it.
Because binutils, gas, ld modules have this problem, as the above solution, enter these modules separately, delete the - Werror parameter in Makefile.

6.4 Build initial GCC (without glibc support)

cd $SRCDIR
tar -xjvf gcc-4.8.2.tar.bz2

Delete the original mpfr, mpc, gmp and re-decompress:

rm -rf mpfr-3.1.2 mpc-1.0.1 gmp-5.1.3
tar -xjvf gmp-5.1.3.tar.bz2
mv gmp-5.1.3 gmp
mv ./gmp ./gcc-4.8.2

tar -xjvf mpfr-3.1.2.tar.bz2
mv mpfr-3.1.2 mpfr
mv ./mpfr ./gcc-4.8.2

tar -xzvf mpc-1.0.1.tar.gz
mv mpc-1.0.1 mpc
mv ./mpc ./gcc-4.8.2

cd $BUILDDIR
mkdir gcc-4.8.2
cd gcc-4.8.2
$SRCDIR/gcc-4.8.2/configure --prefix=$PREFIX --target=$TARGET --without-headers --enable-languages=c --disable-threads --with-newlib --disable-shared --disable-libmudflap --disable-libssp --disable-decimal-float
make all-gcc
sudo make install-gcc
make all-target-libgcc
sudo make install-target-libgcc

After that, $PREFIX/bin has several more files:
arm-linux-cpp*
arm-linux-gcc*
arm-linux-gcc-4.8.2*
arm-linux-gcov*
The functions of these generated files are as follows:
arm-linux-cpp: C precompiler for GNU
arm-linux-gcc:GNU C Language Compiler
arm-linux-gcc-4.8.2: GNU's c language compiler is actually the same as arm-linux-gcc
arm-linux-gcov: gcc, an auxiliary testing tool for analyzing and optimizing programs

6.5 build glibc

Glibc is the runtime for cross-compiling environments.

cd $SRCDIR
tar -pxjf glibc-2.18.tar.bz2
tar -pxjf glibc-linuxthreads-2.5.tar.bz2 --directory=./glibc-2.18/
cd $BUILDDIR
mkdir glibc
cd glibc
export CC=$TARGET-gcc
export CFLAGS="-g -O2 -march=armv7-a"

(Note: TI 3354 board is armv7, AM335x microprocessor is based on ARM Cortex-A8 processor, using armv7-a architecture. Samsung 2440 board is armv4t
(If the architecture is not selected correctly, there will be an error message: configure: 2763: arm-linux-gnueabi-g C c-c-g-O 2-march = armv7l conftest.c > & 5
arm-linux-gnueabi-gcc: error: unrecognized argument in option '-march=armv7l'
arm-linux-gnueabi-gcc: note: valid arguments to '-march=' are: armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5e armv5t armv5te armv6 armv6-m armv6j armv6k armv6s-m armv6t2 armv6z armv6zk armv7 armv7-a armv7-m armv7-r armv7e-m armv8-a iwmmxt iwmmxt2 native)

sudo ln -s /usr/local/arm/4.8.2/lib/gcc/arm-linux-gnueabi/4.8.2/libgcc.a /usr/local/arm/4.8.2/lib/gcc/arm-linux-gnueabi/4.8.2/libgcc_eh.a
Create config.cache configuration file:

vim config.cache,Write in:
libc_cv_forced_unwind=yes
libc_cv_c_cleanup=yes
libc_cv_arm_tls=yes
$SRCDIR/glibc-2.18/configure --host=$TARGET --target=$TARGET --prefix=$TARGET_PREFIX --enable-add-ons --disable-profile --cache-file=config.cache --with-binutils=$PREFIX/bin --with-headers=$TARGET_PREFIX/include
make all
sudo make install

Common problem:
(1) make too old
Reason: make version is wrong, 4.1 is too high. Change to 3.82.
Download make-3.82
wget http://ftp.gnu.org/gnu/make/make-3.82.tar.bz2
tar -pxjf make-3.82.tar.bz2
./configure
make
Then add the path of make file to PATH
Export PATH = < make path >: $PATH
(2) Error reporting: checking sysdep dirs... configure: error: The arm is not supported
This problem is the reason for downloading glibc-ports. Copy the extracted glibc ports directly into the glibc directory and rename them ports.

6.6 build full gcc

Note: When compiling gcc, we need to generate the cross compiler itself. We don't want to compile the cross compiler with the cross compiler. Therefore, unset cross-compiled variables are needed to reply to GCC compilation.
unset CC
unset CFLAGS
cd $BUILDDIR/gcc-4.8.2
Clear the last compiled file:
rm -rf *
SRCDIR/gcc−4.8.2/configure−−prefix=SRCDIR/gcc-4.8.2/configure --prefix=SRCDIR/gcc−4.8.2/configure−−prefix=PREFIX --target=$TARGET --enable-shared --enable-languages=c,c++
make
sudo make install

After that, $PREFIX/bin has several more files:
arm-linux-c++*
arm-linux-g++*
The functions of these generated files are as follows:
arm-linux-g+: GNU's c++ compiler
arm-linux-c +: equivalent to arm-linux-g +

6.7 build gdb for arm

cd $SRCDIR
tar -pxjf gdb-7.6.1.tar.bz2
cd $BUILDDIR
mkdir gdb
cd gdb
$SRCDIR/gdb-7.6.1/configure --prefix=$PREFIX --target=$TARGET
make
sudo make install

6.8 Create links to cross-compiler executables

cd $PREFIX/bin
sudo ln -s arm-linux-gnueabi-addr2line arm-linux-addr2line
sudo ln -s arm-linux-gnueabi-ar arm-linux-ar
sudo ln -s arm-linux-gnueabi-as arm-linux-as
sudo ln -s arm-linux-gnueabi-c++ arm-linux-c++
sudo ln -s arm-linux-gnueabi-c++filt arm-linux-c++filt
sudo ln -s arm-linux-gnueabi-cpp arm-linux-cpp
sudo ln -s arm-linux-gnueabi-elfedit arm-linux-elfedit
sudo ln -s arm-linux-gnueabi-g++ arm-linux-g++
sudo ln -s arm-linux-gnueabi-gcc arm-linux-gcc
sudo ln -s arm-linux-gnueabi-gcc-4.6.3 arm-linux-gcc-4.6.3
sudo ln -s arm-linux-gnueabi-gcov arm-linux-gcov
sudo ln -s arm-linux-gnueabi-gdb arm-linux-gdb
sudo ln -s arm-linux-gnueabi-gdbtui arm-linux-gdbtui
sudo ln -s arm-linux-gnueabi-gprof arm-linux-gprof
sudo ln -s arm-linux-gnueabi-ld arm-linux-ld
sudo ln -s arm-linux-gnueabi-ld.bfd arm-linux-ld.bfd
sudo ln -s arm-linux-gnueabi-nm arm-linux-nm
sudo ln -s arm-linux-gnueabi-objcopy arm-linux-objcopy
sudo ln -s arm-linux-gnueabi-objdump arm-linux-objdump
sudo ln -s arm-linux-gnueabi-ranlib arm-linux-ranlib
sudo ln -s arm-linux-gnueabi-readelf arm-linux-readelf
sudo ln -s arm-linux-gnueabi-run arm-linux-run
sudo ln -s arm-linux-gnueabi-size arm-linux-size
sudo ln -s arm-linux-gnueabi-strings arm-linux-strings
sudo ln -s arm-linux-gnueabi-strip arm-linux-strip

6.9 Setting environmental variables

cd ~
vim .profile

```export PATH=$PATH:/usr/local/arm/4.8.2/bin

7. Inspection

Create a new source file: hello.c

#include <stdio.h>
int main(int argc, char* argv[]) {
    printf("hello\n");
    return 0;
}
arm-linux-gcc -static hello.c -o hello
file hello
//Output:
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, not stripped

It indicates that the preliminary test is successful.

Tags: Linux sudo glibc ftp

Posted on Mon, 12 Aug 2019 02:56:35 -0700 by Lillefix