Browse Source
Will be pulled into release tarball by a release script. Signed-off-by: Alexey Neyman <stilor@att.net>dev-linux

15 changed files with 17 additions and 2423 deletions
@ -1,71 +0,0 @@
|
||||
File.........: 0 - Table of content.txt |
||||
Copyright....: (C) 2010 Yann E. MORIN <yann.morin.1998@free.fr> |
||||
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5 |
||||
|
||||
|
||||
Table Of Content / |
||||
_________________/ |
||||
|
||||
|
||||
1- Introduction |
||||
- History |
||||
- Referring to crosstool-NG |
||||
|
||||
2- Installing crosstool-NG |
||||
- Install method |
||||
- The hacker's way |
||||
- Preparing for packaging |
||||
- Shell completion |
||||
- Contributed code |
||||
|
||||
3- Configuring a toolchain |
||||
- Interesting config options |
||||
- Re-building an existing toolchain |
||||
|
||||
4- Building the toolchain |
||||
- Stopping and restarting a build |
||||
- Testing all toolchains at once |
||||
- Overriding the number of // jobs |
||||
- Note on // jobs |
||||
- Tools wrapper |
||||
|
||||
5- Using the toolchain |
||||
- The 'populate' script |
||||
|
||||
6- Toolchain types |
||||
- Seemingly-native toolchains |
||||
|
||||
7- Contributing |
||||
- Sending a bug report |
||||
- Sending patches |
||||
|
||||
8- Internals |
||||
- Makefile front-end |
||||
- Kconfig parser |
||||
- Architecture-specific |
||||
- Adding a new version of a component |
||||
- Build scripts |
||||
|
||||
9 - How is a toolchain constructed? |
||||
- I want a cross-compiler! What is this toolchain you're speaking about? |
||||
- So, what are those components in a toolchain? |
||||
- And now, how do all these components chained together? |
||||
- So the list is complete. But why does crosstool-NG have more steps? |
||||
|
||||
A- Credits |
||||
|
||||
B- Known issues |
||||
- gcc is not found, although I *do* have gcc installed |
||||
- The extract and/or path steps fail under Cygwin |
||||
- uClibc fails to build under Cygwin |
||||
- On 64-bit build systems, the glibc build |
||||
fails for 64-bit targets, because it can not find libgcc |
||||
- libtool.m4: error: problem compiling FC test program |
||||
- unable to detect the exception model |
||||
- configure: error: forced unwind support is required |
||||
- glibc start files and headers fail with: [/usr/include/limits.h] Error 1 |
||||
|
||||
C- Misc. tutorials |
||||
- Using crosstool-NG on FreeBSD (and other *BSD) |
||||
- Using crosstool-NG on MacOS-X |
||||
- Using Mercurial to hack crosstool-NG |
@ -1,111 +0,0 @@
|
||||
File.........: 1 - Introduction.txt |
||||
Copyright....: (C) 2010 Yann E. MORIN <yann.morin.1998@free.fr> |
||||
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5 |
||||
|
||||
|
||||
Introduction / |
||||
_____________/ |
||||
|
||||
|
||||
crosstool-NG aims at building toolchains. Toolchains are an essential component |
||||
in a software development project. It will compile, assemble and link the code |
||||
that is being developed. Some pieces of the toolchain will eventually end up |
||||
in the resulting binary/ies: static libraries are but an example. |
||||
|
||||
So, a toolchain is a very sensitive piece of software, as any bug in one of the |
||||
components, or a poorly configured component, can lead to execution problems, |
||||
ranging from poor performance, to applications ending unexpectedly, to |
||||
mis-behaving software (which more than often is hard to detect), to hardware |
||||
damage, or even to human risks (which is more than regrettable). |
||||
|
||||
Toolchains are made of different piece of software, each being quite complex |
||||
and requiring specially crafted options to build and work seamlessly. This |
||||
is usually not that easy, even in the not-so-trivial case of native toolchains. |
||||
The work reaches a higher degree of complexity when it comes to cross- |
||||
compilation, where it can become quite a nightmare... |
||||
|
||||
Some cross-toolchains exist on the internet, and can be used for general |
||||
development, but they have a number of limitations: |
||||
- they can be general purpose, in that they are configured for the majority: |
||||
no optimisation for your specific target, |
||||
- they can be prepared for a specific target and thus are not easy to use, |
||||
nor optimised for, or even supporting your target, |
||||
- they often are using aging components (compiler, C library, etc...) not |
||||
supporting special features of your shiny new processor; |
||||
On the other side, these toolchain offer some advantages: |
||||
- they are ready to use and quite easy to install and setup, |
||||
- they are proven if used by a wide community. |
||||
|
||||
But once you want to get all the juice out of your specific hardware, you will |
||||
want to build your own toolchain. This is where crosstool-NG comes into play. |
||||
|
||||
There are also a number of tools that build toolchains for specific needs, |
||||
which are not really scalable. Examples are: |
||||
- buildroot (buildroot.uclibc.org) whose main purpose is to build root file |
||||
systems, hence the name. But once you have your toolchain with buildroot, |
||||
part of it is installed in the root-to-be, so if you want to build a whole |
||||
new root, you either have to save the existing one as a template and |
||||
restore it later, or restart again from scratch. This is not convenient, |
||||
- ptxdist (www.pengutronix.de/software/ptxdist), whose purpose is very |
||||
similar to buildroot, |
||||
- other projects (openembedded.org for example), which are again used to |
||||
build root file systems. |
||||
|
||||
crosstool-NG is really targeted at building toolchains, and only toolchains. |
||||
It is then up to you to use it the way you want. |
||||
|
||||
|
||||
History | |
||||
--------+ |
||||
|
||||
crosstool was first 'conceived' by Dan Kegel, who offered it to the community |
||||
as a set of scripts, a repository of patches, and some pre-configured, general |
||||
purpose setup files to be used to configure crosstool. This is available at |
||||
http://www.kegel.com/crosstool, and the subversion repository is hosted on |
||||
google at http://code.google.com/p/crosstool/. |
||||
|
||||
Yann E. MORIN once managed to add support for uClibc-based toolchains, but it |
||||
did not make into mainline, mostly because Yann didn't have time to port the |
||||
patch forward to the new versions, due in part to the big effort it was taking. |
||||
|
||||
So Yann decided to clean up crosstool in the state it was, re-order the things |
||||
in place, add appropriate support for what Yann needed, that is uClibc support |
||||
and a menu-driven configuration, named the new implementation crosstool-NG, |
||||
(standing for crosstool Next Generation, as many other community projects do, |
||||
and as a wink at the TV series "Star Trek: The Next Generation" ;-) ) and |
||||
made it available to the community, in case it was of interest to any one. |
||||
|
||||
In late 2014, Yann became very busy with buildroot and other projects, and so |
||||
Bryan Hundven opted to become the new maintainer for crosstool-NG. |
||||
|
||||
|
||||
Referring to crosstool-NG | |
||||
--------------------------+ |
||||
|
||||
The long name of the project is crosstool-NG: |
||||
* no leading uppercase (except as first word in a sentence) |
||||
* crosstool and NG separated with a hyphen (dash) |
||||
* NG in uppercase |
||||
|
||||
Crosstool-NG can also be referred to by its short name CT-NG: |
||||
* all in uppercase |
||||
* CT and NG separated with a hyphen (dash) |
||||
|
||||
The long name is preferred over the short name, except in mail subjects, where |
||||
the short name is a better fit. |
||||
|
||||
When referring to a specific version of crosstool-NG, append the version number |
||||
either as: |
||||
* crosstool-NG X.Y.Z |
||||
- the long name, a space, and the version string |
||||
* crosstool-ng-X.Y.Z |
||||
- the long name in lowercase, a hyphen (dash), and the version string |
||||
- this is used to name the release tarballs |
||||
* crosstool-ng-X.Y.Z+hg_id |
||||
- the long name in lowercase, a hyphen, the version string, and the Hg id |
||||
(as returned by: ct-ng version) |
||||
- this is used to differentiate between releases and snapshots |
||||
|
||||
The frontend to crosstool-NG is the command ct-ng: |
||||
* all in lowercase |
||||
* ct and ng separated by a hyphen (dash) |
@ -1,99 +0,0 @@
|
||||
File.........: 2 - Installing crosstool-NG.txt |
||||
Copyright....: (C) 2010 Yann E. MORIN <yann.morin.1998@free.fr> |
||||
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5 |
||||
|
||||
|
||||
Installing crosstool-NG / |
||||
________________________/ |
||||
|
||||
|
||||
There are two ways you can use crosstool-NG: |
||||
- build and install it, then get rid of the sources like you'd do for most |
||||
programs, |
||||
- or only build it and run from the source directory. |
||||
|
||||
The former should be used if you got crosstool-NG from a packaged tarball, see |
||||
"Install method", below, while the latter is most useful for developers that |
||||
use a clone of the repository, and want to submit patches, see "The Hacker's |
||||
way", below. |
||||
|
||||
|
||||
Install method | |
||||
---------------+ |
||||
|
||||
If you go for the install, then you just follow the classical, but yet easy |
||||
./configure way: |
||||
./configure --prefix=/some/place |
||||
make |
||||
make install |
||||
export PATH="${PATH}:/some/place/bin" |
||||
|
||||
You can then get rid of crosstool-NG source. Next create a directory to serve |
||||
as a working place, cd in there and run: |
||||
mkdir work-dir |
||||
cd work-dir |
||||
ct-ng help |
||||
|
||||
See below for complete usage. |
||||
|
||||
|
||||
The Hacker's way | |
||||
-----------------+ |
||||
|
||||
If you go the hacker's way, then the usage is a bit different, although very |
||||
simple. First, you need to generate the ./configure script from its autoconf |
||||
template: |
||||
./bootstrap |
||||
|
||||
Then, you run ./configure for local execution of crosstool-NG: |
||||
./configure --enable-local |
||||
make |
||||
|
||||
Now, *do not* remove crosstool-NG sources. They are needed to run crosstool-NG! |
||||
Stay in the directory holding the sources, and run: |
||||
./ct-ng help |
||||
|
||||
See below for complete usage. |
||||
|
||||
Now, provided you used a clone of the repository, you can send me your changes. |
||||
See the section titled CONTRIBUTING, below, for how to submit changes. |
||||
|
||||
|
||||
Preparing for packaging | |
||||
------------------------+ |
||||
|
||||
If you plan on packaging crosstool-NG, you surely don't want to install it |
||||
in your root file system. The install procedure of crosstool-NG honors the |
||||
DESTDIR variable: |
||||
|
||||
./configure --prefix=/usr |
||||
make |
||||
make DESTDIR=/packaging/place install |
||||
|
||||
|
||||
Shell completion | |
||||
-----------------+ |
||||
|
||||
crosstool-NG comes with a shell script fragment that defines bash-compatible |
||||
completion. That shell fragment is currently not installed automatically, but |
||||
this is planned. |
||||
|
||||
To install the shell script fragment, you have two options: |
||||
- install system-wide, most probably by copying ct-ng.comp into |
||||
/etc/bash_completion.d/ |
||||
- install for a single user, by copying ct-ng.comp into ${HOME}/ and |
||||
sourcing this file from your ${HOME}/.bashrc |
||||
|
||||
|
||||
Contributed code | |
||||
-----------------+ |
||||
|
||||
Some people contributed code that couldn't get merged for various reasons. This |
||||
code is available as lzma-compressed patches, in the contrib/ sub-directory. |
||||
These patches are to be applied to the source of crosstool-NG, prior to |
||||
installing, using something like the following: |
||||
lzcat contrib/foobar.patch.lzma |patch -p1 |
||||
|
||||
There is no guarantee that a particular contribution applies to the current |
||||
version of crosstool-ng, or that it will work at all. Use contributions at |
||||
your own risk. |
@ -1,117 +0,0 @@
|
||||
File.........: 3 - Configuring a toolchain.txt |
||||
Copyright....: (C) 2010 Yann E. MORIN <yann.morin.1998@free.fr> |
||||
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5 |
||||
|
||||
|
||||
|
||||
Configuring crosstool-NG / |
||||
_________________________/ |
||||
|
||||
|
||||
crosstool-NG is configured with a configurator presenting a menu-structured set |
||||
of options. These options let you specify the way you want your toolchain |
||||
built, where you want it installed, what architecture and specific processor it |
||||
will support, the version of the components you want to use, etc... The |
||||
value for those options are then stored in a configuration file. |
||||
|
||||
The configurator works the same way you configure your Linux kernel. It is |
||||
assumed you know how to handle this. |
||||
|
||||
To enter the menu, type: |
||||
ct-ng menuconfig |
||||
|
||||
Almost every config item has a help entry. Read them carefully. |
||||
|
||||
String and number options can refer to environment variables. In such a case, |
||||
you must use the shell syntax: ${VAR}. You shall neither single- nor double- |
||||
quote the string/number options. |
||||
|
||||
There are three environment variables that are computed by crosstool-NG, and |
||||
that you can use: |
||||
|
||||
CT_TARGET: |
||||
It represents the target tuple you are building for. You can use it for |
||||
example in the installation/prefix directory, such as: |
||||
/opt/x-tools/${CT_TARGET} |
||||
|
||||
CT_TOP_DIR: |
||||
The top directory where crosstool-NG is running. You shouldn't need it in |
||||
most cases. There is one case where you may need it: if you have local |
||||
patches and you store them in your running directory, you can refer to them |
||||
by using CT_TOP_DIR, such as: |
||||
${CT_TOP_DIR}/patches.myproject |
||||
|
||||
CT_VERSION: |
||||
The version of crosstool-NG you are using. Not much use for you, but it's |
||||
there if you need it. |
||||
|
||||
|
||||
Interesting config options | |
||||
---------------------------+ |
||||
|
||||
CT_LOCAL_TARBALLS_DIR: |
||||
If you already have some tarballs in a directory, enter it here. That will |
||||
speed up the retrieving phase, where crosstool-NG would otherwise download |
||||
those tarballs. |
||||
|
||||
CT_PREFIX_DIR: |
||||
This is where the toolchain will be installed in (and for now, where it |
||||
will run from). Common use is to add the target tuple in the directory |
||||
path, such as (see above): |
||||
/opt/x-tools/${CT_TARGET} |
||||
|
||||
CT_TARGET_VENDOR: |
||||
An identifier for your toolchain, will take place in the vendor part of the |
||||
target tuple. It shall *not* contain spaces or dashes. Usually, keep it |
||||
to a one-word string, or use underscores to separate words if you need. |
||||
Avoid dots, commas, and special characters. |
||||
|
||||
CT_TARGET_ALIAS: |
||||
An alias for the toolchain. It will be used as a prefix to the toolchain |
||||
tools. For example, you will have ${CT_TARGET_ALIAS}-gcc |
||||
|
||||
Also, if you think you don't see enough versions, you can try to enable one of |
||||
those: |
||||
|
||||
CT_OBSOLETE: |
||||
Show obsolete versions or tools. Most of the time, you don't want to base |
||||
your toolchain on too old a version (of gcc, for example). But at times, it |
||||
can come handy to use such an old version for regression tests. Those old |
||||
versions are hidden behind CT_OBSOLETE. Those versions (or features) are so |
||||
marked because maintaining support for those in crosstool-NG would be too |
||||
costly, time-wise, and time is dear. |
||||
|
||||
CT_EXPERIMENTAL: |
||||
Show experimental versions or tools. Again, you might not want to base your |
||||
toolchain on too recent tools (eg. gcc) for production. But if you need a |
||||
feature present only in a recent version, or a new tool, you can find them |
||||
hidden behind CT_EXPERIMENTAL. Those versions (or features) did not (yet) |
||||
receive thorough testing in crosstool-NG, and/or are not mature enough to |
||||
be blindly trusted. |
||||
|
||||
|
||||
Re-building an existing toolchain | |
||||
----------------------------------+ |
||||
|
||||
If you have an existing toolchain, you can re-use the options used to build it |
||||
to create a new toolchain. That needs a very little bit of effort on your side |
||||
but is quite easy. The options to build a toolchain are saved with the |
||||
toolchain, and you can retrieve this configuration by running: |
||||
${CT_TARGET}-ct-ng.config |
||||
|
||||
An alternate method is to extract the configuration from a build.log file. |
||||
This will be necessary if your toolchain was build with crosstool-NG prior |
||||
to 1.4.0, but can be used with build.log files from any version: |
||||
ct-ng extractconfig <build.log >.config |
||||
|
||||
Or, if your build.log file is compressed (most probably!): |
||||
bzcat build.log.bz2 |ct-ng extractconfig >.config |
||||
|
||||
The above commands will dump the configuration to stdout, so to rebuild a |
||||
toolchain with this configuration, just redirect the output to the |
||||
.config file: |
||||
${CT_TARGET}-ct-ng.config >.config |
||||
ct-ng oldconfig |
||||
|
||||
Then, you can review and change the configuration by running: |
||||
ct-ng menuconfig |
@ -1,145 +0,0 @@
|
||||
File.........: 4 - Building 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 |
||||
|
||||
|
||||
Building the toolchain / |
||||
_______________________/ |
||||
|
||||
|
||||
To build the toolchain, simply type: |
||||
ct-ng build |
||||
|
||||
This will use the above configuration to retrieve, extract and patch the |
||||
components, build, install and eventually test your newly built toolchain. |
||||
|
||||
You are then free to add the toolchain /bin directory in your PATH to use |
||||
it at will. |
||||
|
||||
In any case, you can get some terse help. Just type: |
||||
ct-ng help |
||||
or: |
||||
man 1 ct-ng |
||||
|
||||
|
||||
Stopping and restarting a build | |
||||
--------------------------------+ |
||||
|
||||
If you want to stop the build after a step you are debugging, you can pass the |
||||
variable STOP to make: |
||||
ct-ng build STOP=some_step |
||||
|
||||
Conversely, if you want to restart a build at a specific step you are |
||||
debugging, you can pass the RESTART variable to make: |
||||
ct-ng build RESTART=some_step |
||||
|
||||
Alternatively, you can call make with the name of a step to just do that step: |
||||
ct-ng libc_headers |
||||
is equivalent to: |
||||
ct-ng build RESTART=libc_headers STOP=libc_headers |
||||
|
||||
The shortcuts +step_name and step_name+ allow to respectively stop or restart |
||||
at that step. Thus: |
||||
ct-ng +libc_headers and: ct-ng libc_headers+ |
||||
are equivalent to: |
||||
ct-ng build STOP=libc_headers and: ct-ng build RESTART=libc_headers |
||||
|
||||
To obtain the list of acceptable steps, please call: |
||||
ct-ng list-steps |
||||
|
||||
Note that in order to restart a build, you'll have to say 'Y' to the config |
||||
option CT_DEBUG_CT_SAVE_STEPS, and that the previous build effectively went |
||||
that far. |
||||
|
||||
|
||||
Building all toolchains at once | |
||||
--------------------------------+ |
||||
|
||||
You can build all samples; simply call: |
||||
ct-ng build-all |
||||
|
||||
|
||||
Overriding the number of // jobs | |
||||
---------------------------------+ |
||||
|
||||
If you want to override the number of jobs to run in // (the -j option to |
||||
make), you can either re-enter the menuconfig, or simply add it on the command |
||||
line, as such: |
||||
ct-ng build.4 |
||||
|
||||
which tells crosstool-NG to override the number of // jobs to 4. |
||||
|
||||
You can see the actions that support overriding the number of // jobs in |
||||
the help menu. Those are the ones with [.#] after them (eg. build[.#] or |
||||
build-all[.#], and so on...). |
||||
|
||||
|
||||
Note on // jobs | |
||||
----------------+ |
||||
|
||||
The crosstool-NG script 'ct-ng' is a Makefile-script. It does *not* execute |
||||
in parallel (there is not much to gain). When speaking of // jobs, we are |
||||
refering to the number of // jobs when making the *components*. That is, we |
||||
speak of the number of // jobs used to build gcc, glibc, and so on... |
||||
|
||||
|
||||
Tools wrapper | |
||||
--------------+ |
||||
|
||||
Starting with gcc-4.3 come two new dependencies: GMP and MPFR. With gcc-4.4, |
||||
come three new ones: PPL, CLooG/ppl and MPC. With gcc-4.5 again comes a new |
||||
dependency on libelf. These are libraries that enable advanced features to |
||||
gcc. Additionally, some of those libraries can be used by binutils and gdb. |
||||
Unfortunately, not all systems on which crosstool-NG runs have all of those |
||||
libraries. And for those that do, the versions of those libraries may be |
||||
older than the version required by gcc (and binutils and gdb). To date, |
||||
Debian stable (aka Lenny) is lagging behind on some, and is missing the |
||||
others. With >= gcc-4.8, we drop PPL and CLooG/PPL, and switch to ISL to |
||||
replace PPL, and use the upstream version of CLooG instead of CLooG/PPL |
||||
which was a fork of CLooG that provided PPL backend support, that was under- |
||||
maintained. See: https://gcc.gnu.org/wiki/Graphite-4.8 |
||||
|
||||
This is why crosstool-NG builds its own set of libraries as part of the |
||||
toolchain. |
||||
|
||||
The companion libraries can be built either as static libraries, or as shared |
||||
libraries. The default is to build static libraries, and is the safe way. |
||||
If you decide to use static companion libraries, then you can stop reading |
||||
this section. |
||||
|
||||
But if you prefer to have shared libraries, then read on... |
||||
|
||||
Building shared companion libraries poses no problem at build time, as |
||||
crosstool-NG correctly points gcc (and binutils and gdb) to the correct |
||||
place where our own version of the libraries are installed. But it poses |
||||
a problem when gcc et al. are run: the place where the libraries are is most |
||||
probably not known to the host dynamic linker. Still worse, if the host system |
||||
has its own versions, then ld.so would load the wrong libraries! |
||||
|
||||
So we have to force the dynamic linker to load the correct version. We do this |
||||
by using the LD_LIBRARY_PATH variable, that informs the dynamic linker where |
||||
to look for shared libraries prior to searching its standard places. But we |
||||
can't impose that burden on all the system (because it'd be a nightmare to |
||||
configure, and because two toolchains on the same system may use different |
||||
versions of the libraries); so we have to do it on a per-toolchain basis. |
||||
|
||||
So we rename all binaries of the toolchain (by adding a dot '.' as their first |
||||
character), and add a small program, the so-called "tools wrapper", that |
||||
correctly sets LD_LIBRARY_PATH prior to running the real tool. |
||||
|
||||
First, the wrapper was written as a POSIX-compliant shell script. That shell |
||||
script is very simple, if not trivial, and works great. The only drawback is |
||||
that it does not work on host systems that lack a shell, for example the |
||||
MingW32 environment. To solve the issue, the wrapper has been re-written in C, |
||||
and compiled at build time. This C wrapper is much more complex than the shell |
||||
script, and although it seems to be working, it's been only lightly tested. |
||||
Some of the expected short-comings with this C wrapper are; |
||||
- multi-byte file names may not be handled correctly |
||||
- it's really big for what it does |
||||
|
||||
So, the default wrapper installed with your toolchain is the shell script. |
||||
If you know that your system is missing a shell, then you shall use the C |
||||
wrapper (and report back whether it works, or does not work, for you). |
||||
|
||||
A final word on the subject: do not build shared libraries. Build them |
||||
static, and you'll be safe. |
@ -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. |
@ -1,64 +0,0 @@
|
||||
File.........: 6 - Toolchain types.txt |
||||
Copyright....: (C) 2010 Yann E. MORIN <yann.morin.1998@free.fr> |
||||
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5 |
||||
|
||||
|
||||
Toolchain types / |
||||
________________/ |
||||
|
||||
|
||||
There are four kinds of toolchains you could encounter. |
||||
|
||||
First off, you must understand the following: when it comes to compilers there |
||||
are up to four machines involved: |
||||
1) the machine configuring the toolchain components: the config machine |
||||
2) the machine building the toolchain components: the build machine |
||||
3) the machine running the toolchain: the host machine |
||||
4) the machine the toolchain is generating code for: the target machine |
||||
|
||||
We can most of the time assume that the config machine and the build machine |
||||
are the same. Most of the time, this will be true. The only time it isn't |
||||
is if you're using distributed compilation (such as distcc). Let's forget |
||||
this for the sake of simplicity. |
||||
|
||||
So we're left with three machines: |
||||
- build |
||||
- host |
||||
- target |
||||
|
||||
Any toolchain will involve those three machines. You can be as pretty sure of |
||||
this as "2 and 2 are 4". Here is how they come into play: |
||||
|
||||
1) build == host == target |
||||
This is a plain native toolchain, targeting the exact same machine as the |
||||
one it is built on, and running again on this exact same machine. You have |
||||
to build such a toolchain when you want to use an updated component, such |
||||
as a newer gcc for example. |
||||
crosstool-NG calls it "native". |
||||
|
||||
2) build == host != target |
||||
This is a classic cross-toolchain, which is expected to be run on the same |
||||
machine it is compiled on, and generate code to run on a second machine, |
||||
the target. |
||||
crosstool-NG calls it "cross". |
||||
|
||||
3) build != host == target |
||||
Such a toolchain is also a native toolchain, as it targets the same machine |
||||
as it runs on. But it is build on another machine. You want such a |
||||
toolchain when porting to a new architecture, or if the build machine is |
||||
much faster than the host machine. |
||||
crosstool-NG calls it "cross-native". |
||||
|
||||
4) build != host != target |
||||
This one is called a canadian-toolchain (*), and is tricky. The three |
||||
machines in play are different. You might want such a toolchain if you |
||||
have a fast build machine, but the users will use it on another machine, |
||||
and will produce code to run on a third machine. |
||||
crosstool-NG calls it "canadian". |
||||
|
||||
crosstool-NG can build all these kinds of toolchains (or is aiming at it, |
||||
anyway!) |
||||
|
||||
(*) The term Canadian Cross came about because at the time that these issues |
||||
were all being hashed out, Canada had three national political parties. |
||||
http://en.wikipedia.org/wiki/Cross_compiler |
@ -1,63 +0,0 @@
|
||||
File.........: 7 - Contributing to crosstool-NG.txt |
||||
Copyright....: (C) 2010 Yann E. MORIN <yann.morin.1998@free.fr> |
||||
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5 |
||||
|
||||
|
||||
Contributing to crosstool-NG / |
||||
_____________________________/ |
||||
|
||||
|
||||
Sending a bug report | |
||||
---------------------+ |
||||
|
||||
If you need to send a bug report, please send a mail with subject |
||||
prefixed with "[CT_NG]" with to following destinations: |
||||
TO: yann.morin.1998 (at) free.fr |
||||
CC: crossgcc (at) sourceware.org |
||||
|
||||
|
||||
Sending patches | |
||||
----------------+ |
||||
|
||||
If you want to enhance crosstool-NG, there's a to-do list in the TODO file. |
||||
|
||||
When updating a package, please include the category and component in the |
||||
start of the description. For example: |
||||
cc/gcc: update to the Linaro 2011.09 release |
||||
|
||||
Here is the (mostly-complete) list of categories and components: |
||||
|
||||
Categories | Components |
||||
------------+------------------------------------------------------- |
||||
arch | alpha, arm, mips, powerpc... |
||||
cc | gcc |
||||
binutils | binutils, elf2flt, sstrip |
||||
libc | uClibc, glibc, newlib, mingw, none |
||||
kernel | linux, mingw32, bare-metal |
||||
debug | duma, gdb, ltrace, strace |
||||
complibs | gmp, mpfr, isl, cloog, mpc, libelf |
||||
comptools | make, m4, autoconf, automake, libtool |
||||
------------+------------------------------------------------------- |
||||
| The following categories have no component-part: |
||||
samples | when adding/updating/removing a sample |
||||
kconfig | for stuff in the kconfig/ dir |
||||
docs | for changes to the documentation |
||||
configure | for changes to ./configure and/or Makefile.in |
||||
config | for stuff in config/ not covered above |
||||
scripts | for stuff in scripts/ not covered above |
||||
|
||||
|
||||
Patches should come with the appropriate SoB line. A SoB line is typically |
||||
something like: |
||||
Signed-off-by: John DOE <john.doe@somewhere.net> |
||||
|
||||
The SoB line is clearly described in Documentation/SubmittingPatches , section |
||||
12, of your favourite Linux kernel source tree. |
||||
|
||||
You can also add any of the following lines if applicable: |
||||
Acked-by: |
||||
Tested-by: |
||||
Reviewed-by: |
||||
|
||||
For larger or more frequent contributions, mercurial should be used. |
||||
There is a nice, complete and step-by-step tutorial in section 'C'. |
@ -1,293 +0,0 @@
|
||||
File.........: 8 - Internals.txt |
||||
Copyright....: (C) 2010 Yann E. MORIN <yann.morin.1998@free.fr> |
||||
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5 |
||||
|
||||
|
||||
Internals / |
||||
__________/ |
||||
|
||||
|
||||
Internally, crosstool-NG is script-based. To ease usage, the frontend is |
||||
Makefile-based. |
||||
|
||||
|
||||
Makefile front-end | |
||||
-------------------+ |
||||
|
||||
The entry point to crosstool-NG is the Makefile script "ct-ng". Calling this |
||||
script with an action will act exactly as if the Makefile was in the current |
||||
working directory and make was called with the action as rule. Thus: |
||||
ct-ng menuconfig |
||||
|
||||
is equivalent to having the Makefile in CWD, and calling: |
||||
make menuconfig |
||||
|
||||
Having ct-ng as it is avoids copying the Makefile everywhere, and acts as a |
||||
traditional command. |
||||
|
||||
ct-ng loads sub- Makefiles from the library directory $(CT_LIB_DIR), as set up |
||||
at configuration time with ./configure. |
||||
|
||||
ct-ng also searches for config files, sub-tools, samples, scripts and patches in |
||||
that library directory. |
||||
|
||||
Because of a stupid make behavior/bug I was unable to track down, implicit make |
||||
rules are disabled: installing with --local would trigger those rules, and mconf |
||||
was unbuildable. |
||||
|
||||
|
||||
Kconfig parser | |
||||
---------------+ |
||||
|
||||
The kconfig language is a hacked version, vampirised from the Linux kernel |
||||
(http://www.kernel.org/), and (heavily) adapted to my needs. |
||||
|
||||
The list of the most notable changes (at least the ones I remember) follows: |
||||
- the CONFIG_ prefix has been replaced with CT_ |
||||
- a leading | in prompts is skipped, and subsequent leading spaces are not |
||||
trimmed; otherwise leading spaces are silently trimmed |
||||
- removed the warning about undefined environment variable |
||||
|
||||
The kconfig parsers (conf and mconf) are not installed pre-built, but as |
||||
source files. Thus you can have the directory where crosstool-NG is installed, |
||||
exported (via NFS or whatever) and have clients with different architectures |
||||
use the same crosstool-NG installation, and most notably, the same set of |
||||
patches. |
||||
|
||||
|
||||
Architecture-specific | |
||||
----------------------+ |
||||
|
||||
Note: this chapter is not really well written, and might thus be a little bit |
||||
complex to understand. To get a better grasp of what an architecture is, the |
||||
reader is kindly encouraged to look at the "arch/" sub-directory, and to the |
||||
existing architectures to see how things are laid out. |
||||
|
||||
An architecture is defined by: |
||||
|
||||
- a human-readable name, in lower case letters, with numbers as appropriate. |
||||
The underscore is allowed; space and special characters are not. |
||||
Eg.: arm, x86_64 |
||||
- a file in "config/arch/", named after the architecture's name, and suffixed |
||||
with ".in". |
||||
Eg.: config/arch/arm.in |
||||
- a file in "scripts/build/arch/", named after the architecture's name, and |
||||
suffixed with ".sh". |
||||
Eg.: scripts/build/arch/arm.sh |
||||
|
||||
The architecture's ".in" file API: |
||||
> the config option "ARCH_%arch%" (where %arch% is to be replaced with the |
||||
actual architecture name). |
||||
That config option must have *neither* a type, *nor* a prompt! Also, it can |
||||
*not* depend on any other config option (EXPERIMENTAL is managed as above). |
||||
Eg.: |
||||
config ARCH_arm |
||||
+ mandatory: |
||||
defines a (terse) help entry for this architecture: |
||||
Eg.: |
||||
config ARCH_arm |
||||
help |
||||
The ARM architecture. |
||||
+ optional: |
||||
selects adequate associated config options. |
||||
Note: 64-bit architectures *shall* select ARCH_64 |
||||
Eg.: |
||||
config ARCH_arm |
||||
select ARCH_SUPPORTS_BOTH_ENDIAN |
||||
select ARCH_DEFAULT_LE |
||||
help |
||||
The ARM architecture. |
||||
Eg.: |
||||
config ARCH_x86_64 |
||||
select ARCH_64 |
||||
help |
||||
The x86_64 architecture. |
||||
|
||||
> other target-specific options, at your discretion. Note however that to |
||||
avoid name-clashing, such options shall be prefixed with "ARCH_%arch%", |
||||
where %arch% is again replaced by the actual architecture name. |
||||
(Note: due to historical reasons, and lack of time to clean up the code, |
||||
I may have left some config options that do not completely conform to |
||||
this, as the architecture name was written all upper case. However, the |
||||
prefix is unique among architectures, and does not cause harm). |
||||
|
||||
The architecture's ".sh" file API: |
||||
> the function "CT_DoArchTupleValues" |
||||
+ parameters: none |
||||
+ environment: |
||||
- all variables from the ".config" file, |
||||
- the two variables "target_endian_eb" and "target_endian_el" which are |
||||
the endianness suffixes |
||||
+ return value: 0 upon success, !0 upon failure |
||||
+ provides: |
||||
- mandatory |
||||
- the environment variable CT_TARGET_ARCH |
||||
- contains: |
||||
the architecture part of the target tuple. |
||||
Eg.: "armeb" for big endian ARM |
||||
"i386" for an i386 |
||||
+ provides: |
||||
- optional |
||||
- the environment variable CT_TARGET_SYS |
||||
- contains: |
||||
the system part of the target tuple. |
||||
Eg.: "gnu" for glibc on most architectures |
||||
"gnueabi" for glibc on an ARM EABI |
||||
- defaults to: |
||||
- for glibc-based toolchain: "gnu" |
||||
- for uClibc-based toolchain: "uclibc" |
||||
+ provides: |
||||
- optional |
||||
- the environment variables to configure the cross-gcc (defaults) |
||||
- CT_ARCH_WITH_ARCH : the gcc ./configure switch to select architecture level ( "--with-arch=${CT_ARCH_ARCH}" ) |
||||
- CT_ARCH_WITH_ABI : the gcc ./configure switch to select ABI level ( "--with-abi=${CT_ARCH_ABI}" ) |
||||
- CT_ARCH_WITH_CPU : the gcc ./configure switch to select CPU instruction set ( "--with-cpu=${CT_ARCH_CPU}" ) |
||||
- CT_ARCH_WITH_TUNE : the gcc ./configure switch to select scheduling ( "--with-tune=${CT_ARCH_TUNE}" ) |
||||
- CT_ARCH_WITH_FPU : the gcc ./configure switch to select FPU type ( "--with-fpu=${CT_ARCH_FPU}" ) |
||||
- CT_ARCH_WITH_FLOAT : the gcc ./configure switch to select floating point arithmetics ( "--with-float=soft" or /empty/ ) |
||||
+ provides: |
||||
- optional |
||||
- the environment variables to pass to the cross-gcc to build target binaries (defaults) |
||||
- CT_ARCH_ARCH_CFLAG : the gcc switch to select architecture level ( "-march=${CT_ARCH_ARCH}" ) |
||||
- CT_ARCH_ABI_CFLAG : the gcc switch to select ABI level ( "-mabi=${CT_ARCH_ABI}" ) |
||||
- CT_ARCH_CPU_CFLAG : the gcc switch to select CPU instruction set ( "-mcpu=${CT_ARCH_CPU}" ) |
||||
- CT_ARCH_TUNE_CFLAG : the gcc switch to select scheduling ( "-mtune=${CT_ARCH_TUNE}" ) |
||||
- CT_ARCH_FPU_CFLAG : the gcc switch to select FPU type ( "-mfpu=${CT_ARCH_FPU}" ) |
||||
- CT_ARCH_FLOAT_CFLAG : the gcc switch to choose floating point arithmetics ( "-msoft-float" or /empty/ ) |
||||
- CT_ARCH_ENDIAN_CFLAG : the gcc switch to choose big or little endian ( "-mbig-endian" or "-mlittle-endian" ) |
||||
- default to: |
||||
see above. |
||||
+ provides: |
||||
- optional |
||||
- the environment variables to configure the core and final compiler, specific to this architecture: |
||||
- CT_ARCH_CC_CORE_EXTRA_CONFIG : additional, architecture specific core gcc ./configure flags |
||||
- CT_ARCH_CC_EXTRA_CONFIG : additional, architecture specific final gcc ./configure flags |
||||
- default to: |
||||
- all empty |
||||
+ provides: |
||||
- optional |
||||
- the architecture-specific CFLAGS and LDFLAGS: |
||||
- CT_ARCH_TARGET_CLFAGS |
||||
- CT_ARCH_TARGET_LDFLAGS |
||||
- default to: |
||||
- all empty |
||||
|
||||
You can have a look at "config/arch/arm.in" and "scripts/build/arch/arm.sh" for |
||||
a quite complete example of what an actual architecture description looks like. |
||||
|
||||
|
||||
Kernel specific | |
||||
----------------+ |
||||
|
||||
A kernel is defined by: |
||||
|
||||
- a human-readable name, in lower case letters, with numbers as appropriate. |
||||
The underscore is allowed; space and special characters are not (although |
||||
they are internally replaced with underscores. |
||||
Eg.: linux, bare-metal |
||||
- a file in "config/kernel/", named after the kernel name, and suffixed with |
||||
".in". |
||||
Eg.: config/kernel/linux.in, config/kernel/bare-metal.in |
||||
- a file in "scripts/build/kernel/", named after the kernel name, and suffixed |
||||
with ".sh". |
||||
Eg.: scripts/build/kernel/linux.sh, scripts/build/kernel/bare-metal.sh |
||||
|
||||
The kernel's ".in" file must contain: |
||||
> an optional lines containing exactly "# EXPERIMENTAL", starting on the |
||||
first column, and without any following space or other character. |
||||
If this line is present, then this kernel is considered EXPERIMENTAL, |
||||
and correct dependency on EXPERIMENTAL will be set. |
||||
|
||||
> the config option "KERNEL_%kernel_name%" (where %kernel_name% is to be |
||||
replaced with the actual kernel name, with all special characters and |
||||
spaces replaced by underscores). |
||||
That config option must have *neither* a type, *nor* a prompt! Also, it can |
||||
*not* depends on EXPERIMENTAL. |
||||
Eg.: KERNEL_linux, KERNEL_bare_metal |
||||
+ mandatory: |
||||
defines a (terse) help entry for this kernel. |
||||
Eg.: |
||||
config KERNEL_bare_metal |
||||
help |
||||
Build a compiler for use without any kernel. |
||||
+ optional: |
||||
selects adequate associated config options. |
||||
Eg.: |
||||
config KERNEL_bare_metal |
||||
select BARE_METAL |
||||
help |
||||
Build a compiler for use without any kernel. |
||||
|
||||
> other kernel specific options, at your discretion. Note however that, to |
||||
avoid name-clashing, such options should be prefixed with |
||||
"KERNEL_%kernel_name%", where %kernel_name% is again tp be replaced with |
||||
the actual kernel name. |
||||
(Note: due to historical reasons, and lack of time to clean up the code, |
||||
I may have left some config options that do not completely conform to |
||||
this, as the kernel name was written all upper case. However, the prefix |
||||
is unique among kernels, and does not cause harm). |
||||
|
||||
The kernel's ".sh" file API: |
||||
> is a bash script fragment |
||||
|
||||
> defines the function CT_DoKernelTupleValues |
||||
+ see the architecture's CT_DoArchTupleValues, except for: |
||||
+ set the environment variable CT_TARGET_KERNEL, the kernel part of the |
||||
target tuple |
||||
+ return value: ignored |
||||
|
||||
> defines the function "do_kernel_get": |
||||
+ parameters: none |
||||
+ environment: |
||||
- all variables from the ".config" file. |
||||
+ return value: 0 for success, !0 for failure. |
||||
+ behavior: download the kernel's sources, and store the tarball into |
||||
"${CT_TARBALLS_DIR}". To this end, a functions is available, that |
||||
abstracts downloading tarballs: |
||||
- CT_DoGet <tarball_base_name> <URL1 [URL...]> |
||||
Eg.: CT_DoGet linux-2.6.26.5 ftp://ftp.kernel.org/pub/linux/kernel/v2.6 |
||||
Note: retrieving sources from svn, cvs, git and the likes is not supported |
||||
by CT_DoGet. For now, you'll have to do this by hand. |
||||
|
||||
> defines the function "do_kernel_extract": |
||||
+ parameters: none |
||||
+ environment: |
||||
- all variables from the ".config" file, |
||||
+ return value: 0 for success, !0 for failure. |
||||
+ behavior: extract the kernel's tarball into "${CT_SRC_DIR}", and apply |
||||
required patches. To this end, a function is available, that abstracts |
||||
extracting tarballs: |
||||
- CT_ExtractAndPatch <tarball_base_name> |
||||
Eg.: CT_ExtractAndPatch linux-2.6.26.5 |
||||
|
||||
> defines the function "do_kernel_headers": |
||||
+ parameters: none |
||||
+ environment: |
||||
- all variables from the ".config" file, |
||||
+ return value: 0 for success, !0 for failure. |
||||
+ behavior: install the kernel headers (if any) in "${CT_SYSROOT_DIR}/usr/include" |
||||
|
||||
> defines any kernel-specific helper functions |
||||
These functions, if any, must be prefixed with "do_kernel_%CT_KERNEL%_", |
||||
where '%CT_KERNEL%' is to be replaced with the actual kernel name, to avoid |
||||
any name-clashing. |
||||
|
||||
You can have a look at "config/kernel/linux.in" and "scripts/build/kernel/linux.sh" |
||||
as an example of what a complex kernel description looks like. |
||||
|
||||
|
||||
Adding a new version of a component | |
||||
------------------------------------+ |
||||
|
||||
When a new component, such as the Linux kernel, gcc or any other is released, |
||||
adding the new version to crosstool-NG is quite easy. There is a script that |
||||
will do all that for you: |
||||
scripts/addToolVersion.sh |
||||
|
||||
Run it with no option to get some help. |
||||
|
||||
|
||||
Build scripts | |
||||
--------------+ |
||||
|
||||
To Be Written later... |
@ -1,253 +0,0 @@
|
||||
File.........: 9 - Build procedure overview.txt |
||||
Copyright....: (C) 2011 Yann E. MORIN <yann.morin.1998@free.fr> |
||||
License......: Creative Commons Attribution Share Alike (CC-by-sa), v2.5 |
||||
|
||||
|
||||
How is a toolchain constructed? / |
||||
_______________________________/ |
||||
|
||||
This is the result of a discussion with Francesco Turco <mail@fturco.org>: |
||||
http://sourceware.org/ml/crossgcc/2011-01/msg00060.html |
||||
|
||||
Francesco has a nice tutorial for beginners, along with a sample, step-by- |
||||
step procedure to build a toolchain for an ARM target from an x86_64 Debian |
||||
host: |
||||
http://fturco.org/wiki/doku.php?id=debian:cross-compiler |
||||
|
||||
Thank you Francesco for initiating this! |
||||
|
||||
|
||||
I want a cross-compiler! What is this toolchain you're speaking about? | |
||||
-----------------------------------------------------------------------+ |
||||
|
||||
A cross-compiler is in fact a collection of different tools set up to |
||||
tightly work together. The tools are arranged in a way that they are |
||||
chained, in a kind of cascade, where the output from one becomes the |
||||
input to another one, to ultimately produce the actual binary code that |
||||
runs on a machine. So, we call this arrangement a "toolchain". When |
||||
a toolchain is meant to generate code for a machine different from the |
||||
machine it runs on, this is called a cross-toolchain. |
||||
|
||||
|
||||
So, what are those components in a toolchain? | |
||||
----------------------------------------------+ |
||||
|
||||
The components that play a role in the toolchain are first and foremost |
||||
the compiler itself. The compiler turns source code (in C, C++, whatever) |
||||
into assembly code. The compiler of choice is the GNU compiler collection, |
||||
well known as 'gcc'. |
||||
|
||||
The assembly code is interpreted by the assembler to generate object code. |
||||
This is done by the binary utilities, such as the GNU 'binutils'. |
||||
|
||||
Once the different object code files have been generated, they got to get |
||||
aggregated together to form the final executable binary. This is called |
||||
linking, and is achieved with the use of a linker. The GNU 'binutils' also |
||||
come with a linker. |
||||
|
||||
So far, we get a complete toolchain that is capable of turning source code |
||||
into actual executable code. Depending on the Operating System, or the lack |
||||
thereof, running on the target, we also need the C library. The C library |
||||
provides a standard abstraction layer that performs basic tasks (such as |
||||
allocating memory, printing output on a terminal, managing file access...). |
||||
There are many C libraries, each targeted to different systems. For the |
||||
Linux /desktop/, there is glibc or even uClibc, for embedded Linux, |
||||
you have a choice of uClibc, while for system without an Operating |
||||
System, you may use newlib, dietlibc, or even none at all. There a few other |
||||
C libraries, but they are not as widely used, and/or are targeted to very |
||||
specific needs (eg. klibc is a very small subset of the C library aimed at |
||||
building constrained initial ramdisks). |
||||
|
||||
Under Linux, the C library needs to know the API to the kernel to decide |
||||
what features are present, and if needed, what emulation to include for |
||||
missing features. That API is provided by the kernel headers. Note: this |
||||
is Linux-specific (and potentially a very few others), the C library on |
||||
other OSes do not need the kernel headers. |
||||
|
||||
|
||||
And now, how do all these components chained together? | |
||||
-------------------------------------------------------+ |
||||
|
||||
So far, all major components have been covered, but yet there is a specific |
||||
order they need to be built. Here we see what the dependencies are, starting |
||||
with the compiler we want to ultimately use. We call that compiler the |
||||
'final compiler'. |
||||
|
||||
- the final compiler needs the C library, to know how to use it, |
||||
but: |
||||
- building the C library requires a compiler |
||||
|
||||
A needs B which needs A. This is the classic chicken'n'egg problem... This |
||||
is solved by building a stripped-down compiler that does not need the C |
||||
library, but is capable of building it. We call it a bootstrap, initial, or |
||||
core compiler. So here is the new dependency list: |
||||
|
||||
- the final compiler needs the C library, to know how to use it, |
||||
- building the C library requires a core compiler |
||||
but: |
||||
- the core compiler needs the C library headers and start files, to know |
||||
how to use the C library |
||||
|
||||
B needs C which needs B. Chicken'n'egg, again. To solve this one, we will |
||||
need to build a C library that will only install its headers and start |
||||
files. The start files are a very few files that gcc needs to be able to |
||||
turn on thread local storage (TLS) on an NPTL system. So now we have: |
||||
|
||||
- the final compiler needs the C library, to know how to use it, |
||||
- building the C library requires a core compiler |
||||
- the core compiler needs the C library headers and start files, to know |
||||
how to use the C library |
||||
but: |
||||
- building the start files require a compiler |
||||
|
||||
Geez... C needs D which needs C, yet again. So we need to build a yet |
||||
simpler compiler, that does not need the headers and does need the start |
||||
files. This compiler is also a bootstrap, initial or core compiler. In order |
||||
to differentiate the two core compilers, let's call that one "core pass 1", |
||||
and the former one "core pass 2". The dependency list becomes: |
||||
|
||||
- the final compiler needs the C library, to know how to use it, |
||||
- building the C library requires a compiler |
||||
- the core pass 2 compiler needs the C library headers and start files, |
||||
to know how to use the C library |
||||
- building the start files requires a compiler |
||||
- we need a core pass 1 compiler |
||||
|
||||
And as we said earlier, the C library also requires the kernel headers. |
||||
There is no requirement for the kernel headers, so end of story in this |
||||
case: |
||||
|
||||
- the final compiler needs the C library, to know how to use it, |
||||
- building the C library requires a core compiler |
||||
- the core pass 2 compiler needs the C library headers and start files, |
||||
to know how to use the C library |
||||
- building the start files requires a compiler and the kernel headers |
||||
- we need a core pass 1 compiler |
||||
|
||||
We need to add a few new requirements. The moment we compile code for the |
||||
target, we need the assembler and the linker. Such code is, of course, |
||||
built from the C library, so we need to build the binutils before the C |
||||
library start files, and the complete C library itself. Also, some code |
||||
in gcc will turn to run on the target as well. Luckily, there is no |
||||
requirement for the binutils. So, our dependency chain is as follows: |
||||
|
||||
- the final compiler needs the C library, to know how to use it, and the |
||||
binutils |
||||
- building the C library requires a core pass 2 compiler and the binutils |
||||
- the core pass 2 compiler needs the C library headers and start files, |
||||
to know how to use the C library, and the binutils |
||||
- building the start files requires a compiler, the kernel headers and the |
||||
binutils |
||||
- the core pass 1 compiler needs the binutils |
||||
|
||||
Which turns in this order to build the components: |
||||
|
||||
1 binutils |
||||
2 core pass 1 compiler |
||||
3 kernel headers |
||||