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