My Wiki!

author “Yann E. MORIN” yann.morin.1998@free.fr

Thu Feb 09 21:39:31 2012 +0100 (11 days ago)

branch 1.13 changeset 2875 1a29ad87a9ec parent 2563 e17f35b05539 permissions -rw-r–r– 1.13: update version to 1.13.4

 1 File.........: 9 - Build procedure overview.txt

 2 Copyright....: (C) 2011 Yann E. MORIN <yann.morin.1998@anciens.enib.fr>

 3 License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5
 4 
 5 
 6 How is a toolchain constructed? /
 7 _______________________________/
 8 
 9 This is the result of a discussion with Francesco Turco <mail@fturco.org>:
10   http://sourceware.org/ml/crossgcc/2011-01/msg00060.html
11 
12 Francesco has a nice tutorial for beginners, along with a sample, step-by-
13 step procedure to build a toolchain for an ARM target from an x86_64 Debian
14 host:
15   http://fturco.org/wiki/doku.php?id=debian:cross-compiler
16 
17 Thank you Francesco for initiating this!
18 
19 
20 I want a cross-compiler! What is this toolchain you're speaking about? |
21 -----------------------------------------------------------------------+
22 
23 A cross-compiler is in fact a collection of different tools set up to
24 tightly work together. The tools are arranged in a way that they are
25 chained, in a kind of cascade, where the output from one becomes the
26 input to another one, to ultimately produce the actual binary code that
27 runs on a machine. So, we call this arrangement a "toolchain". When
28 a toolchain is meant to generate code for a machine different from the

29 machine it runs on, this is called a cross-toolchain.

30 

31 

32 So, what are those components in a toolchain? |

33 ----------------------------------------------+

34 

35 The components that play a role in the toolchain are first and foremost

36 the compiler itself. The compiler turns source code (in C, C++, whatever)

37 into assembly code. The compiler of choice is the GNU compiler collection,

38 well known as 'gcc'.

39 

40 The assembly code is interpreted by the assembler to generate object code.

41 This is done by the binary utilities, such as the GNU 'binutils'.

42 

43 Once the different object code files have been generated, they got to get

44 aggregated together to form the final executable binary. This is called

45 linking, and is achieved with the use of a linker. The GNU 'binutils' also

46 come with a linker.

47 

48 So far, we get a complete toolchain that is capable of turning source code

49 into actual executable code. Depending on the Operating System, or the lack

50 thereof, running on the target, we also need the C library. The C library

51 provides a standard abstraction layer that performs basic tasks (such as

52 allocating memory, printing output on a terminal, managing file access...).

53 There are many C libraries, each targeted to different systems. For the

54 Linux /desktop/, there is glibc or eglibc or even uClibc, for embedded Linux,

55 you have a choice of eglibc or uClibc, while for system without an Operating

56 System, you may use newlib, dietlibc, or even none at all. There a few other

57 C libraries, but they are not as widely used, and/or are targeted to very

58 specific needs (eg. klibc is a very small subset of the C library aimed at

59 building constrained initial ramdisks).

60 

61 Under Linux, the C library needs to know the API to the kernel to decide

62 what features are present, and if needed, what emulation to include for

63 missing features. That API is provided by the kernel headers. Note: this

64 is Linux-specific (and potentially a very few others), the C library on

65 other OSes do not need the kernel headers.

66 

67 

68 And now, how do all these components chained together? |

69 -------------------------------------------------------+

70 

71 So far, all major components have been covered, but yet there is a specific

72 order they need to be built. Here we see what the dependencies are, starting

73 with the compiler we want to ultimately use. We call that compiler the

74 'final compiler'.

75 

76   - the final compiler needs the C library, to know how to use it,

77 but:

78   - building the C library requires a compiler

79 

80 A needs B which needs A. This is the classic chicken'n'egg problem... This

81 is solved by building a stripped-down compiler that does not need the C

82 library, but is capable of building it. We call it a bootstrap, initial, or

83 core compiler. So here is the new dependency list:

84 

85   - the final compiler needs the C library, to know how to use it,

86   - building the C library requires a core compiler

87 but:

88   - the core compiler needs the C library headers and start files, to know

89     how to use the C library

90 

91 B needs C which needs B. Chicken'n'egg, again. To solve this one, we will

92 need to build a C library that will only install its headers and start

93 files. The start files are a very few files that gcc needs to be able to

94 turn on thread local storage (TLS) on an NPTL system. So now we have:

95 

96   - the final compiler needs the C library, to know how to use it,

97   - building the C library requires a core compiler

98   - the core compiler needs the C library headers and start files, to know

99     how to use the C library
 100 but:
 101   - building the start files require a compiler
 102 
 103 Geez... C needs D which needs C, yet again. So we need to build a yet
 104 simpler compiler, that does not need the headers and does need the start
 105 files. This compiler is also a bootstrap, initial or core compiler. In order
 106 to differentiate the two core compilers, let's call that one "core pass 1",
 107 and the former one "core pass 2". The dependency list becomes:
 108 
 109   - the final compiler needs the C library, to know how to use it,
 110   - building the C library requires a compiler
 111   - the core pass 2 compiler needs the C library headers and start files,
 112     to know how to use the C library
 113   - building the start files requires a compiler
 114   - we need a core pass 1 compiler
 115 
 116 And as we said earlier, the C library also requires the kernel headers.
 117 There is no requirement for the kernel headers, so end of story in this
 118 case:
 119 
 120   - the final compiler needs the C library, to know how to use it,
 121   - building the C library requires a core compiler
 122   - the core pass 2 compiler needs the C library headers and start files,
 123     to know how to use the C library
 124   - building the start files requires a compiler and the kernel headers
 125   - we need a core pass 1 compiler
 126 
 127 We need to add a few new requirements. The moment we compile code for the
 128 target, we need the assembler and the linker. Such code is, of course,
 129 built from the C library, so we need to build the binutils before the C
 130 library start files, and the complete C library itself. Also, some code
 131 in gcc will turn to run on the target as well. Luckily, there is no
 132 requirement for the binutils. So, our dependency chain is as follows:
 133 
 134   - the final compiler needs the C library, to know how to use it, and the
 135     binutils
 136   - building the C library requires a core pass 2 compiler and the binutils
 137   - the core pass 2 compiler needs the C library headers and start files,
 138     to know how to use the C library, and the binutils
 139   - building the start files requires a compiler, the kernel headers and the
 140     binutils
 141   - the core pass 1 compiler needs the binutils
 142 
 143 Which turns in this order to build the components:
 144 
 145   1 binutils
 146   2 core pass 1 compiler
 147   3 kernel headers
 148   4 C library headers and start files
 149   5 core pass 2 compiler
 150   6 complete C library
 151   7 final compiler
 152 
 153 Yes! :-) But are we done yet?
 154 
 155 In fact, no, there are still missing dependencies. As far as the tools
 156 themselves are involved, we do not need anything else.
 157 
 158 But gcc has a few pre-requisites. It relies on a few external libraries to
 159 perform some non-trivial tasks (such as handling complex numbers in
 160 constants...). There are a few options to build those libraries. First, one
 161 may think to rely on a Linux distribution to provide those libraries. Alas,
 162 they were not widely available until very, very recently. So, if the distro
 163 is not too recent, chances are that we will have to build those libraries
 164 (which we do below). The affected libraries are:
 165 
 166   - the GNU Multiple Precision Arithmetic Library, GMP
 167   - the C library for multiple-precision floating-point computations with
 168     correct rounding, MPFR
 169   - the C library for the arithmetic of complex numbers, MPC
 170 
 171 The dependencies for those libraries are:
 172 
 173   - MPC requires GMP and MPFR
 174   - MPFR requires GMP
 175   - GMP has no pre-requisite
 176 
 177 So, the build order becomes:
 178 
 179   1 GMP
 180   2 MPFR
 181   3 MPC
 182   4 binutils
 183   5 core pass 1 compiler
 184   6 kernel headers
 185   7 C library headers and start files
 186   8 core pass 2 compiler
 187   9 complete C library
 188  10 final compiler
 189 
 190 Yes! Or yet some more?
 191 
 192 This is now sufficient to build a functional toolchain. So if you've had
 193 enough for now, you can stop here. Or if you are curious, you can continue
 194 reading.
 195 
 196 gcc can also make use of a few other external libraries. These additional,
 197 optional libraries are used to enable advanced features in gcc, such as
 198 loop optimisation (GRAPHITE) and Link Time Optimisation (LTO). If you want
 199 to use these, you'll need three additional libraries:
 200 
 201 To enable GRAPHITE:
 202   - the Parma Polyhedra Library, PPL
 203   - the Chunky Loop Generator, using the PPL backend, CLooG/PPL
 204 
 205 To enable LTO:
 206   - the ELF object file access library, libelf
 207 
 208 The dependencies for those libraries are:
 209 
 210   - PPL requires GMP
 211   - CLooG/PPL requires GMP and PPL
 212   - libelf has no pre-requisites
 213 
 214 The list now looks like (optional libs with a *):
 215 
 216   1 GMP
 217   2 MPFR
 218   3 MPC
 219   4 PPL *
 220   5 CLooG/PPL *
 221   6 libelf *
 222   7 binutils
 223   8 core pass 1 compiler
 224   9 kernel headers
 225  10 C library headers and start files
 226  11 core pass 2 compiler
 227  12 complete C library
 228  13 final compiler
 229 
 230 This list is now complete! Wouhou! :-)
 231 
 232 
 233 So the list is complete. But why does crosstool-NG have more steps? |
 234 --------------------------------------------------------------------+
 235 
 236 The already thirteen steps are the necessary steps, from a theoretical point
 237 of view. In reality, though, there are small differences; there are three
 238 different reasons for the additional steps in crosstool-NG.
 239 
 240 First, the GNU binutils do not support some kinds of output. It is not possible
 241 to generate 'flat' binaries with binutils, so we have to use another component
 242 that adds this support: elf2flt. Another binary utility called sstrip has been
 243 added. It allows for super-stripping the target binaries, although it is not
 244 strictly required.
 245 
 246 Second, some C libraries require another step after the compiler is built, to
 247 install additional stuff. This is the case for mingw and newlib. Hence the
 248 libc_finish step.
 249 
 250 Third, crosstool-NG can also build some additional debug utilities to run on
 251 the target. This is where we build, for example, the cross-gdb, the gdbserver
 252 and the native gdb (the last two run on the target, the first runs on the
 253 same machine as the toolchain). The others (strace, ltrace, DUMA and dmalloc)
 254 are absolutely not related to the toolchain, but are nice-to-have stuff that
 255 can greatly help when developing, so are included as goodies (and they are
 256 quite easy to build, so it's OK; more complex stuff is not worth the effort
 257 to include in crosstool-NG).

Navigation