diff options
Diffstat (limited to 'docs/5 - Using the toolchain.txt')
-rw-r--r-- | docs/5 - Using the toolchain.txt | 231 |
1 files changed, 0 insertions, 231 deletions
diff --git a/docs/5 - Using the toolchain.txt b/docs/5 - Using the toolchain.txt deleted file mode 100644 index 1b11b49e..00000000 --- a/docs/5 - Using the toolchain.txt +++ /dev/null @@ -1,231 +0,0 @@ -File.........: 5 - Using the toolchain.txt -Copyright....: (C) 2010 Yann E. MORIN <yann.morin.1998@free.fr> -License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5 - - -Using the toolchain / -____________________/ - - -Using the toolchain is as simple as adding the toolchain's bin directory in -your PATH, such as: - export PATH="${PATH}:/your/toolchain/path/bin" - -and then using the '--host' tuple to tell the build systems to use your -toolchain (if the software package uses the autotools system you should -also pass --build, for completeness): - ./configure --host=your-host-tuple --build=your-build-tuple -or - make CC=your-host-tuple-gcc -or - make CROSS_COMPILE=your-host-tuple- -and so on... - -(Note: in the above example, 'host' refers to the host of your program, -not the host of the toolchain; and 'build' refers to the machine where -you build your program, that is the host of the toolchain.) - - -Assembling a root filesystem / -_____________________________/ - - -Assembling a root filesystem for a target device requires the successive -building of a set of software packages for the target architecture. Building -a package potentially requires artifacts which were generated as part of an -earlier build. Note that not all artifacts which are installed as part of a -package are desirable on a target's root filesystem (e.g. man/info files, -include files, etc.). Therefore we must distinguish between a 'staging' -directory and a 'rootfs' directory. - -A 'staging' directory is a location into which we install all the build -artifacts. We can then point future builds to this location so they can find -the appropriate header and library files. A 'rootfs' directory is a location -into which we place only the files we want to have on our target. - -There are four schools of thought here: - -1) Install directly into the sysroot of the toolchain. - - By default (i.e. if you don't pass any arguments to the tools which - would change this behaviour) the toolchain that is built by - crosstool-NG will only look in its toolchain directories for system - header and library files: - -#include "..." search starts here: -#include <...> search starts here: -<ct-ng install path>/lib/gcc/<host tuple>/4.5.2/include -<ct-ng install path>/lib/gcc/<host tuple>/4.5.2/include-fixed -<ct-ng install path>/lib/gcc/<host tuple>/4.5.2/../../../../<host tuple>/include -<ct-ng install path>/<host tuple>/sysroot/usr/include - - In other words, the compiler will automagically find headers and - libraries without extra flags if they are installed under the - toolchain's sysroot directory. - - However, this is bad because the toolchain gets poluted, and can - not be re-used. - - $ ./configure --build=<build tuple> --host=<host tuple> \ - --prefix=/usr --enable-foo-bar... - $ make - $ make DESTDIR=/<ct-ng install path>/<host tuple>/sysroot install - -2) Copy the toolchain's sysroot to the 'staging' area. - - If you start off by copying the toolchain's sysroot directory to your - staging area, you can simply proceed to install all your packages' - artifacts to the same staging area. You then only need to specify a - '--sysroot=<staging area>' option to the compiler of any subsequent - builds and all your required header and library files will be found/used. - - This is a viable option, but requires the user to always specify CFLAGS - in order to include --sysroot=<staging area>, or requires the use of a - wrapper to a few select tools (gcc, ld...) to pass this flag. - - Instead of polluting the toolchain's sysroot you are copying its contents - to a new location and polluting the contents in that new location. By - specifying the --sysroot option you're effectively abandoning the default - sysroot in favour of your own. - - Incidentally this is what buildroot does using a wrapper, when using an - external toolchain. - - $ cp -a $(<host tuple>-gcc --your-cflags-except-sysroot -print-sysroot) \ - /path/to/staging - $ ./configure --build=<build tuple> --host=<host tuple> \ - --prefix=/usr --enable-foo-bar... \ - CC="<host tuple>-gcc --syroot=/path/to/staging" \ - CXX="<host tuple>-g++ --sysroot=/path/to/staging" \ - LD="<host tuple>-ld --sysroot=/path/to/staging" \ - AND_SO_ON="tuple-andsoon --sysroot=/path/to/staging" - $ make - $ make DESTDIR=/path/to/staging install - -3) Use separate staging and sysroot directories. - - In this scenario you use a staging area to install programs, but you do - not pre-fill that staging area with the toolchain's sysroot. In this case - the compiler will find the system includes and libraries in its sysroot - area but you have to pass appropriate CPPFLAGS and LDFLAGS to tell it - where to find your headers and libraries from your staging area (or use - a wrapper). - - $ ./configure --build=<build tuple> --host=<host tuple> \ - --prefix=/usr --enable-foo-bar... \ - CPPFLAGS="-I/path/to/staging/usr/include" \ - LDFLAGS="-L/path/to/staging/lib -L/path/to/staging/usr/lib" - $ make - $ make DESTDIR=/path/to/staging install - -4) A mix of 2) and 3), using carefully crafted union mounts. - - The staging area is a union mount of: - - the sysroot as a read-only branch - - the real staging area as a read-write branch - This also requires passing --sysroot to point to the union mount, but has - other advantages, such as allowing per-package staging, and a few more - obscure pros. It also has its disadvantages, as it potentially requires - non-root users to create union mounts. Additionally, union mounts are not - yet mainstream in the Linux kernel, so it requires patching. There is a - FUSE-based unionfs implementation, but development is almost stalled, - and there are a few gotchas... - - $ (good luck!) - - -It is strongly advised not to use the toolchain sysroot directory as an -install directory (i.e. option 1) for your programs/packages. If you do so, -you will not be able to use your toolchain for another project. It is even -strongly advised that your toolchain is chmod-ed to read-only once -successfully install, so that you don't go polluting your toolchain with -your programs'/packages' files. This can be achieved by selecting the -"Render the toolchain read-only" from crosstool-NG's "Paths and misc options" -configuration page. - -Thus, when you build a program/package, install it in a separate, staging, -directory and let the cross-toolchain continue to use its own, pristine, -sysroot directory. - -When you are done building and want to assemble your rootfs you could simply -take the full contents of your staging directory and use the 'populate' -script to add in the necessary files from the sysroot. However, the staging -area you have created will include lots of build artifacts that you won't -necessarily want/need on your target. For example: static libraries, header -files, linking helper files, man/info pages. You'll also need to add various -configuration files, scripts, and directories to the rootfs so it will boot. - -Therefore you'll probably end up creating a separate rootfs directory which -you will populate from the staging area, necessary extras, and then use -crosstool-NG's populate script to add the necessary sysroot libraries. - - -The 'populate' script | -----------------------+ - -When your root directory is ready, it is still missing some important bits: the -toolchain's libraries. To populate your root directory with those libs, just -run: - your-target-tuple-populate -s /your/root -d /your/root-populated - -This will copy /your/root into /your/root-populated, and put the needed and only -the needed libraries there. Thus you don't pollute /your/root with any cruft that -would no longer be needed should you have to remove stuff. /your/root always -contains only those things you install in it. - -You can then use /your/root-populated to build up your file system image, a -tarball, or to NFS-mount it from your target, or whatever you need. - -The populate script accepts the following options: - - -s src_dir - Use 'src_dir' as the un-populated root directory. - - -d dst_dir - Put the populated root directory in 'dst_dir'. - - -l lib1 [...] - Always add specified libraries. - - -L file - Always add libraries listed in 'file'. - - -f - Remove 'dst_dir' if it previously existed; continue even if any library - specified with -l or -L is missing. - - -v - Be verbose, and tell what's going on (you can see exactly where libs are - coming from). - - -h - Print the help. - -See 'your-target-tuple-populate -h' for more information on the options. - -Here is how populate works: - - 1) performs some sanity checks: - - src_dir and dst_dir are specified - - src_dir exists - - unless forced, dst_dir does not exist - - src_dir != dst_dir - - 2) copy src_dir to dst_dir - - 3) add forced libraries to dst_dir - - build the list from -l and -L options - - get forced libraries from the sysroot (see below for heuristics) - - abort on the first missing library, unless -f is specified - - 4) add all missing libraries to dst_dir - - scan dst_dir for every ELF files that are 'executable' or - 'shared object' - - list the "NEEDED Shared library" fields - - check if the library is already in dst_dir/lib or dst_dir/usr/lib - - if not, get the library from the sysroot - - if it's in sysroot/lib, copy it to dst_dir/lib - - if it's in sysroot/usr/lib, copy it to dst_dir/usr/lib - - in both cases, use the SONAME of the library to create the file - in dst_dir - - if it was not found in the sysroot, this is an error. |