\documentclass[aspectratio=169,obeyspaces,spaces,hyphens,dvipsnames]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{minted}
\usepackage{hyperref}

\mode<presentation>
\usetheme{Bootlin}

\title{Anatomy of Cross-compilation toolchains}

\begin{document}

\begin{frame}{Embedded Linux Conference Europe 2016}
  \begin{center}
    \begin{columns}
      \column{0.6\textwidth}
      \huge
      Anatomy of cross-compilation toolchains\\
      \vspace{2cm}
      \normalsize
      Thomas Petazzoni\\
      Bootlin\\
      {\em thomas.petazzoni@bootlin.com}
      \column{0.4\textwidth}
      \begin{center}
        \includegraphics[width=\textwidth]{anatomy-of-a-lego-man-jason-freeny-5.jpg}\\
        \tiny
        Artwork and Photography by Jason Freeny
      \end{center}
    \end{columns}
  \end{center}
\end{frame}

\begin{frame}{Thomas Petazzoni}
  \begin{columns}
    \column{0.7\textwidth}
  \begin{itemize}
  \item CTO and Embedded Linux engineer at {\bf Bootlin}
    \begin{itemize}
    \item Embedded Linux specialists.
    \item Development, consulting and training.
    \item \url{http://bootlin.com}
    \end{itemize}
  \item Contributions
    \begin{itemize}
    \item {\bf Kernel support for the Marvell Armada} ARM SoCs from
      Marvell
    \item Major contributor to {\bf Buildroot}, an open-source, simple and
      fast embedded Linux build system
    \end{itemize}
  \item Living in {\bf Toulouse}, south west of France
  \end{itemize}
  \column{0.3\textwidth}
  \begin{center}
  \includegraphics[width=0.6\textwidth]{thomas-petazzoni.jpg}\\
  {\small Drawing from Frank Tizzoni, at Kernel Recipes 2016}
  \end{center}
\end{columns}
\end{frame}

\begin{frame}{Disclaimer}
  \begin{itemize}
  \item I am {\bf not a toolchain developer}. Not pretending to know
    everything about toolchains.
  \item Experience gained from building simple toolchains in the
    context of Buildroot
  \item Purpose of the talk is to give an introduction, not in-depth
    information.
  \item Focused on simple gcc-based toolchains, and for a number of
    examples, on ARM specific details.
    \begin{itemize}
    \item Will not cover advanced use cases, such as LTO, GRAPHITE
      optimizations, etc.
    \item Will not cover LLVM
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{What is a cross-compiling toolchain?}
  \begin{itemize}
  \item A set of tools that allows to build source code into binary
    code for a {\em target platform} different than the one where the
    build takes place
    \begin{itemize}
    \item Different CPU architecture
    \item Different ABI
    \item Different operating system
    \item Different C library
    \end{itemize}
  \item Three {\em machines} involved in the build process
    \begin{itemize}
    \item {\bf build} machine, where the build takes place
    \item {\bf host} machine, where the execution takes place
    \item {\bf target} machine, for which the programs generate code
    \end{itemize}
  \item Native toolchain: {\em build == host == target}
  \item Cross-compilation toolchain: {\em build == host != target}
  \item Corresponds to the \code{--build}, \code{--host} and
    \code{--target} {\em autoconf} \code{configure} script arguments
    \begin{itemize}
    \item By default, automatically guessed by {\em autoconf} to be
      for the current machine
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Toolchain tuple}
  \begin{itemize}
  \item autoconf defines the concept of {\em system definitions},
    represented as {\bf tuples}
  \item A system definition describes a system: CPU architecture,
    operating system, vendor, ABI, C library
  \item Different forms:
    \begin{itemize}
    \item \code{<arch>-<vendor>-<os>-<libc/abi>}, full form
    \item \code{<arch>-<os>-<libc/abi>}
    \end{itemize}
  \item Components:
    \begin{itemize}
    \item \code{<arch>}, the CPU architecture: arm, mips, powerpc,
      i386, i686, etc.
    \item \code{<vendor>}, (mostly) free-form string, ignored by {\em autoconf}
    \item \code{<os>}, the operating system. Either \code{none} or
      \code{linux} for the purpose of this talk.
    \item \code{<libc/abi>}, combination of details on the C library
      and the ABI in use
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Toolchain tuple examples}
  \begin{itemize}
  \item \code{arm-foo-none-eabi}, bare-metal toolchain targeting the
    ARM architecture, from vendor {\em foo}
  \item \code{arm-unknown-linux-gnueabihf}, Linux toolchain targeting
    the ARM architecture, using the EABIhf ABI and the glibc C
    library, from an {\em unknown} vendor
  \item \code{armeb-linux-uclibcgnueabi}, Linux toolchain targeting
    the ARM big-endian architecture, using the EABI ABI and the uClibc
    C library
  \item \code{mips-img-linux-gnu}, Linux toolchain targeting the MIPS
    architecture, using the glibc C library, provided by Imagination
    Technologies.
  \end{itemize}
\end{frame}

\begin{frame}{Bare-metal vs. Linux toolchain}
  \begin{itemize}
  \item Two main values for \code{<os>}
    \begin{itemize}
    \item \code{none} for {\bf bare-metal} toolchains
      \begin{itemize}
      \item Used for development without an operating system
      \item C library used is generally {\bf newlib}
      \item Provides C library services that do not require an
        operating system
      \item Allows to provide basic {\em system calls} for specific
        hardware targets
      \item Can be used to build bootloaders or the Linux kernel,
        cannot build Linux userspace code
      \end{itemize}
    \item \code{linux} for {\bf Linux} toolchains
      \begin{itemize}
      \item Used for development with a Linux operating system
      \item Choice of Linux-specific C libraries: {\bf glibc}, {\bf
          uclibc}, {\bf musl}
      \item Supports Linux system calls
      \item Can be used to build Linux userspace code, but also
        bare-metal code such as bootloaders or the kernel itself
      \end{itemize}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Components}
  \begin{itemize}
  \item There are four core components in a Linux cross-compilation
    toolchain
    \begin{enumerate}
    \item {\bf binutils}
    \item {\bf gcc}
    \item {\bf Linux kernel headers}
    \item {\bf C library}
    \end{enumerate}
  \item In addition to these, a few dependencies are needed to build
    {\em gcc} itself.
  \end{itemize}
\end{frame}

\begin{frame}{binutils}
  \begin{itemize}
  \item ``{\em collection of binary tools}''
  \item Main tools
    \begin{itemize}
    \item {\bf ld}, the linker. Links multiple object files into a
      shared library, an executable, or another object file.
    \item {\bf as}, the assembler. Takes architecture-specific
      assembler code in text form, and produces a corresponding object
      file with binary code.
    \end{itemize}
  \item Debugging/analysis tools and other tools
    \begin{itemize}
    \item addr2line, ar, c++filt, gold, gprof, nm, objcopy, objdump,
      ranlib, readelf, size, strings, strip
    \end{itemize}
  \item Needs to be configured for each CPU architecture: your native
    x86 binutils cannot produce ARM code.
  \item Pretty straightforward to cross-compile, no special
    dependencies are needed.\\
    \code{./configure --target=arm-buildroot-linux-gnueabihf --with-sysroot=PATH}
  \end{itemize}
\end{frame}

\begin{frame}{gcc}
  \begin{itemize}
  \item GNU Compiler Collection
  \item Front-ends for many source languages: C, C++, Fortran, Go,
    etc.
  \item Back-ends for many CPU architectures.
  \item Provides:
    \begin{itemize}
    \item The compiler itself, \code{cc1} for C, \code{cc1plus} for
      C++. Only generates assembly code in text format.
    \item The compiler driver, \code{gcc}, \code{g++}, which drives
      the compiler itself, but also the binutils assembler and linker.
    \item Target libraries: \code{libgcc} (gcc runtime),
      \code{libstdc++} (the C++ library), \code{libgfortran} (the
      Fortran runtime)
    \item Header files for the standard C++ library.
    \end{itemize}
  \item Building {\em gcc} is a bit more involved than building {\em
      binutils}: two steps are needed, see later.
  \end{itemize}
\end{frame}

\begin{frame}{Linux Kernel headers}
  \begin{itemize}
  \item In order to build a C library, the Linux kernel headers are
    needed: definitions of system call numbers, various structure
    types and definitions.
  \item In the kernel, headers are split between:
    \begin{itemize}
    \item User-space visible headers, stored in \code{uapi}
      directories: \code{include/uapi/},
      \code{arch/<ARCH>/include/uapi/asm}
    \item Internal kernel headers.
    \end{itemize}
  \item Installation takes place using \code{make
      ARCH=.. INSTALL_HDR_PATH=... headers_install}
    \begin{itemize}
    \item The installation includes a sanitation pass, to remove
      kernel-specific constructs from the headers.
    \item As of Linux 4.8, installs 756 header files.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Linux Kernel headers version}
  \begin{itemize}
  \item Which version of the kernel headers should be used in a
    toolchain?
  \item The kernel to userspace ABI is backward compatible.
  \item Therefore, the version of the kernel used for the kernel
    headers must be the same version or older than the kernel version
    running on the target system.
  \item Otherwise the C library might use system calls that are not
    provided by the kernel.
  \item Examples:
    \begin{itemize}
    \item Toolchain using 3.10 kernel headers, running 4.4 kernel on
      the target $\rightarrow$ OK
    \item Toolchain using 4.8 kernel headers, running 4.4 kernel on
      the target $\rightarrow$ NOK
    \end{itemize}
  \end{itemize}
  \begin{block}{Linux 3.13.0 headers}
\begin{verbatim}
$ cat arm-none-linux-gnueabi/libc/usr/include/linux/version.h
define LINUX_VERSION_CODE 199936
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
\end{verbatim}
  \end{block}
\end{frame}

\begin{frame}{C library}
  \begin{itemize}
  \item Provides the implementation of the POSIX standard functions,
    plus several other standards and extensions
  \item Based on the Linux system calls
  \item Several implementations available:
    \begin{itemize}
    \item glibc
    \item uClibc-ng (formerly uClibc)
    \item musl
    \item bionic, for Android systems
    \item A few other more special-purpose: newlib (for bare-metal),
      dietlibc, klibc
    \end{itemize}
  \item After compilation and installation, provides:
    \begin{itemize}
    \item The dynamic linker, \code{ld.so}
    \item The C library itself \code{libc.so}, and its companion
      libraries: \code{libm}, \code{librt}, \code{libpthread},
      \code{libutil}, \code{libnsl}, \code{libresolv}, \code{libcrypt}
    \item The C library headers: \code{stdio.h}, \code{string.h}, etc.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{C library: glibc}
  \begin{itemize}
  \item GNU C Library
  \item {\bf De-facto standard} of Linux C libraries
  \item Used in virtually all common desktop/server distributions
  \item {\bf Full-featured}
  \item Supports for numerous architectures or operating systems
  \item No support for noMMU platforms
  \item No support for static linking
  \item {\bf ABI backward} compatibility
  \item Almost no configurability
  \item Used to be ``too big'' for embedded, but no longer necessarily
    the case.
  \item LGPLv2.1 or later
  \item \url{https://www.gnu.org/software/libc/}
  \end{itemize}
\end{frame}

\begin{frame}{C library: uClibc/uClibc-ng}
  \begin{itemize}
  \item Started in {\bf 2000}
  \item High-level of configurability
  \item Supports many architectures, include some not supported by
    glibc
  \item Supports {\bf only Linux} as operating system
  \item {\bf No ABI} backward compatibility
  \item Supports numerous {\bf no-MMU} architectures: ARM noMMU, Blackfin,
    etc.
  \item No longer related to {\em uClinux}
  \item Support for {\bf static linking}
  \item Original {\em uClibc} project dead (last release in May 2012),
    but the {\bf uClibc-ng} fork is very active and is the de-facto
    replacement.
  \item LGPLv2.1
  \item \url{http://uclibc-ng.org/}
  \end{itemize}
\end{frame}

\begin{frame}{C library: musl}
  \begin{itemize}
  \item Started in 2011
  \item {\bf MIT licensed}
  \item Very active development
  \item Support for ARM, ARM64, i386, Microblaze, MIPS(64), OpenRisc,
    PowerPC(64), SuperH, x86-4
  \item Recently, {\bf noMMU support} was added for SuperH2, for the
    J-core Open Processor
  \item No configurability
  \item {\bf Small}, even smaller than uClibc, especially for static
    linking scenarios
  \item Strict conformance to standards (stricter than glibc, uClibc),
    causes a few build issues with a number of packages
  \item Nice comparison of the three main C libraries:
    \url{http://www.etalabs.net/compare_libcs.html}
  \item \url{http://www.musl-libc.org/}
  \end{itemize}
\end{frame}

\begin{frame}{C library: size comparison}

\begin{center}
\begin{tabular}{|c|c|c|c|}
\hline
& glibc & uclibc & musl \\
\hline
\code{ld}, dynamic linker & 121 KB & 25 KB & N/A \\
\code{libc} & 878 KB & 286 KB & 437 KB \\
\code{libcrypt} & 30 KB & 17 KB & N/A \\
\code{libdl} & 9.5 KB & 9 KB & N/A \\
\code{libm} & 414 KB & 37 KB & N/A \\
\code{libnsl} & 54 KB & 4.7 KB & N/A \\
\code{libnss_dns} & 14 KB & N/A & N/A \\
\code{libnss_files} & 30 KB & N/A & N/A \\
\code{libpthread} & 105 KB & 76 KB &N/A \\
\code{libresolv} & 54 KB & 4.7 KB & N/A \\
\code{librt} & 22 KB & 13 KB & N/A \\
\code{libutil} & 9.5K & 4.7 KB & N/A \\
\hline
TOTAL & 1741 KB & 477 KB & 437 KB \\
\hline
\end{tabular}

{\tiny ARM Cortex-A9 toolchain built with the Thumb-2 instruction set, using
Buildroot. gcc 4.9, binutils 2.26, musl 1.1.15, glibc 2.23, uclibc-ng
1.0.17}

\end{center}

\end{frame}

\begin{frame}{gcc dependencies}
  \begin{itemize}
  \item Several math libraries are needed to build {\em gcc}
  \item They are compiled for the host machine, i.e they are not
    needed on the target
    \begin{itemize}
    \item {\bf mpfr}, multiple-precision floating-point
      computations. Used since gcc 4.3 to {\em evaluate and replace at
        compile-time calls to built-in math functions having constant
        arguments with their mathematically equivalent results}
    \item {\bf gmp}, dependency of {\em mpfr}
    \item {\bf mpc}, for computation of complex numbers. Used since
      gcc 4.5 to {\em evaluate calls to complex built-in math
        functions having constant arguments and replace them at
        compile time with their mathematically equivalent result}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Overall build process}
  \begin{itemize}
  \item The build process for a regular Linux cross-compilation
    toolchain is in fact fairly easy:
    \begin{enumerate}
    \item Build {\em binutils}
    \item Build the dependencies of {\em gcc}: {\em mpfr}, {\em gmp},
      {\em mpc}
    \item Install the Linux kernel headers
    \item Build a first stage {\em gcc}: no support for a C library,
      support only for static linking
    \item Build the {\em C library} using the first stage {\em gcc}
    \item Build the final {\em gcc}, with C library and support for
      dynamic linking
    \end{enumerate}
  \end{itemize}
\end{frame}

\begin{frame}{Overall build process: example in Buildroot}
  \begin{center}
    \includegraphics[width=\textwidth]{toolchain-graph-depends.pdf}
  \end{center}
\end{frame}

\begin{frame}{Concept of sysroot}
  \begin{itemize}
  \item The {\em sysroot} is the {\bf the logical root directory for
      headers and libraries}
  \item Where {\em gcc} looks for headers, and {\em ld} looks for
    libraries
  \item Both {\em gcc} and {\em binutils} are built with
    \code{--with-sysroot=<SYSROOT>}
  \item The kernel headers and the C library are installed in
    \code{<SYSROOT>}
  \item If the toolchain has been moved to a different location, {\em
      gcc} will still find its sysroot if it's in a subdir of
    \code{--prefix}
    \begin{itemize}
    \item \code{--prefix=/home/thomas/buildroot/arm-uclibc/host/usr}
    \item \code{--with-sysroot=/home/thomas/buildroot/arm-uclibc/host/usr/arm-buildroot-linux-uclibcgnueabihf/sysroot}
    \end{itemize}
  \item Can be overridden at runtime using gcc's \code{--sysroot}
    option.
  \item The current {\em sysroot} can be printed using the
    \code{-print-sysroot} option.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Multilib toolchains (1)}
  \begin{itemize}
  \item Most toolchains provide a {\bf single sysroot} with the C
    library and gcc runtime libraries
  \item These libraries, built for the target, are optimized for a
    {\bf specific architecture variant and ABI}
  \item Need to have one toolchain for each architecture variant or
    ABI
  \item {\bf Multilib} toolchains contain multiple {\em sysroot}, each
    having a version of the target libraries for different
    architecture/ABI variants.
  \item Example of the Sourcery CodeBench ARM toolchain:
\begin{block}{}
{\small
    \begin{verbatim}
$ arm-none-linux-gnueabi-gcc -print-multi-lib
.;
armv4t;@march=armv4t
thumb2;@mthumb@march=armv7-a
\end{verbatim}
}
\end{block}
  \item Three sysroots: ARMv5, ARMv4 and ARMv7 Thumb-2
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Multilib toolchains (2)}
  \begin{itemize}
  \item The compiler automatically selects the right {\em sysroot}
    depending on the gcc flags:
\begin{block}{}
{\tiny
\begin{verbatim}
$ arm-none-linux-gnueabi-gcc -march=armv5te -print-sysroot
.../bin/../arm-none-linux-gnueabi/libc
$ arm-none-linux-gnueabi-gcc -march=armv4t -print-sysroot
.../bin/../arm-none-linux-gnueabi/libc/armv4t
$ arm-none-linux-gnueabi-gcc -march=armv7-a -mthumb -print-sysroot
.../bin/../arm-none-linux-gnueabi/libc/thumb2
\end{verbatim}
}
\end{block}

  \item Each {\em sysroot} has a different library variant:
\begin{block}{}
{\tiny
    \begin{verbatim}
$ readelf -A arm-none-linux-gnueabi/libc/lib/ld-2.18.so
  Tag_CPU_name: "5TE"
  Tag_CPU_arch: v5TE
$ readelf -A arm-none-linux-gnueabi/libc/armv4t/lib/ld-2.18.so
  Tag_CPU_name: "4T"
  Tag_CPU_arch: v4T
$ readelf -A arm-none-linux-gnueabi/libc/thumb2/lib/ld-2.18.so
  Tag_CPU_name: "7-A"
  Tag_CPU_arch: v7
  Tag_THUMB_ISA_use: Thumb-2
\end{verbatim}
}
\end{block}
  \end{itemize}
\end{frame}

\begin{frame}{Toolchain contents}
  \only<1>{
    Cross-compilation toolchain generated by Buildroot
  }
  \begin{itemize}
  \item \code{arm-buildroot-linux-uclibcgnueabihf/}
    \only<2>{
      \begin{itemize}
      \item \code{bin/}
        \begin{itemize}
        \item Limited set of {\em binutils} programs, without their
          cross-compilation prefix. Hard links to their counterparts
          with the prefix. This is where {\em gcc} finds them.
        \end{itemize}
      \item \code{include/c++/4.9.4/}
        \begin{itemize}
        \item Headers for the C++ standard library, installed by {\em
            gcc}
        \item Interestingly, they are not part of the {\em sysroot}
          per-se.
        \end{itemize}
      \item \code{lib/}
        \begin{itemize}
        \item The {\em gcc} runtime libraries, built for the target
        \item \code{libatomic}, provides a software implementation of
          \code{atomic} built-ins, when needed
        \item \code{libgcc}, the main {\em gcc} runtime (optimized
          functions, 64-bit division, floating point emulation)
        \item \code{libitm}, transactional memory library
        \item \code{libstdc++}, standard C++ library
        \item \code{libsupc++}, subset of \code{libstdc++} with only
          the {\em language support} functions
        \end{itemize}
      \item \code{sysroot/}
        \begin{itemize}
        \item \code{lib/}, \code{usr/lib/}: C library and gcc runtime
          libraries (shared and static)
        \item \code{usr/include/}, Linux kernel and C library headers
        \end{itemize}
      \end{itemize}
    }
  \item \code{bin/}
    \only<3>{
      \begin{itemize}
      \item \code{arm-buildroot-linux-uclibcgnueabihf-} prefixed tools
      \item From {\em binutils}: addr2line, ar, as, elfedit, gcov,
        gprof, ld, nm, objcopy, objdump, ranlib, readelf, size, strings,
        strip
      \item From {\em gcc}: c++ (same as g++), cc (same as gcc), cpp,
        g++, gcc, gcc-ar, gcc-nm, gcc-ranlib
      \item The \code{gcc-{ar,nm,ranlib}} are wrappers for the corresponding
        binutils program, to support Link Time Optimization (LTO)
      \end{itemize}
    }
  \item \code{include/}
    \only<4>{
      \begin{itemize}
      \item Headers of the host libraries ({\em gmp}, {\em mpfr}, {\em
          mpc})
      \end{itemize}
    }
  \item \code{lib/}
    \only<5>{
      \begin{itemize}
      \item \code{gcc/arm-buildroot-linux-uclibcgnueabihf/4.9.4/}
        \begin{itemize}
        \item \code{crtbegin*.o}, \code{crtend*.o}, object files
          handling constructors/destructors, linked into executables
        \item \code{include/}, headers provided by the compiler
          (\code{stdarg.h}, \code{stdint.h}, \code{stdatomic.h}, etc.)
        \item \code{include-fixed/}, system headers that gcc fixed up
          using {\em fixincludes}
        \item \code{install-tools/}, also related to the {\em
            fixincludes} process
        \item \code{libgcc.a}, \code{libgcc_eh.a}, \code{libgcov.a},
          static variants of the gcc runtime libraries
        \end{itemize}
      \item \code{ldscripts/}, linker scripts provided by {\em gcc} to
        link programs and libraries
      \item Host version of {\em gmp}, {\em mpfr}, {\em mpc}, needed for
        {\em gcc}
      \end{itemize}
    }
  \item \code{libexec/}
    \only<6>{
      \begin{itemize}
      \item \code{gcc/arm-buildroot-linux-uclibcgnueabihf/4.9.4/}
        \begin{itemize}
        \item \code{cc1}, the actual C compiler
        \item \code{cc1plus}, the actual C++ compiler
        \item \code{collect2}, program from gcc collecting
          initialization functions, wrapping the linker
        \item \code{install-tools/}, misc {\em gcc} related tools, not
          needed for the compilation process
        \item \code{liblto_plugin.so.0.0.0}, \code{lto-wrapper},
          \code{lto1}, related to LTO support (outside of the scope of
          this talk)
        \end{itemize}
      \end{itemize}
    }
  \item \code{share/}
    \only<7>{
      \begin{itemize}
      \item documentation (man pages and info pages)
      \item translation files for gcc and binutils
      \end{itemize}
    }
  \end{itemize}
\end{frame}

\begin{frame}{Architecture tuning}
  \begin{itemize}
  \item {\em gcc} provides several configure-time options to tune for
    a specific architecture/CPU variant: \code{--with-arch},
    \code{--with-cpu}, \code{--with-abi}, \code{--with-fpu}
  \item These define the {\em default} architecture/CPU variant for
    which {\em gcc} will generate code.
  \item They can be overridden at runtime using the \code{-march},
    \code{-mcpu}, \code{-mabi}, \code{-mfpu} options.
  \item However, be careful: parts of the toolchain are built for the target!
    \begin{itemize}
    \item The gcc runtime libraries
    \item The C library, dynamic linker, and startup code
    \end{itemize}
  \item They are built {\em together} with the rest of the toolchain,
    so it's important to know with what optimization level they were
    built!
  \item Passing \code{-march=armv5te} is not sufficient to make your
    binary work on ARMv5 if your toolchain originally targets ARMv7.
  \item Read the {\em gcc} documentation, section {\em
      Machine-dependent options} to get the complete list of possible
    values.
  \end{itemize}
\end{frame}

\begin{frame}{ABI: definition}
  \begin{itemize}
  \item ABI = {\em Application Binary Interface}
  \item From the point of a toolchain, the ABI defines:
    \begin{itemize}
    \item How function calls are made (so-called {\em calling
        convention})
      \begin{itemize}
      \item How arguments are passed: in registers (which ones?), on
        the stack, how 64-bits arguments are handled on 32 bits
        architectures
      \item How the return value is passed
      \end{itemize}
    \item Size of basic data types
    \item Alignment of members in structures
    \item When there is an operating system, how system calls are made
    \end{itemize}
  \item Object files from different ABIs cannot be linked together
    (especially important if you have pre-built libraries or
    executables!)
  \item For a given CPU architecture, there can potentially be an
    infinite number of ABIs: ABIs are just specifications on how to
    use the CPU architecture
  \item Need to understand the ABIs for each architecture.
  \end{itemize}
\end{frame}

\begin{frame}{ABI: example of ARM 32}
  \begin{itemize}
  \item {\bf OABI}: obsolete ABI. Forced the use of hard-float
    instructions, which required emulation of floating-point
    operations in the kernel. No longer supported anywhere.
  \item {\bf EABI}, standardized by ARM. Allows mixing hard-float code
    with soft-float code. Floating point arguments passed in integer
    registers.
    \begin{itemize}
    \item Hard-float code: uses floating point instructions directly.
    \item Soft-float code: emulates floating point instructions using
      a userspace library provided by gcc
    \end{itemize}
  \item {\bf EABIhf}, also standardized by ARM. Requires a floating
    point unit: only hard-float code. Floating point arguments passed
    in floating point registers.
  \item {\em gcc} options
    \begin{itemize}
    \item EABI soft-float: \code{-mabi=aapcs-linux -mfloat-abi=soft}
    \item EABI hard-float: \code{-mabi=aapcs-linux -mfloat-abi=softfp}
    \item EABIhf: \code{-mabi=aapcs-linux -mfloat-abi=hard}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Difference between toolchain and SDK}
  \begin{itemize}
  \item Toolchain: just the compiler, binutils and C library
  \item SDK: a toolchain, plus a number (potentially large) of
    libraries built for the target architecture, and additional native
    tools helpful when building software.
  \item Build systems such as OpenEmbedded or Yocto can typically:
    \begin{itemize}
    \item Use an existing toolchain as input, or build their own toolchain
    \item In addition to producing a root filesystem, they can also
      produce a SDK to allow application developers to build
      applications/libraries for the target.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{How to get a cross-compilation toolchain}
  \begin{itemize}
  \item Pre-built
    \begin{itemize}
    \item From your {\bf distribution}. Ubuntu and Debian have
      numerous cross-compilers readily available.
    \item From various {\bf organization}: Linaro provides ARM and
      AArch64 toolchains, Mentor provides a few free Sourcery
      CodeBench toolchains, Imagination provides MIPS toolchains, etc.
    \end{itemize}
  \item Built it yourself
    \begin{itemize}
    \item {\bf Crosstool-NG}, tool specialized in building
      cross-compilation toolchain. By far the most
      configurable/versatile.
    \item Embedded Linux {\bf build systems} generally all know how to
      build a cross-compilation toolchain: Yocto/OpenEmbedded,
      Buildroot, OpenWRT, etc.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{References}
  \begin{itemize}
  \item Crosstool-NG documentation,
    \url{https://github.com/crosstool-ng/crosstool-ng/blob/master/docs/}
  \item GCC documentation,
    \url{https://gcc.gnu.org/onlinedocs/}
  \item Binutils documentation,
    \url{https://sourceware.org/binutils/docs/}
  \end{itemize}
\end{frame}

\begin{frame}
  \begin{center}
    \large
    Thanks for your attention!\\
    \Huge
    Questions?\\
    \vspace{2cm}
    \large
    Thomas Petazzoni\\
    \code{thomas.petazzoni@bootlin.com}\\
    \vspace{0.5cm}
    \scriptsize
    Slides under CC-BY-SA 3.0\\
    \url{http://bootlin.com/pub/conferences/2016/elce/petazzoni-toolchain-anatomy/}
  \end{center}
\end{frame}

\end{document}
