docs/5 - Using the toolchain.txt
author "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
Mon Apr 16 15:25:36 2012 +0200 (2012-04-16)
changeset 2941 13e40098fffc
parent 2764 986e90e1ca27
permissions -rw-r--r--
cc/gcc: update Linaro GCC revisions to 2012.04

Update Linaro GCC with the latest available revisions.

The 4.7 revision is also released, but the infrastructure is not yet ready for
it in CT-NG.

Signed-off-by: "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
yann@2076
     1
File.........: 5 - Using the toolchain.txt
yann@2908
     2
Copyright....: (C) 2010 Yann E. MORIN <yann.morin.1998@free.fr>
yann@2076
     3
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5
yann@2076
     4
yann@2076
     5
yann@2076
     6
Using the toolchain  /
yann@2076
     7
____________________/
yann@2076
     8
yann@2076
     9
yann@2076
    10
Using the toolchain is as simple as adding the toolchain's bin directory in
yann@2076
    11
your PATH, such as:
yann@2076
    12
  export PATH="${PATH}:/your/toolchain/path/bin"
yann@2076
    13
twoerner@2753
    14
and then using the '--host' tuple to tell the build systems to use your
twoerner@2753
    15
toolchain (if the software package uses the autotools system you should
twoerner@2753
    16
also pass --build, for completeness):
twoerner@2753
    17
  ./configure --host=your-host-tuple --build=your-build-tuple
yann@2076
    18
or
twoerner@2753
    19
  make CC=your-host-tuple-gcc
yann@2076
    20
or
twoerner@2753
    21
  make CROSS_COMPILE=your-host-tuple-
yann@2076
    22
and so on...
yann@2076
    23
twoerner@2753
    24
(Note: in the above example, 'host' refers to the host of your program,
twoerner@2753
    25
not the host of the toolchain; and 'build' refers to the machine where
twoerner@2753
    26
you build your program, that is the host of the toolchain.)
twoerner@2753
    27
twoerner@2764
    28
twoerner@2764
    29
Assembling a root filesystem  /
twoerner@2764
    30
_____________________________/
twoerner@2764
    31
twoerner@2764
    32
twoerner@2764
    33
Assembling a root filesystem for a target device requires the successive
twoerner@2764
    34
building of a set of software packages for the target architecture. Building
twoerner@2764
    35
a package potentially requires artifacts which were generated as part of an
twoerner@2764
    36
earlier build. Note that not all artifacts which are installed as part of a
twoerner@2764
    37
package are desirable on a target's root filesystem (e.g. man/info files,
twoerner@2764
    38
include files, etc.). Therefore we must distinguish between a 'staging'
twoerner@2764
    39
directory and a 'rootfs' directory.
twoerner@2764
    40
twoerner@2764
    41
A 'staging' directory is a location into which we install all the build
twoerner@2764
    42
artifacts. We can then point future builds to this location so they can find
twoerner@2764
    43
the appropriate header and library files. A 'rootfs' directory is a location
twoerner@2764
    44
into which we place only the files we want to have on our target.
twoerner@2764
    45
twoerner@2764
    46
There are four schools of thought here:
twoerner@2764
    47
twoerner@2764
    48
1) Install directly into the sysroot of the toolchain.
twoerner@2764
    49
twoerner@2764
    50
   By default (i.e. if you don't pass any arguments to the tools which
twoerner@2764
    51
   would change this behaviour) the toolchain that is built by
twoerner@2764
    52
   crosstool-NG will only look in its toolchain directories for system
twoerner@2764
    53
   header and library files:
twoerner@2764
    54
twoerner@2764
    55
#include "..." search starts here:
twoerner@2764
    56
#include <...> search starts here:
twoerner@2764
    57
<ct-ng install path>/lib/gcc/<host tuple>/4.5.2/include
twoerner@2764
    58
<ct-ng install path>/lib/gcc/<host tuple>/4.5.2/include-fixed
twoerner@2764
    59
<ct-ng install path>/lib/gcc/<host tuple>/4.5.2/../../../../<host tuple>/include
twoerner@2764
    60
<ct-ng install path>/<host tuple>/sysroot/usr/include
twoerner@2764
    61
twoerner@2764
    62
   In other words, the compiler will automagically find headers and
twoerner@2764
    63
   libraries without extra flags if they are installed under the
twoerner@2764
    64
   toolchain's sysroot directory.
twoerner@2764
    65
twoerner@2764
    66
   However, this is bad because the toolchain gets poluted, and can
twoerner@2764
    67
   not be re-used.
twoerner@2764
    68
twoerner@2764
    69
   $ ./configure --build=<build tuple> --host=<host tuple> \
twoerner@2764
    70
         --prefix=/usr --enable-foo-bar...
twoerner@2764
    71
   $ make
twoerner@2764
    72
   $ make DESTDIR=/<ct-ng install path>/<host tuple>/sysroot install
twoerner@2764
    73
twoerner@2764
    74
2) Copy the toolchain's sysroot to the 'staging' area.
twoerner@2764
    75
twoerner@2764
    76
   If you start off by copying the toolchain's sysroot directory to your
twoerner@2764
    77
   staging area, you can simply proceed to install all your packages'
twoerner@2764
    78
   artifacts to the same staging area. You then only need to specify a
twoerner@2764
    79
   '--sysroot=<staging area>' option to the compiler of any subsequent
twoerner@2764
    80
   builds and all your required header and library files will be found/used.
twoerner@2764
    81
twoerner@2764
    82
   This is a viable option, but requires the user to always specify CFLAGS
twoerner@2764
    83
   in order to include --sysroot=<staging area>, or requires the use of a
twoerner@2764
    84
   wrapper to a few select tools (gcc, ld...) to pass this flag.
twoerner@2764
    85
twoerner@2764
    86
   Instead of polluting the toolchain's sysroot you are copying its contents
twoerner@2764
    87
   to a new location and polluting the contents in that new location. By
twoerner@2764
    88
   specifying the --sysroot option you're effectively abandoning the default
twoerner@2764
    89
   sysroot in favour of your own.
twoerner@2764
    90
twoerner@2764
    91
   Incidentally this is what buildroot does using a wrapper, when using an
twoerner@2764
    92
   external toolchain.
twoerner@2764
    93
twoerner@2764
    94
   $ cp -a $(<host tuple>-gcc --your-cflags-except-sysroot -print-sysroot) \
twoerner@2764
    95
         /path/to/staging
twoerner@2764
    96
   $ ./configure --build=<build tuple> --host=<host tuple>          \
twoerner@2764
    97
                 --prefix=/usr --enable-foo-bar...                  \
twoerner@2764
    98
                 CC="<host tuple>-gcc --syroot=/path/to/staging"    \
twoerner@2764
    99
                 CXX="<host tuple>-g++ --sysroot=/path/to/staging"  \
twoerner@2764
   100
                 LD="<host tuple>-ld --sysroot=/path/to/staging"    \
twoerner@2764
   101
                 AND_SO_ON="tuple-andsoon --sysroot=/path/to/staging"
twoerner@2764
   102
   $ make
twoerner@2764
   103
   $ make DESTDIR=/path/to/staging install
twoerner@2764
   104
twoerner@2764
   105
3) Use separate staging and sysroot directories.
twoerner@2764
   106
twoerner@2764
   107
   In this scenario you use a staging area to install programs, but you do
twoerner@2764
   108
   not pre-fill that staging area with the toolchain's sysroot. In this case
twoerner@2764
   109
   the compiler will find the system includes and libraries in its sysroot
twoerner@2764
   110
   area but you have to pass appropriate CPPFLAGS and LDFLAGS to tell it
twoerner@2764
   111
   where to find your headers and libraries from your staging area (or use
twoerner@2764
   112
   a wrapper).
twoerner@2764
   113
twoerner@2764
   114
   $ ./configure --build=<build tuple> --host=<host tuple>          \
twoerner@2764
   115
                 --prefix=/usr --enable-foo-bar...                  \
twoerner@2764
   116
                 CPPFLAGS="-I/path/to/staging/usr/include"          \
twoerner@2764
   117
                 LDFLAGS="-L/path/to/staging/lib -L/path/to/staging/usr/lib"
twoerner@2764
   118
   $ make
twoerner@2764
   119
   $ make DESTDIR=/path/to/staging install
twoerner@2764
   120
twoerner@2764
   121
4) A mix of 2) and 3), using carefully crafted union mounts.
twoerner@2764
   122
twoerner@2764
   123
   The staging area is a union mount of:
twoerner@2764
   124
      - the sysroot as a read-only branch
twoerner@2764
   125
      - the real staging area as a read-write branch
twoerner@2764
   126
   This also requires passing --sysroot to point to the union mount, but has
twoerner@2764
   127
   other advantages, such as allowing per-package staging, and a few more
twoerner@2764
   128
   obscure pros. It also has its disadvantages, as it potentially requires
twoerner@2764
   129
   non-root users to create union mounts. Additionally, union mounts are not
twoerner@2764
   130
   yet mainstream in the Linux kernel, so it requires patching. There is a
twoerner@2764
   131
   FUSE-based unionfs implementation, but development is almost stalled,
twoerner@2764
   132
   and there are a few gotchas...
twoerner@2764
   133
twoerner@2764
   134
   $ (good luck!)
twoerner@2764
   135
twoerner@2764
   136
yann@2279
   137
It is strongly advised not to use the toolchain sysroot directory as an
twoerner@2764
   138
install directory (i.e. option 1) for your programs/packages. If you do so,
twoerner@2764
   139
you will not be able to use your toolchain for another project. It is even
twoerner@2764
   140
strongly advised that your toolchain is chmod-ed to read-only once
twoerner@2764
   141
successfully install, so that you don't go polluting your toolchain with
twoerner@2764
   142
your programs'/packages' files. This can be achieved by selecting the
twoerner@2764
   143
"Render the toolchain read-only" from crosstool-NG's "Paths and misc options"
twoerner@2764
   144
configuration page.
yann@2076
   145
twoerner@2764
   146
Thus, when you build a program/package, install it in a separate, staging,
twoerner@2764
   147
directory and let the cross-toolchain continue to use its own, pristine,
twoerner@2764
   148
sysroot directory.
twoerner@2764
   149
twoerner@2764
   150
When you are done building and want to assemble your rootfs you could simply
twoerner@2764
   151
take the full contents of your staging directory and use the 'populate'
twoerner@2764
   152
script to add in the necessary files from the sysroot. However, the staging
twoerner@2764
   153
area you have created will include lots of build artifacts that you won't
twoerner@2764
   154
necessarily want/need on your target. For example: static libraries, header
twoerner@2764
   155
files, linking helper files, man/info pages. You'll also need to add various
twoerner@2764
   156
configuration files, scripts, and directories to the rootfs so it will boot.
twoerner@2764
   157
twoerner@2764
   158
Therefore you'll probably end up creating a separate rootfs directory which
twoerner@2764
   159
you will populate from the staging area, necessary extras, and then use
twoerner@2764
   160
crosstool-NG's populate script to add the necessary sysroot libraries.
yann@2076
   161
yann@2076
   162
yann@2076
   163
The 'populate' script |
yann@2076
   164
----------------------+
yann@2076
   165
yann@2076
   166
When your root directory is ready, it is still missing some important bits: the
yann@2076
   167
toolchain's libraries. To populate your root directory with those libs, just
yann@2076
   168
run:
yann@2076
   169
  your-target-tuple-populate -s /your/root -d /your/root-populated
yann@2076
   170
yann@2076
   171
This will copy /your/root into /your/root-populated, and put the needed and only
antony@2564
   172
the needed libraries there. Thus you don't pollute /your/root with any cruft that
yann@2076
   173
would no longer be needed should you have to remove stuff. /your/root always
yann@2076
   174
contains only those things you install in it.
yann@2076
   175
yann@2076
   176
You can then use /your/root-populated to build up your file system image, a
yann@2076
   177
tarball, or to NFS-mount it from your target, or whatever you need.
yann@2076
   178
yann@2076
   179
The populate script accepts the following options:
yann@2076
   180
yann@2076
   181
 -s src_dir
yann@2076
   182
    Use 'src_dir' as the un-populated root directory.
yann@2076
   183
yann@2076
   184
 -d dst_dir
yann@2076
   185
    Put the populated root directory in 'dst_dir'.
yann@2076
   186
yann@2076
   187
 -l lib1 [...]
yann@2076
   188
    Always add specified libraries.
yann@2076
   189
yann@2076
   190
 -L file
yann@2076
   191
    Always add libraries listed in 'file'.
yann@2076
   192
yann@2076
   193
 -f
yann@2076
   194
    Remove 'dst_dir' if it previously existed; continue even if any library
yann@2076
   195
    specified with -l or -L is missing.
yann@2076
   196
yann@2076
   197
 -v
yann@2076
   198
    Be verbose, and tell what's going on (you can see exactly where libs are
yann@2076
   199
    coming from).
yann@2076
   200
yann@2076
   201
 -h
yann@2076
   202
    Print the help.
yann@2076
   203
yann@2076
   204
See 'your-target-tuple-populate -h' for more information on the options.
yann@2076
   205
yann@2076
   206
Here is how populate works:
yann@2076
   207
yann@2076
   208
  1) performs some sanity checks:
yann@2076
   209
     - src_dir and dst_dir are specified
yann@2076
   210
     - src_dir exists
yann@2076
   211
     - unless forced, dst_dir does not exist
yann@2076
   212
     - src_dir != dst_dir
yann@2076
   213
yann@2076
   214
  2) copy src_dir to dst_dir
yann@2076
   215
yann@2076
   216
  3) add forced libraries to dst_dir
yann@2076
   217
     - build the list from -l and -L options
yann@2076
   218
     - get forced libraries from the sysroot (see below for heuristics)
yann@2076
   219
       - abort on the first missing library, unless -f is specified
yann@2076
   220
yann@2076
   221
  4) add all missing libraries to dst_dir
yann@2076
   222
     - scan dst_dir for every ELF files that are 'executable' or
yann@2076
   223
       'shared object'
yann@2076
   224
     - list the "NEEDED Shared library" fields
yann@2076
   225
       - check if the library is already in dst_dir/lib or dst_dir/usr/lib
yann@2076
   226
       - if not, get the library from the sysroot
yann@2076
   227
         - if it's in sysroot/lib, copy it to dst_dir/lib
yann@2076
   228
         - if it's in sysroot/usr/lib, copy it to dst_dir/usr/lib
yann@2076
   229
         - in both cases, use the SONAME of the library to create the file
yann@2076
   230
           in dst_dir
yann@2076
   231
         - if it was not found in the sysroot, this is an error.