docs/5 - Using the toolchain.txt
changeset 2764 986e90e1ca27
parent 2753 710fa859bfe6
child 2908 dcdb309b7967
     1.1 --- a/docs/5 - Using the toolchain.txt	Wed Nov 16 16:06:42 2011 -0500
     1.2 +++ b/docs/5 - Using the toolchain.txt	Wed Nov 16 17:36:17 2011 -0500
     1.3 @@ -25,16 +25,139 @@
     1.4  not the host of the toolchain; and 'build' refers to the machine where
     1.5  you build your program, that is the host of the toolchain.)
     1.6  
     1.7 +
     1.8 +Assembling a root filesystem  /
     1.9 +_____________________________/
    1.10 +
    1.11 +
    1.12 +Assembling a root filesystem for a target device requires the successive
    1.13 +building of a set of software packages for the target architecture. Building
    1.14 +a package potentially requires artifacts which were generated as part of an
    1.15 +earlier build. Note that not all artifacts which are installed as part of a
    1.16 +package are desirable on a target's root filesystem (e.g. man/info files,
    1.17 +include files, etc.). Therefore we must distinguish between a 'staging'
    1.18 +directory and a 'rootfs' directory.
    1.19 +
    1.20 +A 'staging' directory is a location into which we install all the build
    1.21 +artifacts. We can then point future builds to this location so they can find
    1.22 +the appropriate header and library files. A 'rootfs' directory is a location
    1.23 +into which we place only the files we want to have on our target.
    1.24 +
    1.25 +There are four schools of thought here:
    1.26 +
    1.27 +1) Install directly into the sysroot of the toolchain.
    1.28 +
    1.29 +   By default (i.e. if you don't pass any arguments to the tools which
    1.30 +   would change this behaviour) the toolchain that is built by
    1.31 +   crosstool-NG will only look in its toolchain directories for system
    1.32 +   header and library files:
    1.33 +
    1.34 +#include "..." search starts here:
    1.35 +#include <...> search starts here:
    1.36 +<ct-ng install path>/lib/gcc/<host tuple>/4.5.2/include
    1.37 +<ct-ng install path>/lib/gcc/<host tuple>/4.5.2/include-fixed
    1.38 +<ct-ng install path>/lib/gcc/<host tuple>/4.5.2/../../../../<host tuple>/include
    1.39 +<ct-ng install path>/<host tuple>/sysroot/usr/include
    1.40 +
    1.41 +   In other words, the compiler will automagically find headers and
    1.42 +   libraries without extra flags if they are installed under the
    1.43 +   toolchain's sysroot directory.
    1.44 +
    1.45 +   However, this is bad because the toolchain gets poluted, and can
    1.46 +   not be re-used.
    1.47 +
    1.48 +   $ ./configure --build=<build tuple> --host=<host tuple> \
    1.49 +         --prefix=/usr --enable-foo-bar...
    1.50 +   $ make
    1.51 +   $ make DESTDIR=/<ct-ng install path>/<host tuple>/sysroot install
    1.52 +
    1.53 +2) Copy the toolchain's sysroot to the 'staging' area.
    1.54 +
    1.55 +   If you start off by copying the toolchain's sysroot directory to your
    1.56 +   staging area, you can simply proceed to install all your packages'
    1.57 +   artifacts to the same staging area. You then only need to specify a
    1.58 +   '--sysroot=<staging area>' option to the compiler of any subsequent
    1.59 +   builds and all your required header and library files will be found/used.
    1.60 +
    1.61 +   This is a viable option, but requires the user to always specify CFLAGS
    1.62 +   in order to include --sysroot=<staging area>, or requires the use of a
    1.63 +   wrapper to a few select tools (gcc, ld...) to pass this flag.
    1.64 +
    1.65 +   Instead of polluting the toolchain's sysroot you are copying its contents
    1.66 +   to a new location and polluting the contents in that new location. By
    1.67 +   specifying the --sysroot option you're effectively abandoning the default
    1.68 +   sysroot in favour of your own.
    1.69 +
    1.70 +   Incidentally this is what buildroot does using a wrapper, when using an
    1.71 +   external toolchain.
    1.72 +
    1.73 +   $ cp -a $(<host tuple>-gcc --your-cflags-except-sysroot -print-sysroot) \
    1.74 +         /path/to/staging
    1.75 +   $ ./configure --build=<build tuple> --host=<host tuple>          \
    1.76 +                 --prefix=/usr --enable-foo-bar...                  \
    1.77 +                 CC="<host tuple>-gcc --syroot=/path/to/staging"    \
    1.78 +                 CXX="<host tuple>-g++ --sysroot=/path/to/staging"  \
    1.79 +                 LD="<host tuple>-ld --sysroot=/path/to/staging"    \
    1.80 +                 AND_SO_ON="tuple-andsoon --sysroot=/path/to/staging"
    1.81 +   $ make
    1.82 +   $ make DESTDIR=/path/to/staging install
    1.83 +
    1.84 +3) Use separate staging and sysroot directories.
    1.85 +
    1.86 +   In this scenario you use a staging area to install programs, but you do
    1.87 +   not pre-fill that staging area with the toolchain's sysroot. In this case
    1.88 +   the compiler will find the system includes and libraries in its sysroot
    1.89 +   area but you have to pass appropriate CPPFLAGS and LDFLAGS to tell it
    1.90 +   where to find your headers and libraries from your staging area (or use
    1.91 +   a wrapper).
    1.92 +
    1.93 +   $ ./configure --build=<build tuple> --host=<host tuple>          \
    1.94 +                 --prefix=/usr --enable-foo-bar...                  \
    1.95 +                 CPPFLAGS="-I/path/to/staging/usr/include"          \
    1.96 +                 LDFLAGS="-L/path/to/staging/lib -L/path/to/staging/usr/lib"
    1.97 +   $ make
    1.98 +   $ make DESTDIR=/path/to/staging install
    1.99 +
   1.100 +4) A mix of 2) and 3), using carefully crafted union mounts.
   1.101 +
   1.102 +   The staging area is a union mount of:
   1.103 +      - the sysroot as a read-only branch
   1.104 +      - the real staging area as a read-write branch
   1.105 +   This also requires passing --sysroot to point to the union mount, but has
   1.106 +   other advantages, such as allowing per-package staging, and a few more
   1.107 +   obscure pros. It also has its disadvantages, as it potentially requires
   1.108 +   non-root users to create union mounts. Additionally, union mounts are not
   1.109 +   yet mainstream in the Linux kernel, so it requires patching. There is a
   1.110 +   FUSE-based unionfs implementation, but development is almost stalled,
   1.111 +   and there are a few gotchas...
   1.112 +
   1.113 +   $ (good luck!)
   1.114 +
   1.115 +
   1.116  It is strongly advised not to use the toolchain sysroot directory as an
   1.117 -install directory for your programs/packages. If you do so, you will not be
   1.118 -able to use your toolchain for another project. It is even strongly advised
   1.119 -that your toolchain is chmod-ed to read-only once successfully build, so that
   1.120 -you don't go polluting your toolchain with your programs/packages' files.
   1.121 +install directory (i.e. option 1) for your programs/packages. If you do so,
   1.122 +you will not be able to use your toolchain for another project. It is even
   1.123 +strongly advised that your toolchain is chmod-ed to read-only once
   1.124 +successfully install, so that you don't go polluting your toolchain with
   1.125 +your programs'/packages' files. This can be achieved by selecting the
   1.126 +"Render the toolchain read-only" from crosstool-NG's "Paths and misc options"
   1.127 +configuration page.
   1.128  
   1.129 -Thus, when you build a program/package, install it in a separate directory,
   1.130 -eg. /your/root. This directory is the /image/ of what would be in the root file
   1.131 -system of your target, and will contain all that your programs/packages have
   1.132 -installed.
   1.133 +Thus, when you build a program/package, install it in a separate, staging,
   1.134 +directory and let the cross-toolchain continue to use its own, pristine,
   1.135 +sysroot directory.
   1.136 +
   1.137 +When you are done building and want to assemble your rootfs you could simply
   1.138 +take the full contents of your staging directory and use the 'populate'
   1.139 +script to add in the necessary files from the sysroot. However, the staging
   1.140 +area you have created will include lots of build artifacts that you won't
   1.141 +necessarily want/need on your target. For example: static libraries, header
   1.142 +files, linking helper files, man/info pages. You'll also need to add various
   1.143 +configuration files, scripts, and directories to the rootfs so it will boot.
   1.144 +
   1.145 +Therefore you'll probably end up creating a separate rootfs directory which
   1.146 +you will populate from the staging area, necessary extras, and then use
   1.147 +crosstool-NG's populate script to add the necessary sysroot libraries.
   1.148  
   1.149  
   1.150  The 'populate' script |