Detailed explanation of cross compilation (making cross compilation chain from zero)

Keywords: shell

Compiling environment

Host hardware environment:

    $ uname -a
    Linux PC 4.4.0-42-generic #62-Ubuntu SMP Fri Oct 7 23:11:45 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
  
  • 1
  • 2

Host software environment:

    $ cat /etc/issue
    Ubuntu 16.04.1 LTS
  
  • 1
  • 2

Tools to install:

    sudo apt-get install libncurses5-dev
    sudo apt-get install gperf
    sudo apt-get install bison
    sudo apt-get install flex
    sudo apt-get install texinfo
    sudo apt-get install help2man
    sudo apt-get install gawk
    sudo apt-get install libtool
    sudo apt-get install libtool-bin
    sudo apt-get install automake
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Libncurses5 dev: developer's libraries for ncurses (required when executing make menuconfig)

gperf: a perfect hash function generator. For example, see this post:
gperf usage instance

Bison: a parser generator. Bison transforms a description of the "look forward left to right rightmost" (LALR) context free grammar into a C or C + + program that can analyze the grammar. It can also generate a general left to right (GLR) parser for ambiguous grammars

flex: lexical analyzer

Textinfo: is another format of help information provided by the Linux system. Compared with man, textinfo has better interactive function. It supports link jump function, and usually uses info and pinfo commands to read textinfo documents

help2man: a tool that can automatically generate man manuals for our programs

gawk: a text tool for finding replacements under linux

libtool / libtool-bin: Generic library support script

automake: Tool for generating GNU Standards-compliant Makefiles

remarks:

  • The tools that need to be installed in different environments are not exactly the same. When an error occurs, you can check it according to the error prompt
  • The descriptions of various tools can be queried using the apt cache search XXX command

Configure global variables

    export PRJROOT=/home/user/tool_prj1         # Change to the directory where your project is located
    export TARGET=arm-none-linux-gnueabi
    export PREFIX=${PRJROOT}/tool-chain
    export TARGET_PREFIX=${PREFIX}/${TARGET}
    export PATH=${PREFIX}/bin:${PATH}
    export ARCH=arm
    export BINUTILS_VERSION=binutils-2.27
    export GCC_VERSION=gcc-5.4.0
    export GLIBC_VERSION=glibc-2.23
    export KERNEL_VERSION=linux-4.4.25
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

directory structure

    $ tree -L 2
    tool_prj1
    ├── build                       # Compilation directory of src
    ├── script                      # Script Tools Directory
    │   ├── toolchain_build.sh        # The automatic compilation script written by myself and subsequent commands are integrated into this script
    │   └── toolchain_config.lst      # Used to configure global variables
    ├── setup                       # Save the downloaded source package
    │   ├── binutils-2.27.tar.bz2
    │   ├── gcc-5.4.0.tar.bz2
    │   ├── glibc-2.23.tar.bz2
    │   └── linux-4.4.25.tar.xz
    ├── src                         # Unzipped source file
    └── tool-chain                  # Installation position of tool chain
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Source package download

    cd setup
    wget http://ftp.gnu.org/gnu/binutils/$BINUTILS_VERSION.tar.bz2
    wget http://ftp.gnu.org/gnu/gcc/$GCC_VERSION/$GCC_VERSION.tar.bz2
    wget ftp://ftp.gnu.org/gnu/glibc/$GLIBC_VERSION.tar.bz2
    wget https://www.kernel.org/pub/linux/kernel/v4.x/$KERNEL_VERSION.tar.xz
  
  • 1
  • 2
  • 3
  • 4
  • 5

binutils

Compilation process

    cd src/
    tar -jxf ../setup/$BINUTILS_VERSION.tar.bz2
    mkdir ../build/$BINUTILS_VERSION
    cd ../build/$BINUTILS_VERSION
    sh ../../src/$BINUTILS_VERSION/configure --target=$TARGET --prefix=$PREFIX --disable-nls --enable-shared
    make
    make install
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Detailed explanation of options

–target=${TARGET}

The compiled program can handle the platform

Note: build/host/target is a set of related parameters, which are described as follows:

  • build the machine currently being compiled
  • host compiled program can run on the platform
  • target is the platform that the compiled program can handle

For example, we need to compile a gcc that can handle mips programs for the arm development board on the i386 machine. The relevant parameters are as follows:

  • build=i386-linux
  • host=arm-linux
  • target=mips-linux

–prefix=${RESULT_DIR}

Tell the configuration script to install the compiled things in result when running make install_ Dir directory

–disable-nls

nls here means Native Language Support

–enable-shared

Compile a shared link library

Check compilation results

    $ ls ../../tool-chain/bin/
    arm-none-linux-gnueabi-addr2line  arm-none-linux-gnueabi-c++filt  arm-none-linux-gnueabi-ld      arm-none-linux-gnueabi-objcopy  arm-none-linux-gnueabi-readelf  arm-none-linux-gnueabi-strip
    arm-none-linux-gnueabi-ar         arm-none-linux-gnueabi-elfedit  arm-none-linux-gnueabi-ld.bfd  arm-none-linux-gnueabi-objdump  arm-none-linux-gnueabi-size
    arm-none-linux-gnueabi-as         arm-none-linux-gnueabi-gprof    arm-none-linux-gnueabi-nm      arm-none-linux-gnueabi-ranlib   arm-none-linux-gnueabi-strings
  
  • 1
  • 2
  • 3
  • 4

Making Linux kernel header files

Compilation process

    cd src
    tar -xf ../setup/$KERNEL_VERSION.tar.xz
    cd $KERNEL_VERSION
    make ARCH=$ARCH CROSS_COMPILE=$TARGET- INSTALL_HDR_PATH=$PREFIX/$TARGET headers_install
  
  • 1
  • 2
  • 3
  • 4

This step is to export the kernel header file, which is required when compiling GLIBC later

Detailed explanation of options

ARCH

The architecture of the target processor is arm processor

CROSS_COMPILE

The name of the cross tool chain used by the compiler

INSTALL_HDR_PATH

Where the header file needs to be installed

headers_install

The execution action of make is to install the header file

Inspection results

    $ ls $PREFIX/$TARGET
    bin  include  lib
  
  • 1
  • 2

You can see the include folder

Create and initialize GCC compiler

Function introduction

This step is mainly to establish the arm linux gcc tool. Note that this gcc is not supported by the glibc library, so it can only be used to compile the kernel, BootLoader and other programs that do not need the support of the C library. This compiler is also used to create the C library later. If you only want to compile the kernel and BootLoader, you can finish installing this

Compilation process

    cd src
    tar -jxf ../setup/$GCC_VERSION.tar.bz2
    cd $GCC_VERSION
    ./contrib/download_prerequisites    # Download mpfr/gmp/mpc/isl
    mkdir ../../build/$GCC_VERSION
    cd ../../build/$GCC_VERSION
    sh ../../src/$GCC_VERSION/configure --target=$TARGET --prefix=$PREFIX --disable-shared --disable-threads --without-headers --disable-libmudflap --enable-languages=c,c++ --disable-nls
    make all-gcc
    make install-gcc
    make all-target-libgcc
    make install-target-libgcc
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Note: GCC requires four libraries mpfr/gmp/mpc/isl. The current GCC can use. / contrib / download_ The prerequisites script can be downloaded directly

  • mpfr
  • gmp
  • mpc
  • isl

Detailed explanation of options

–disable-shared

Do not use shared libraries

–disable-threads

Do not use threading function

–without-headers

Do not use the header file of the target object

–disable-libmudflap

It's not clear what this configuration means

–enable-languages=c,c++

Support C/C + + language

For other detailed parameter descriptions, please refer to the document: gcc/doc/gccinstall.info

Inspection results

    $ ls tool-chain/bin/arm-none-linux-gnueabi-gcc*
    tool-chain/bin/arm-none-linux-gnueabi-gcc        tool-chain/bin/arm-none-linux-gnueabi-gcc-ar  tool-chain/bin/arm-none-linux-gnueabi-gcc-ranlib
    tool-chain/bin/arm-none-linux-gnueabi-gcc-5.4.0  tool-chain/bin/arm-none-linux-gnueabi-gcc-nm 
  
  • 1
  • 2
  • 3

You can see that GCC already exists

GLibc

Compilation process

    cd src
    tar -jxf ../setup/$GLIBC_VERSION.tar.bz2
    mkdir ../build/$GLIBC_VERSION
    cd ../build/$GLIBC_VERSION
    sh ../../src/$GLIBC_VERSION/configure --host=$TARGET --prefix=$PREFIX/$TARGET --with-tls --disable-profile --enable-add-ons --with-headers=$PREFIX/$TARGET/include libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes libc_cv_arm_tls=yes --disable-nls
    make CC=$TARGET-gcc AR=$TARGET-ar RANLIB=$TARGET-ranlib
    make install
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Detailed explanation of options

–with-headers=@var{directory}

Look for kernel header files in @var{directory}

–with-tls

This tells Glibc to use Thread Local Storage

–disable-profile

Don't build libraries with profiling information

–enable-add-ons

Specify add-on packages to include in the build

libc_cv_forced_unwind=yes

libc_cv_c_cleanup=yes

libc_cv_arm_tls=yes

The configuration meaning of these three parameters is unclear

For other detailed parameter descriptions, please refer to the document: manual/install.texi

Inspection results

    $ ls tool-chain/arm-none-linux-gnueabi/lib
    audit          libanl-2.23.so           libc.a            libc.so        libm.a          libnss_compat-2.23.so  libnss_files-2.23.so    libnss_nisplus.so.2     libresolv-2.23.so  libSegFault.so       Scrt1.o
    crt1.o         libanl.a                 libcidn-2.23.so   libc.so.6      libmcheck.a     libnss_compat.so       libnss_files.so         libnss_nis.so           libresolv.a        libthread_db-1.0.so
    crti.o         libanl.so                libcidn.so        libdl-2.23.so  libmemusage.so  libnss_compat.so.2     libnss_files.so.2       libnss_nis.so.2         libresolv.so       libthread_db.so
    crtn.o         libanl.so.1              libcidn.so.1      libdl.a        libm.so         libnss_db-2.23.so      libnss_hesiod-2.23.so   libpcprofile.so         libresolv.so.2     libthread_db.so.1
    gconv          libBrokenLocale-2.23.so  libc_nonshared.a  libdl.so       libm.so.6       libnss_db.so           libnss_hesiod.so        libpthread-2.23.so      librpcsvc.a        libutil-2.23.so
    gcrt1.o        libBrokenLocale.a        libcrypt-2.23.so  libdl.so.2     libnsl-2.23.so  libnss_db.so.2         libnss_hesiod.so.2      libpthread.a            librt-2.23.so      libutil.a
    ld-2.23.so     libBrokenLocale.so       libcrypt.a        libg.a         libnsl.a        libnss_dns-2.23.so     libnss_nis-2.23.so      libpthread_nonshared.a  librt.a            libutil.so
    ld-linux.so.3  libBrokenLocale.so.1     libcrypt.so       libieee.a      libnsl.so       libnss_dns.so          libnss_nisplus-2.23.so  libpthread.so           librt.so           libutil.so.1
    ldscripts      libc-2.23.so             libcrypt.so.1     libm-2.23.so   libnsl.so.1     libnss_dns.so.2        libnss_nisplus.so       libpthread.so.0         librt.so.1         Mcrt1.o                        
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Build a complete GCC compiler

Compilation process

    cd build/$GCC_VERSION
    rm -rf *                        # Delete previous configuration
    sh ../../src/$GCC_VERSION/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c,c++ --enable-shared --disable-nls
    make
    make install
  
  • 1
  • 2
  • 3
  • 4
  • 5

Verify the complete compilation chain

Dynamic compilation

    $ arm-none-linux-gnueabi-gcc -o hello hello.c
    $ arm-none-linux-gnueabi-strip hello
    $ file hello
    hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.32, stripped
  
  • 1
  • 2
  • 3
  • 4

Static compilation

    $ arm-none-linux-gnueabi-gcc -o hello hello.c -static
    $ arm-none-linux-gnueabi-strip hello
    $ file hello
    hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, stripped
  
  • 1
  • 2
  • 3
  • 4
`Insert the code slice here`

Posted by yandoo on Wed, 01 Dec 2021 03:41:52 -0800