docs/overview.txt
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Fri Sep 04 17:27:16 2009 +0200 (2009-09-04)
changeset 1512 439a6b292917
parent 1491 ae44a02d67fb
child 1513 0a405ac9d9ce
permissions -rw-r--r--
TODO: update

Add TODO list for m4, autoconf, automake and libtool.
Building our own versions would remove burden from the users
who have older versions on their distributions, and are not
ready/able/allowed to upgrade.
yann@1
     1
File.........: overview.txt
yann@197
     2
Content......: Overview of how crosstool-NG works.
yann@92
     3
Copyrigth....: (C) 2007 Yann E. MORIN <yann.morin.1998@anciens.enib.fr>
yann@192
     4
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5
yann@92
     5
yann@628
     6
____________________
yann@628
     7
                   /
yann@628
     8
Table Of Content  /
yann@628
     9
_________________/
yann@628
    10
yann@628
    11
yann@628
    12
Introduction
yann@628
    13
History
yann@628
    14
Installing crosstool-NG
yann@628
    15
  Install method
yann@628
    16
  The hacker's way
yann@1048
    17
  Preparing for packaging
yann@837
    18
  Shell completion
yann@628
    19
  Contributed code
yann@628
    20
Configuring crosstool-NG
yann@628
    21
  Interesting config options
yann@628
    22
  Re-building an existing toolchain
yann@628
    23
Running crosstool-NG
yann@628
    24
  Stopping and restarting a build
yann@628
    25
  Testing all toolchains at once
yann@628
    26
  Overriding the number of // jobs
yann@1491
    27
  Note on // jobs
yann@1493
    28
  Tools wrapper
yann@628
    29
Using the toolchain
yann@628
    30
Toolchain types
yann@628
    31
Internals
yann@628
    32
  Makefile front-end
yann@628
    33
  Kconfig parser
yann@628
    34
  Architecture-specific
yann@628
    35
  Adding a new version of a component
yann@628
    36
  Build scripts
yann@628
    37
yann@1
    38
________________
yann@1
    39
               /
yann@1
    40
Introduction  /
yann@1
    41
_____________/
yann@1
    42
yann@1
    43
crosstool-NG aims at building toolchains. Toolchains are an essential component
yann@1
    44
in a software development project. It will compile, assemble and link the code
rpjday@436
    45
that is being developed. Some pieces of the toolchain will eventually end up
yann@1
    46
in the resulting binary/ies: static libraries are but an example.
yann@1
    47
yann@1
    48
So, a toolchain is a very sensitive piece of software, as any bug in one of the
yann@1
    49
components, or a poorly configured component, can lead to execution problems,
yann@1
    50
ranging from poor performance, to applications ending unexpectedly, to
yann@1
    51
mis-behaving software (which more than often is hard to detect), to hardware
rpjday@436
    52
damage, or even to human risks (which is more than regrettable).
yann@1
    53
yann@1
    54
Toolchains are made of different piece of software, each being quite complex
yann@1
    55
and requiring specially crafted options to build and work seamlessly. This
yann@1
    56
is usually not that easy, even in the not-so-trivial case of native toolchains.
yann@1
    57
The work reaches a higher degree of complexity when it comes to cross-
yann@40
    58
compilation, where it can become quite a nightmare...
yann@1
    59
yann@40
    60
Some cross-toolchains exist on the internet, and can be used for general
yann@1
    61
development, but they have a number of limitations:
yann@1
    62
  - they can be general purpose, in that they are configured for the majority:
yann@1
    63
    no optimisation for your specific target,
yann@1
    64
  - they can be prepared for a specific target and thus are not easy to use,
yann@1
    65
    nor optimised for, or even supporting your target,
rpjday@436
    66
  - they often are using aging components (compiler, C library, etc...) not
yann@1
    67
    supporting special features of your shiny new processor;
yann@1
    68
On the other side, these toolchain offer some advantages:
yann@1
    69
  - they are ready to use and quite easy to install and setup,
yann@1
    70
  - they are proven if used by a wide community.
yann@1
    71
yann@1
    72
But once you want to get all the juice out of your specific hardware, you will
yann@197
    73
want to build your own toolchain. This is where crosstool-NG comes into play.
yann@1
    74
rpjday@436
    75
There are also a number of tools that build toolchains for specific needs,
rpjday@436
    76
which are not really scalable. Examples are:
rpjday@436
    77
  - buildroot (buildroot.uclibc.org) whose main purpose is to build root file
yann@1
    78
    systems, hence the name. But once you have your toolchain with buildroot,
yann@1
    79
    part of it is installed in the root-to-be, so if you want to build a whole
yann@1
    80
    new root, you either have to save the existing one as a template and
yann@1
    81
    restore it later, or restart again from scratch. This is not convenient,
yann@1
    82
  - ptxdist (www.pengutronix.de/software/ptxdist), whose purpose is very
yann@1
    83
    similar to buildroot,
yann@702
    84
  - other projects (openembedded.org for example), which are again used to
yann@1
    85
    build root file systems.
yann@1
    86
rpjday@436
    87
crosstool-NG is really targeted at building toolchains, and only toolchains.
yann@1
    88
It is then up to you to use it the way you want.
yann@1
    89
yann@1
    90
___________
yann@1
    91
          /
yann@1
    92
History  /
yann@1
    93
________/
yann@1
    94
rpjday@436
    95
crosstool was first 'conceived' by Dan Kegel, who offered it to the community
yann@1
    96
as a set of scripts, a repository of patches, and some pre-configured, general
yann@1
    97
purpose setup files to be used to configure crosstool. This is available at
yann@203
    98
http://www.kegel.com/crosstool, and the subversion repository is hosted on
yann@203
    99
google at http://code.google.com/p/crosstool/.
yann@1
   100
yann@1
   101
I once managed to add support for uClibc-based toolchains, but it did not make
yann@437
   102
into mainline, mostly because I didn't have time to port the patch forward to
yann@1
   103
the new versions, due in part to the big effort it was taking.
yann@1
   104
yann@1
   105
So I decided to clean up crosstool in the state it was, re-order the things
yann@437
   106
in place, add appropriate support for what I needed, that is uClibc support
yann@437
   107
and a menu-driven configuration, named the new implementation crosstool-NG,
yann@437
   108
(standing for crosstool Next Generation, as many other comunity projects do,
yann@437
   109
and as a wink at the TV series "Star Trek: The Next Generation" ;-) ) and
yann@437
   110
made it available to the community, in case it was of interest to any one.
yann@1
   111
yann@294
   112
___________________________
yann@294
   113
                          /
yann@294
   114
Installing crosstool-NG  /
yann@294
   115
________________________/
yann@294
   116
yann@294
   117
There are two ways you can use crosstool-NG:
yann@294
   118
 - build and install it, then get rid of the sources like you'd do for most
yann@294
   119
   programs,
yann@294
   120
 - or only build it and run from the source directory.
yann@294
   121
yann@294
   122
The former should be used if you got crosstool-NG from a packaged tarball, see
rpjday@436
   123
"Install method", below, while the latter is most useful for developpers that
yann@294
   124
checked the code out from SVN, and want to submit patches, see "The Hacker's
yann@294
   125
way", below.
yann@294
   126
yann@294
   127
Install method |
yann@294
   128
---------------+
yann@294
   129
yann@294
   130
If you go for the install, then you just follow the classical, but yet easy
yann@294
   131
./configure way:
yann@294
   132
  ./configure --prefix=/some/place
yann@294
   133
  make
yann@294
   134
  make install
yann@294
   135
  export PATH="${PATH}:/some/place/bin"
yann@294
   136
yann@294
   137
You can then get rid of crosstool-NG source. Next create a directory to serve
yann@294
   138
as a working place, cd in there and run:
yann@294
   139
  ct-ng help
yann@294
   140
yann@294
   141
See below for complete usage.
yann@294
   142
yann@294
   143
The Hacker's way |
yann@294
   144
-----------------+
yann@294
   145
yann@294
   146
If you go the hacker's way, then the usage is a bit different, although very
yann@294
   147
simple:
yann@294
   148
  ./configure --local
yann@294
   149
  make
yann@294
   150
yann@294
   151
Now, *do not* remove crosstool-NG sources. They are needed to run crosstool-NG!
yann@294
   152
Stay in the directory holding the sources, and run:
yann@294
   153
  ./ct-ng help
yann@294
   154
yann@294
   155
See below for complete usage.
yann@294
   156
yann@294
   157
Now, provided you checked-out the code, you can send me your interesting changes
yann@294
   158
by running:
yann@294
   159
  svn diff
yann@294
   160
yann@294
   161
and mailing me the result! :-P
yann@294
   162
yann@1048
   163
Preparing for packaging |
yann@1048
   164
------------------------+
yann@1048
   165
yann@1048
   166
If you plan on packaging crosstool-NG, you surely don't want to install it
yann@1048
   167
in your root file system. The install procedure of crosstool-NG honors the
yann@1048
   168
DESTDIR variable:
yann@1048
   169
yann@1048
   170
  ./configure --prefix=/usr
yann@1048
   171
  make
rpjday@1291
   172
  make DESTDIR=/packaging/place install
yann@1048
   173
yann@837
   174
Shell completion |
yann@837
   175
-----------------+
yann@837
   176
yann@837
   177
crosstool-NG comes with a shell script fragment that defines bash-compatible
yann@837
   178
completion. That shell fragment is currently not installed automatically, but
yann@837
   179
this is planned.
yann@837
   180
yann@837
   181
To install the shell script fragment, you have two options:
yann@837
   182
 - install system-wide, most probably by copying ct-ng.comp into
yann@837
   183
   /etc/bash_completion.d/
yann@837
   184
 - install for a single user, by copying ct-ng.comp into ${HOME}/ and
yann@837
   185
   sourcing this file from your ${HOME}/.bashrc
yann@837
   186
yann@456
   187
Contributed code |
yann@456
   188
-----------------+
yann@456
   189
yann@456
   190
Some people contibuted code that couldn't get merged for various reasons. This
yann@456
   191
code is available as patches in the contrib/ sub-directory. These patches are
yann@456
   192
to be applied to the source of crosstool-NG, prior to installing.
yann@456
   193
yann@620
   194
An easy way to use contributed code is to pass the --with-contrib= option to
yann@620
   195
./configure. The possible values depend upon which contributions are packaged
yann@620
   196
with your version, but you can get with it with passing one of those two
yann@620
   197
special values:
yann@620
   198
  --with-contrib=list
yann@620
   199
    will list all available contributions
yann@620
   200
yann@620
   201
  --with-contrib=all
yann@620
   202
    will select all avalaible contributions
yann@620
   203
yann@620
   204
There is no guarantee that a particuliar contribution applies to the current
yann@620
   205
version of crosstool-ng, or that it will work at all. Use contributions at
yann@620
   206
your own risk.
yann@620
   207
yann@168
   208
____________________________
yann@168
   209
                           /
yann@168
   210
Configuring crosstool-NG  /
yann@168
   211
_________________________/
yann@168
   212
yann@620
   213
crosstool-NG is configured with a configurator presenting a menu-stuctured set
yann@620
   214
of options. These options let you specify the way you want your toolchain
yann@620
   215
built, where you want it installed, what architecture and specific processor it
yann@277
   216
will support, the version of the components you want to use, etc... The
yann@277
   217
value for those options are then stored in a configuration file.
yann@277
   218
yann@476
   219
The configurator works the same way you configure your Linux kernel. It is
yann@277
   220
assumed you now how to handle this.
yann@168
   221
yann@168
   222
To enter the menu, type:
yann@192
   223
  ct-ng menuconfig
yann@168
   224
yann@203
   225
Almost every config item has a help entry. Read them carefully.
yann@168
   226
yann@168
   227
String and number options can refer to environment variables. In such a case,
yann@192
   228
you must use the shell syntax: ${VAR}. You shall neither single- nor double-
yann@294
   229
quote the string/number options.
yann@168
   230
yann@192
   231
There are three environment variables that are computed by crosstool-NG, and
yann@168
   232
that you can use:
yann@168
   233
yann@168
   234
CT_TARGET:
yann@335
   235
  It represents the target tuple you are building for. You can use it for
yann@168
   236
  example in the installation/prefix directory, such as:
yann@168
   237
    /opt/x-tools/${CT_TARGET}
yann@168
   238
yann@168
   239
CT_TOP_DIR:
yann@182
   240
  The top directory where crosstool-NG is running. You shouldn't need it in
yann@182
   241
  most cases. There is one case where you may need it: if you have local
yann@182
   242
  patches and you store them in your running directory, you can refer to them
yann@168
   243
  by using CT_TOP_DIR, such as:
yann@168
   244
    ${CT_TOP_DIR}/patches.myproject
yann@168
   245
yann@168
   246
CT_VERSION:
yann@192
   247
  The version of crosstool-NG you are using. Not much use for you, but it's
yann@168
   248
  there if you need it.
yann@168
   249
yann@168
   250
Interesting config options |
yann@476
   251
---------------------------+
yann@168
   252
yann@168
   253
CT_LOCAL_TARBALLS_DIR:
yann@277
   254
  If you already have some tarballs in a direcotry, enter it here. That will
yann@197
   255
  speed up the retrieving phase, where crosstool-NG would otherwise download
yann@168
   256
  those tarballs.
yann@168
   257
yann@168
   258
CT_PREFIX_DIR:
yann@168
   259
  This is where the toolchain will be installed in (and for now, where it
yann@437
   260
  will run from). Common use is to add the target tuple in the directory
yann@277
   261
  path, such as (see above):
yann@277
   262
    /opt/x-tools/${CT_TARGET}
yann@168
   263
yann@168
   264
CT_TARGET_VENDOR:
yann@168
   265
  An identifier for your toolchain, will take place in the vendor part of the
yann@335
   266
  target tuple. It shall *not* contain spaces or dashes. Usually, keep it
yann@168
   267
  to a one-word string, or use underscores to separate words if you need.
yann@168
   268
  Avoid dots, commas, and special characters.
yann@168
   269
yann@168
   270
CT_TARGET_ALIAS:
yann@168
   271
  An alias for the toolchian. It will be used as a prefix to the toolchain
yann@168
   272
  tools. For example, you will have ${CT_TARGET_ALIAS}-gcc
yann@168
   273
yann@246
   274
Also, if you think you don't see enough versions, you can try to enable one of
yann@246
   275
those:
yann@246
   276
yann@246
   277
CT_OBSOLETE:
yann@246
   278
  Show obsolete versions or tools. Most of the time, you don't want to base
yann@246
   279
  your toolchain on too old a version (of gcc, for example). But at times, it
yann@246
   280
  can come handy to use such an old version for regression tests. Those old
yann@1300
   281
  versions are hidden behind CT_OBSOLETE. Those versions (or features) are so
yann@1300
   282
  marked because maintaining support for those in crosstool-NG would be too
yann@1300
   283
  costly, time-wise, and time is dear.
yann@246
   284
yann@246
   285
CT_EXPERIMENTAL:
yann@246
   286
  Show experimental versions or tools. Again, you might not want to base your
yann@246
   287
  toolchain on too recent tools (eg. gcc) for production. But if you need a
yann@246
   288
  feature present only in a recent version, or a new tool, you can find them
yann@1300
   289
  hidden behind CT_EXPERIMENTAL. Those versions (or features) did not (yet)
yann@1300
   290
  receive thorough testing in crosstool-NG, and/or are not mature enough to
yann@1300
   291
  be blindly trusted.
yann@246
   292
yann@276
   293
Re-building an existing toolchain |
yann@276
   294
----------------------------------+
yann@276
   295
yann@276
   296
If you have an existing toolchain, you can re-use the options used to build it
yann@276
   297
to create a new toolchain. That needs a very little bit of effort on your side
yann@894
   298
but is quite easy. The options to build a toolchain are saved with the
yann@894
   299
toolchain, and you can retrieve this configuration by running:
yann@894
   300
  ${CT_TARGET}-config
yann@276
   301
yann@894
   302
This will dump the configuration to stdout, so to rebuild a toolchain with this
yann@894
   303
configuration, the following is all you need to do:
yann@894
   304
  ${CT_TARGET}-config >.config
yann@1098
   305
  ct-ng oldconfig
yann@276
   306
yann@894
   307
Then, you can review and change the configuration by running:
yann@894
   308
  ct-ng menuconfig
yann@276
   309
yann@168
   310
________________________
yann@168
   311
                       /
yann@168
   312
Running crosstool-NG  /
yann@168
   313
_____________________/
yann@1
   314
yann@168
   315
To build the toolchain, simply type:
yann@203
   316
  ct-ng build
yann@135
   317
yann@135
   318
This will use the above configuration to retrieve, extract and patch the
yann@135
   319
components, build, install and eventually test your newly built toolchain.
yann@1
   320
yann@1
   321
You are then free to add the toolchain /bin directory in your PATH to use
yann@1
   322
it at will.
yann@1
   323
yann@135
   324
In any case, you can get some terse help. Just type:
yann@192
   325
  ct-ng help
yann@203
   326
or:
yann@203
   327
  man 1 ct-ng
yann@135
   328
rpjday@436
   329
Stopping and restarting a build |
yann@476
   330
--------------------------------+
yann@135
   331
yann@135
   332
If you want to stop the build after a step you are debugging, you can pass the
yann@135
   333
variable STOP to make:
yann@192
   334
  ct-ng STOP=some_step
yann@135
   335
yann@135
   336
Conversely, if you want to restart a build at a specific step you are
yann@135
   337
debugging, you can pass the RESTART variable to make:
yann@192
   338
  ct-ng RESTART=some_step
yann@135
   339
yann@136
   340
Alternatively, you can call make with the name of a step to just do that step:
yann@192
   341
  ct-ng libc_headers
yann@136
   342
is equivalent to:
yann@620
   343
  ct-ng RESTART=libc_headers STOP=libc_headers
yann@136
   344
yann@304
   345
The shortcuts +step_name and step_name+ allow to respectively stop or restart
yann@136
   346
at that step. Thus:
yann@304
   347
  ct-ng +libc_headers        and:    ct-ng libc_headers+
yann@136
   348
are equivalent to:
yann@192
   349
  ct-ng STOP=libc_headers    and:    ct-ng RESTART=libc_headers
yann@136
   350
yann@181
   351
To obtain the list of acceptable steps, please call:
yann@544
   352
  ct-ng list-steps
yann@181
   353
yann@168
   354
Note that in order to restart a build, you'll have to say 'Y' to the config
yann@168
   355
option CT_DEBUG_CT_SAVE_STEPS, and that the previous build effectively went
yann@168
   356
that far.
yann@92
   357
yann@1025
   358
Building all toolchains at once |
yann@1025
   359
--------------------------------+
yann@92
   360
yann@1025
   361
You can build all samples; simply call:
yann@1025
   362
  ct-ng build-all
yann@40
   363
yann@335
   364
Overriding the number of // jobs |
yann@476
   365
---------------------------------+
yann@335
   366
yann@335
   367
If you want to override the number of jobs to run in // (the -j option to
yann@335
   368
make), you can either re-enter the menuconfig, or simply add it on the command
yann@335
   369
line, as such:
yann@335
   370
  ct-ng build.4
yann@335
   371
yann@335
   372
which tells crosstool-NG to override the number of // jobs to 4.
yann@335
   373
yann@335
   374
You can see the actions that support overriding the number of // jobs in
yann@335
   375
the help menu. Those are the ones with [.#] after them (eg. build[.#] or
yann@1025
   376
build-all[.#], and so on...).
yann@1025
   377
yann@1025
   378
Note on // jobs |
yann@1025
   379
----------------+
yann@1025
   380
yann@1025
   381
The crosstool-NG script 'ct-ng' is a Makefile-script. It does *not* execute
yann@1025
   382
in parallel (there is not much to gain). When speaking of // jobs, we are
yann@1025
   383
refering to the number of // jobs when making the *components*. That is, we
yann@1025
   384
speak of the number of // jobs used to build gcc, glibc, and so on...
yann@1025
   385
yann@1493
   386
Tools wrapper |
yann@1493
   387
--------------+
yann@1493
   388
yann@1493
   389
Starting with gcc-4.3 come two new dependencies: GMP and MPFR. With gcc-4.4,
yann@1493
   390
come three new ones: GMP, PPL and CLooG/ppl. These are libraries that enable
yann@1493
   391
advanced features to gcc. Additionally, some of the libraries can be used by
yann@1493
   392
binutils and gdb. Unfortunately, not all systems on which crosstool-NG runs
yann@1493
   393
have all of those libraries. And for those that do, the versions of those
yann@1493
   394
libraries may be older than the version required by gcc.
yann@1493
   395
yann@1493
   396
This is why crosstool-NG builds its own set of libraries as part of the
yann@1493
   397
toolchain.
yann@1493
   398
yann@1493
   399
The libraries are built as shared libraries, because building them as static
yann@1493
   400
libraries has some short-comings. This poses no problem at build time, as
yann@1493
   401
crosstool-NG correctly points gcc (and binutiols and gdb) to the correct
yann@1493
   402
place where our own version of the libraries are installed. But it poses
yann@1493
   403
a problem when gcc et al. are run: the place where the libraries are is most
yann@1493
   404
probably not known to the host dynamic linker. Still worse, if the host system
yann@1493
   405
has its own versions, then ld.so would load the wrong library!
yann@1493
   406
yann@1493
   407
So we have to force the dynamic linker to load the correct version. We do this
yann@1493
   408
by using the LD_LIBRARY_PATH variable, that informs the dynamic linker where
yann@1493
   409
to look for shared libraries prior to searching its standard places. But we
yann@1493
   410
can't impose that burden on all the system (because it'd be a nightmare to
yann@1493
   411
configure, and because two tolchains on the same system may use different
yann@1493
   412
versions of the libraries); so we have to do it on a per-toolchain basis.
yann@1493
   413
yann@1493
   414
So we rename all binaries of the toolchain (by adding a dot '.' as their first
yann@1493
   415
character), and add a small program, the so-called "tools wrapper", that
yann@1493
   416
correctly sets LD_LIBRARY_PATH prior to running the real tool.
yann@1493
   417
yann@1493
   418
First, the wrapper was written as a POSIX-compliant shell script. That shell
yann@1493
   419
script is very simple, if not trivial, and works great. The only drawback is
yann@1493
   420
that it does not work on host systems that lack a shell, for example the
yann@1493
   421
MingW32 environment. To solve the issue, the wrapper has been re-written in C,
yann@1493
   422
and compiled at build time. This C wrapper is much more complex than the shell
yann@1493
   423
script, and although it sems to be working, it's been only lightly tested.
yann@1493
   424
Some of the expected short-comings with this C wrapper are;
yann@1493
   425
 - multi-byte file names may not be handled correctly
yann@1493
   426
 - it's really big for what it does
yann@1493
   427
yann@1493
   428
So, the default wrapper installed with your toolchain is the shell script.
yann@1493
   429
If you know that your system is missing a shell, then you shall use the C
yann@1493
   430
wrapper (and report back whether it works, or does not work, for you).
yann@1493
   431
yann@335
   432
yann@227
   433
_______________________
yann@227
   434
                      /
yann@227
   435
Using the toolchain  /
yann@227
   436
____________________/
yann@227
   437
yann@227
   438
Using the toolchain is as simple as adding the toolchain's bin directory in
yann@227
   439
your PATH, such as:
yann@227
   440
  export PATH="${PATH}:/your/toolchain/path/bin"
yann@227
   441
yann@335
   442
and then using the target tuple to tell the build systems to use your
yann@227
   443
toolchain:
yann@335
   444
  ./configure --target=your-target-tuple
yann@294
   445
or
yann@335
   446
  make CC=your-target-tuple-gcc
yann@294
   447
or
yann@335
   448
  make CROSS_COMPILE=your-target-tuple-
yann@294
   449
and so on...
yann@227
   450
yann@476
   451
It is strongly advised not to use the toolchain sys-root directory as an
yann@620
   452
install directory for your programs/packages. If you do so, you will not be
yann@476
   453
able to use your toolchain for another project. It is even strongly advised
yann@476
   454
that your toolchain is chmod-ed to read-only once successfully build, so that
yann@620
   455
you don't go polluting your toolchain with your programs/packages' files.
yann@476
   456
yann@476
   457
Thus, when you build a program/package, install it in a separate directory,
yann@476
   458
eg. /your/root. This directory is the /image/ of what would be in the root file
yann@620
   459
system of your target, and will contain all that your programs/packages have
yann@476
   460
installed.
yann@476
   461
Yann@1405
   462
The 'populate' script |
Yann@1405
   463
----------------------+
Yann@1405
   464
yann@227
   465
When your root directory is ready, it is still missing some important bits: the
yann@227
   466
toolchain's libraries. To populate your root directory with those libs, just
yann@227
   467
run:
yann@335
   468
  your-target-tuple-populate -s /your/root -d /your/root-populated
yann@227
   469
yann@227
   470
This will copy /your/root into /your/root-populated, and put the needed and only
yann@227
   471
the needed libraries there. Thus you don't polute /your/root with any cruft that
yann@227
   472
would no longer be needed should you have to remove stuff. /your/root always
yann@227
   473
contains only those things you install in it.
yann@227
   474
yann@227
   475
You can then use /your/root-populated to build up your file system image, a
yann@227
   476
tarball, or to NFS-mount it from your target, or whatever you need.
yann@227
   477
Yann@1405
   478
The populate script accepts the following options:
yann@294
   479
Yann@1405
   480
 -s src_dir
Yann@1405
   481
    Use 'src_dir' as the un-populated root directory.
yann@294
   482
Yann@1405
   483
 -d dst_dir
Yann@1405
   484
    Put the populated root directory in 'dst_dir'.
Yann@1405
   485
Yann@1405
   486
 -l lib1 [...]
Yann@1405
   487
    Always add specified libraries.
Yann@1405
   488
Yann@1405
   489
 -L file
Yann@1405
   490
    Always add libraries listed in 'file'.
yann@294
   491
yann@294
   492
 -f
Yann@1405
   493
    Remove 'dst_dir' if it previously existed; continue even if any library
Yann@1405
   494
    specified with -l or -L is missing.
yann@294
   495
yann@294
   496
 -v
yann@294
   497
    Be verbose, and tell what's going on (you can see exactly where libs are
yann@294
   498
    coming from).
yann@294
   499
yann@294
   500
 -h
Yann@1405
   501
    Print the help.
Yann@1405
   502
Yann@1405
   503
See 'your-target-tuple-populate -h' for more information on the options.
yann@294
   504
Yann@1406
   505
Here is how populate works:
Yann@1406
   506
Yann@1406
   507
  1) performs some sanity checks:
Yann@1406
   508
     - src_dir and dst_dir are specified
Yann@1406
   509
     - src_dir exists
Yann@1406
   510
     - unless forced, dst_dir does not exist
Yann@1406
   511
     - src_dir != dst_dir
Yann@1406
   512
Yann@1406
   513
  2) copy src_dir to dst_dir
Yann@1406
   514
Yann@1406
   515
  3) add forced libraries to dst_dir
Yann@1406
   516
     - build the list from -l and -L options
Yann@1406
   517
     - get forced libraries from the sysroot (see below for heuristics)
Yann@1406
   518
       - abort on the first missing library, unless -f is specified
Yann@1406
   519
Yann@1406
   520
  4) add all missing libraries to dst_dir
Yann@1406
   521
     - scan dst_dir for every ELF files that are 'executable' or
Yann@1406
   522
       'shared object'
Yann@1406
   523
     - list the "NEEDED Shared library" fields
Yann@1406
   524
       - check if the library is already in dst_dir/lib or dst_dir/usr/lib
Yann@1406
   525
       - if not, get the library from the sysroot
Yann@1406
   526
         - if it's in sysroot/lib, copy it to dst_dir/lib
Yann@1406
   527
         - if it's in sysroot/usr/lib, copy it to dst_dir/usr/lib
Yann@1406
   528
         - in both cases, use the SONAME of the library to create the file
Yann@1406
   529
           in dst_dir
Yann@1406
   530
         - if it was not found in the sysroot, this is an error.
Yann@1406
   531
yann@40
   532
___________________
yann@40
   533
                  /
yann@40
   534
Toolchain types  /
yann@40
   535
________________/
yann@40
   536
yann@40
   537
There are four kinds of toolchains you could encounter.
yann@40
   538
yann@40
   539
First off, you must understand the following: when it comes to compilers there
yann@40
   540
are up to four machines involved:
yann@40
   541
  1) the machine configuring the toolchain components: the config machine
yann@40
   542
  2) the machine building the toolchain components:    the build machine
yann@40
   543
  3) the machine running the toolchain:                the host machine
yann@203
   544
  4) the machine the toolchain is generating code for: the target machine
yann@40
   545
yann@40
   546
We can most of the time assume that the config machine and the build machine
yann@40
   547
are the same. Most of the time, this will be true. The only time it isn't
yann@40
   548
is if you're using distributed compilation (such as distcc). Let's forget
yann@40
   549
this for the sake of simplicity.
yann@40
   550
yann@40
   551
So we're left with three machines:
yann@40
   552
 - build
yann@40
   553
 - host
yann@40
   554
 - target
yann@40
   555
yann@40
   556
Any toolchain will involve those three machines. You can be as pretty sure of
yann@40
   557
this as "2 and 2 are 4". Here is how they come into play:
yann@40
   558
yann@40
   559
1) build == host == target
yann@40
   560
    This is a plain native toolchain, targetting the exact same machine as the
yann@40
   561
    one it is built on, and running again on this exact same machine. You have
yann@40
   562
    to build such a toolchain when you want to use an updated component, such
yann@40
   563
    as a newer gcc for example.
yann@197
   564
    crosstool-NG calls it "native".
yann@40
   565
yann@40
   566
2) build == host != target
yann@40
   567
    This is a classic cross-toolchain, which is expected to be run on the same
yann@40
   568
    machine it is compiled on, and generate code to run on a second machine,
yann@40
   569
    the target.
yann@197
   570
    crosstool-NG calls it "cross".
yann@40
   571
yann@40
   572
3) build != host == target
yann@40
   573
    Such a toolchain is also a native toolchain, as it targets the same machine
yann@40
   574
    as it runs on. But it is build on another machine. You want such a
yann@40
   575
    toolchain when porting to a new architecture, or if the build machine is
yann@40
   576
    much faster than the host machine.
yann@197
   577
    crosstool-NG calls it "cross-native".
yann@40
   578
yann@40
   579
4) build != host != target
yann@92
   580
    This one is called a canadian-toolchain (*), and is tricky. The three
yann@40
   581
    machines in play are different. You might want such a toolchain if you
yann@40
   582
    have a fast build machine, but the users will use it on another machine,
yann@40
   583
    and will produce code to run on a third machine.
yann@197
   584
    crosstool-NG calls it "canadian".
yann@40
   585
yann@197
   586
crosstool-NG can build all these kinds of toolchains (or is aiming at it,
yann@197
   587
anyway!)
yann@40
   588
yann@40
   589
(*) The term Canadian Cross came about because at the time that these issues
yann@40
   590
    were all being hashed out, Canada had three national political parties.
yann@40
   591
    http://en.wikipedia.org/wiki/Cross_compiler
yann@40
   592
yann@1
   593
_____________
yann@1
   594
            /
yann@1
   595
Internals  /
yann@1
   596
__________/
yann@1
   597
yann@92
   598
Internally, crosstool-NG is script-based. To ease usage, the frontend is
yann@92
   599
Makefile-based.
yann@92
   600
yann@92
   601
Makefile front-end |
yann@476
   602
-------------------+
yann@92
   603
yann@203
   604
The entry point to crosstool-NG is the Makefile script "ct-ng". Calling this
yann@203
   605
script with an action will act exactly as if the Makefile was in the current
yann@203
   606
working directory and make was called with the action as rule. Thus:
yann@203
   607
  ct-ng menuconfig
yann@294
   608
yann@203
   609
is equivalent to having the Makefile in CWD, and calling:
yann@203
   610
  make menuconfig
yann@203
   611
yann@203
   612
Having ct-ng as it is avoids copying the Makefile everywhere, and acts as a
yann@203
   613
traditional command.
yann@203
   614
yann@203
   615
ct-ng loads sub- Makefiles from the library directory $(CT_LIB_DIR), as set up
yann@203
   616
at configuration time with ./configure.
yann@203
   617
yann@437
   618
ct-ng also searches for config files, sub-tools, samples, scripts and patches in
yann@203
   619
that library directory.
yann@92
   620
yann@294
   621
Because of a stupid make behavior/bug I was unable to track down, implicit make
yann@294
   622
rules are disabled: installing with --local would triger those rules, and mconf
yann@294
   623
was unbuildable.
yann@294
   624
yann@182
   625
Kconfig parser |
yann@476
   626
---------------+
yann@92
   627
yann@965
   628
The kconfig language is a hacked version, vampirised from the Linux kernel
yann@965
   629
(http://www.kernel.org/), and (heavily) adapted to my needs.
yann@92
   630
yann@1040
   631
The list of the most notable changes (at least the ones I remember) follows:
yann@1040
   632
- the CONFIG_ prefix has been replaced with CT_
yann@1040
   633
- a leading | in prompts is skipped, and subsequent leading spaces are not
yann@1040
   634
  trimmed
yann@1040
   635
- otherwise leading spaces are silently trimmed
yann@1040
   636
yann@203
   637
The kconfig parsers (conf and mconf) are not installed pre-built, but as
yann@203
   638
source files. Thus you can have the directory where crosstool-NG is installed,
yann@203
   639
exported (via NFS or whatever) and have clients with different architectures
yann@203
   640
use the same crosstool-NG installation, and most notably, the same set of
yann@203
   641
patches.
yann@203
   642
yann@381
   643
Architecture-specific |
yann@476
   644
----------------------+
yann@381
   645
yann@628
   646
Note: this chapter is not really well written, and might thus be a little bit
yann@628
   647
complex to understand. To get a better grasp of what an architecture is, the
yann@628
   648
reader is kindly encouraged to look at the "arch/" sub-directory, and to the
yann@628
   649
existing architectures to see how things are laid out.
yann@628
   650
yann@381
   651
An architecture is defined by:
yann@381
   652
yann@381
   653
 - a human-readable name, in lower case letters, with numbers as appropriate.
yann@628
   654
   The underscore is allowed; space and special characters are not.
yann@628
   655
     Eg.: arm, x86_64
yann@903
   656
 - a file in "config/arch/", named after the architecture's name, and suffixed
yann@903
   657
   with ".in".
yann@903
   658
     Eg.: config/arch/arm.in
yann@903
   659
 - a file in "scripts/build/arch/", named after the architecture's name, and
yann@903
   660
   suffixed with ".sh".
yann@903
   661
     Eg.: scripts/build/arch/arm.sh
yann@628
   662
yann@903
   663
The architecture's ".in" file API:
yann@628
   664
 > the config option "ARCH_%arch%" (where %arch% is to be replaced with the
yann@628
   665
   actual architecture name).
yann@628
   666
   That config option must have *neither* a type, *nor* a prompt! Also, it can
yann@628
   667
   *not* depend on any other config option (EXPERIMENTAL is managed as above).
yann@628
   668
     Eg.:
yann@628
   669
       config ARCH_arm
yann@630
   670
   + mandatory:
yann@702
   671
       defines a (terse) help entry for this architecture:
yann@630
   672
       Eg.:
yann@630
   673
         config ARCH_arm
yann@630
   674
           help
yann@630
   675
             The ARM architecture.
yann@628
   676
   + optional:
yann@628
   677
       selects adequate associated config options.
yann@1038
   678
       Note: 64-bit architectures *shall* select ARCH_64
yann@628
   679
       Eg.:
yann@628
   680
         config ARCH_arm
yann@628
   681
           select ARCH_SUPPORTS_BOTH_ENDIAN
yann@628
   682
           select ARCH_DEFAULT_LE
yann@630
   683
           help
yann@630
   684
             The ARM architecture.
yann@1038
   685
       Eg.:
yann@1038
   686
         config ARCH_x86_64
yann@1038
   687
            select ARCH_64
yann@1038
   688
            help
yann@1038
   689
              The x86_64 architecture.
yann@628
   690
yann@628
   691
 > other target-specific options, at your discretion. Note however that to
yann@628
   692
   avoid name-clashing, such options shall be prefixed with "ARCH_%arch%",
yann@628
   693
   where %arch% is again replaced by the actual architecture name.
yann@628
   694
   (Note: due to historical reasons, and lack of time to clean up the code,
yann@628
   695
    I may have left some config options that do not completely conform to
yann@628
   696
    this, as the architecture name was written all upper case. However, the
yann@628
   697
    prefix is unique among architectures, and does not cause harm).
yann@381
   698
yann@903
   699
The architecture's ".sh" file API:
yann@965
   700
 > the function "CT_DoArchTupleValues"
yann@381
   701
   + parameters: none
yann@381
   702
   + environment:
yann@901
   703
     - all variables from the ".config" file,
yann@901
   704
     - the two variables "target_endian_eb" and "target_endian_el" which are
yann@901
   705
       the endianness suffixes
yann@381
   706
   + return value: 0 upon success, !0 upon failure
yann@381
   707
   + provides:
yann@391
   708
     - mandatory
yann@383
   709
     - the environment variable CT_TARGET_ARCH
yann@389
   710
     - contains:
yann@389
   711
       the architecture part of the target tuple.
yann@389
   712
       Eg.: "armeb" for big endian ARM
yann@389
   713
            "i386" for an i386
yann@389
   714
   + provides:
yann@391
   715
     - optional
yann@389
   716
     - the environment variable CT_TARGET_SYS
yann@456
   717
     - contains:
yann@383
   718
       the sytem part of the target tuple.
yann@383
   719
       Eg.: "gnu" for glibc on most architectures
yann@383
   720
            "gnueabi" for glibc on an ARM EABI
yann@383
   721
     - defaults to:
yann@383
   722
       - for glibc-based toolchain: "gnu"
yann@383
   723
       - for uClibc-based toolchain: "uclibc"
yann@383
   724
   + provides:
yann@383
   725
     - optional
yann@391
   726
     - the environment variable CT_KERNEL_ARCH
yann@383
   727
     - contains:
yann@391
   728
       the architecture name as understandable by the Linux kernel build
yann@391
   729
       system.
yann@391
   730
       Eg.: "arm" for an ARM
yann@391
   731
            "powerpc" for a PowerPC
yann@391
   732
            "i386" for an x86
yann@383
   733
     - defaults to:
yann@391
   734
       ${CT_ARCH}
yann@391
   735
   + provides:
yann@391
   736
     - optional
yann@767
   737
     - the environment variables to configure the cross-gcc (defaults)
yann@767
   738
       - CT_ARCH_WITH_ARCH    : the gcc ./configure switch to select architecture level         ( "--with-arch=${CT_ARCH_ARCH}"   )
yann@767
   739
       - CT_ARCH_WITH_ABI     : the gcc ./configure switch to select ABI level                  ( "--with-abi=${CT_ARCH_ABI}"     )
yann@767
   740
       - CT_ARCH_WITH_CPU     : the gcc ./configure switch to select CPU instruction set        ( "--with-cpu=${CT_ARCH_CPU}"     )
yann@767
   741
       - CT_ARCH_WITH_TUNE    : the gcc ./configure switch to select scheduling                 ( "--with-tune=${CT_ARCH_TUNE}"   )
yann@767
   742
       - CT_ARCH_WITH_FPU     : the gcc ./configure switch to select FPU type                   ( "--with-fpu=${CT_ARCH_FPU}"     )
yann@767
   743
       - CT_ARCH_WITH_FLOAT   : the gcc ./configure switch to select floating point arithmetics ( "--with-float=soft" or /empty/  )
yann@391
   744
   + provides:
yann@391
   745
     - optional
yann@767
   746
     - the environment variables to pass to the cross-gcc to build target binaries (defaults)
yann@391
   747
       - CT_ARCH_ARCH_CFLAG   : the gcc switch to select architecture level                     ( "-march=${CT_ARCH_ARCH}"            )
yann@456
   748
       - CT_ARCH_ABI_CFLAG    : the gcc switch to select ABI level                              ( "-mabi=${CT_ARCH_ABI}"              )
yann@391
   749
       - CT_ARCH_CPU_CFLAG    : the gcc switch to select CPU instruction set                    ( "-mcpu=${CT_ARCH_CPU}"              )
yann@391
   750
       - CT_ARCH_TUNE_CFLAG   : the gcc switch to select scheduling                             ( "-mtune=${CT_ARCH_TUNE}"            )
yann@391
   751
       - CT_ARCH_FPU_CFLAG    : the gcc switch to select FPU type                               ( "-mfpu=${CT_ARCH_FPU}"              )
yann@391
   752
       - CT_ARCH_FLOAT_CFLAG  : the gcc switch to choose floating point arithmetics             ( "-msoft-float" or /empty/           )
yann@391
   753
       - CT_ARCH_ENDIAN_CFLAG : the gcc switch to choose big or little endian                   ( "-mbig-endian" or "-mlittle-endian" )
yann@391
   754
     - default to:
yann@391
   755
       see above.
yann@767
   756
   + provides:
yann@767
   757
     - optional
yann@767
   758
     - the environement variables to configure the core and final compiler, specific to this architecture:
yann@767
   759
       - CT_ARCH_CC_CORE_EXTRA_CONFIG   : additional, architecture specific core gcc ./configure flags
yann@767
   760
       - CT_ARCH_CC_EXTRA_CONFIG        : additional, architecture specific final gcc ./configure flags
yann@767
   761
     - default to:
yann@767
   762
       - all empty
yann@767
   763
   + provides:
yann@767
   764
     - optional
yann@767
   765
     - the architecture-specific CFLAGS and LDFLAGS:
yann@767
   766
       - CT_ARCH_TARGET_CLFAGS
yann@767
   767
       - CT_ARCH_TARGET_LDFLAGS
yann@767
   768
     - default to:
yann@767
   769
       - all empty
yann@628
   770
yann@903
   771
You can have a look at "config/arch/arm.in" and "scripts/build/arch/arm.sh" for
yann@903
   772
a quite complete example of what an actual architecture description looks like.
yann@901
   773
yann@890
   774
Kernel specific |
yann@890
   775
----------------+
yann@890
   776
yann@890
   777
A kernel is defined by:
yann@890
   778
yann@890
   779
 - a human-readable name, in lower case letters, with numbers as appropriate.
yann@890
   780
   The underscore is allowed; space and special characters are not (although
yann@890
   781
   they are internally replaced with underscores.
yann@890
   782
     Eg.: linux, bare-metal
yann@890
   783
 - a file in "config/kernel/", named after the kernel name, and suffixed with
yann@890
   784
   ".in".
yann@890
   785
     Eg.: config/kernel/linux.in, config/kernel/bare-metal.in
yann@901
   786
 - a file in "scripts/build/kernel/", named after the kernel name, and suffixed
yann@901
   787
   with ".sh".
yann@901
   788
     Eg.: scripts/build/kernel/linux.sh, scripts/build/kernel/bare-metal.sh
yann@890
   789
yann@890
   790
The kernel's ".in" file must contain:
yann@890
   791
 > an optional lines containing exactly "# EXPERIMENTAL", starting on the
yann@890
   792
   first column, and without any following space or other character.
yann@890
   793
   If this line is present, then this kernel is considered EXPERIMENTAL,
yann@890
   794
   and correct dependency on EXPERIMENTAL will be set.
yann@901
   795
yann@890
   796
 > the config option "KERNEL_%kernel_name%" (where %kernel_name% is to be
yann@890
   797
   replaced with the actual kernel name, with all special characters and
yann@890
   798
   spaces replaced by underscores).
yann@890
   799
   That config option must have *neither* a type, *nor* a prompt! Also, it can
yann@890
   800
   *not* depends on EXPERIMENTAL.
yann@890
   801
     Eg.: KERNEL_linux, KERNEL_bare_metal
yann@890
   802
   + mandatory:
yann@890
   803
       defines a (terse) help entry for this kernel.
yann@890
   804
       Eg.:
yann@890
   805
         config KERNEL_bare_metal
yann@890
   806
           help
yann@890
   807
             Build a compiler for use without any kernel.
yann@890
   808
   + optional:
yann@890
   809
       selects adequate associated config options.
yann@890
   810
       Eg.:
yann@890
   811
         config KERNEL_bare_metal
yann@890
   812
           select BARE_METAL
yann@890
   813
           help
yann@890
   814
             Build a compiler for use without any kernel.
yann@890
   815
yann@890
   816
 > other kernel specific options, at your discretion. Note however that, to
yann@890
   817
   avoid name-clashing, such options should be prefixed with
yann@890
   818
   "KERNEL_%kernel_name%", where %kernel_name% is again tp be replaced with
yann@890
   819
   the actual kernel name.
yann@890
   820
   (Note: due to historical reasons, and lack of time to clean up the code,
yann@890
   821
    I may have left some config options that do not completely conform to
yann@890
   822
    this, as the kernel name was written all upper case. However, the prefix
yann@890
   823
    is unique among kernels, and does not cause harm).
yann@890
   824
yann@901
   825
The kernel's ".sh" file API:
yann@901
   826
 > is a bash script fragment
yann@901
   827
yann@965
   828
 > defines the function CT_DoKernelTupleValues
yann@965
   829
   + see the architecture's CT_DoArchTupleValues, except for:
yann@965
   830
   + set the environment variable CT_TARGET_KERNEL, the kernel part of the
yann@965
   831
     target tuple
yann@965
   832
   + return value: ignored
yann@965
   833
yann@901
   834
 > defines the function "do_kernel_get":
yann@901
   835
   + parameters: none
yann@901
   836
   + environment:
yann@901
   837
      - all variables from the ".config" file.
yann@901
   838
   + return value: 0 for success, !0 for failure.
yann@901
   839
   + behavior: download the kernel's sources, and store the tarball into
yann@901
   840
     "${CT_TARBALLS_DIR}". To this end, a functions is available, that
yann@901
   841
     abstracts downloading tarballs:
yann@901
   842
     - CT_DoGet <tarball_base_name> <URL1 [URL...]>
yann@901
   843
       Eg.: CT_DoGet linux-2.6.26.5 ftp://ftp.kernel.org/pub/linux/kernel/v2.6
yann@901
   844
     Note: retrieving sources from svn, cvs, git and the likes is not supported
yann@901
   845
     by CT_DoGet. You'll have to do this by hand, as it is done for eglibc in
yann@901
   846
     "scripts/build/libc/eglibc.sh"
yann@901
   847
yann@901
   848
 > defines the function "do_kernel_extract":
yann@901
   849
   + parameters: none
yann@901
   850
   + environment:
yann@901
   851
      - all variables from the ".config" file,
yann@901
   852
   + return value: 0 for success, !0 for failure.
yann@901
   853
   + behavior: extract the kernel's tarball into "${CT_SRC_DIR}", and apply
yann@901
   854
     required patches. To this end, a function is available, that abstracts
yann@901
   855
     extracting tarballs:
yann@901
   856
     - CT_ExtractAndPatch <tarball_base_name>
yann@901
   857
       Eg.: CT_ExtractAndPatch linux-2.6.26.5
yann@901
   858
yann@901
   859
 > defines the function "do_kernel_headers":
yann@901
   860
   + parameters: none
yann@901
   861
   + environment:
yann@901
   862
      - all variables from the ".config" file,
yann@901
   863
   + return value: 0 for success, !0 for failure.
yann@901
   864
   + behavior: install the kernel headers (if any) in "${CT_SYSROOT_DIR}/usr/include"
yann@901
   865
yann@901
   866
 > defines any kernel-specific helper functions
yann@901
   867
   These functions, if any, must be prefixed with "do_kernel_%CT_KERNEL%_",
yann@901
   868
   where '%CT_KERNEL%' is to be replaced with the actual kernel name, to avoid
yann@901
   869
   any name-clashing.
yann@901
   870
yann@901
   871
You can have a look at "config/kernel/linux.in" and "scripts/build/kernel/linux.sh"
yann@903
   872
as an example of what a complex kernel description looks like.
yann@901
   873
yann@620
   874
Adding a new version of a component |
yann@476
   875
------------------------------------+
yann@476
   876
yann@476
   877
When a new component, such as the Linux kernel, gcc or any other is released,
yann@476
   878
adding the new version to crosstool-NG is quite easy. There is a script that
yann@476
   879
will do all that for you:
yann@1095
   880
  scripts/addToolVersion.sh
yann@476
   881
yann@476
   882
Run it with no option to get some help.
yann@381
   883
yann@203
   884
Build scripts |
yann@476
   885
--------------+
yann@203
   886
yann@203
   887
To Be Written later...