docs: Add strategies for assembling root filesystems.
Expand the documentation for using a crosstool-NG-generated toolchain for
building a root filesystem for a target device.
Signed-off-by: "Trevor Woerner" <twoerner@gmail.com>
yann.morin.1998@anciens.enib.fr: some eye-candy]
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
1.1 --- a/docs/5 - Using the toolchain.txt Mon Nov 07 21:40:28 2011 +0100
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 |