全部博文(584)
分类: LINUX
2009-12-31 15:02:05
Crosstool was originally developed for embedded system developers, but is also useful for mainstream developers who simply want their compiles to go fast or who need to build programs that run on older versions of Linux (e.g. Red Hat 6.2), but don't want to develop on those ancient systems.
It includes minimal patches for gcc and glibc needed to build a few combinations of (alpha, arm, i686, ia64, mips, powerpc, powerpc64, sh4, sparc, sparc64, s390, x86_64) x (gcc-2.95.3 ... gcc-4.0.0) x (glibc-2.1.3 ... glibc-2.3.5).
It also supports building toolchains that target Cygwin; see demo-cygwin.sh.
Crosstool is a portable shell script. You can use it to build linux-targeted compilers that run on Linux, Mac OS X, Solaris, and Cygwin. It includes support for creating hetrogenous build clusters; it lets you use virtually every computer in the building, regardless of operating system or CPU type, to speed up your Linux compiles.
wgetThen look at the demo scripts; there's one for each supported CPU type. For instance, demo-i686.sh is an example of how to build a toolchain that targets the i686 processor. It sets three important variables:
tar -xzvf crosstool-0.43.tar.gz
cd crosstool-0.43
TARBALLS_DIR=$HOME/downloads # where it will save source tarballsIt then builds gcc-3.4.0 and glibc-2.3.2 for i686 with the line
RESULT_TOP=/opt/crosstool # where it will install the tools
GCC_LANGUAGES="c,c++,java,f77" # which languages it will make compilers for
eval `cat i686.dat gcc-3.4.0-glibc-2.3.2.dat` sh all.sh --notestEdit the script if you want to change any of these settings or versions. Then (as root) create the directory /opt/crosstool and make it writable by you, and finally (as yourself) run the demo script, e.g.
sudo mkdir /opt/crosstoolWhen it finishes, you can run the new compiler as /opt/crosstool/gcc-3.4.0-glibc-2.3.2/i686-unknown-linux-gnu/bin/i686-unknown-linux-gnu-gcc. (You might want to put /opt/crosstool/gcc-3.4.0-glibc-2.3.2/i686-unknown-linux-gnu/bin on your PATH; then you can run the compiler as i686-unknown-linux-gnu-gcc.) If for some reason you want the resulting toolchain binaries to be statically linked, set the following environment variables before running crosstool.sh (or all.sh):
sudo chown $USER /opt/crosstool
sh demo-i686.sh
BINUTILS_EXTRA_CONFIG="LDFLAGS=-all-static"Building RPMs of the compiler used to be done by the same shell script, all.sh, with the --buildrpm option, but that was not enough to satisfy real Linux distributions, which require true .src.rpm's. So now the procedure to build an RPM is to first build the .src.rpm, then build the .rpm from that, using rpmbuild in the traditional way.
GCC_EXTRA_CONFIG="LDFLAGS=-static"
A script demonstrating how to build .src.rpm's is buildsrpms.sh. A script demonstrating how to build both .src.rpm's and .rpm's is buildrpms.sh. Both of these are only examples; I use them myself to build a specific set of toolchains.
Each .src.rpm generated by buildsrpms.sh builds toolchains for all supported CPUs, where 'supported' means 'the CPU is listed in the buildlogs directory as having successfully built a working toolchain'. This greatly cuts down on the number of .src.rpm's needed. To build for just e.g. i686, run rpmbuild with options "--without all --with i686".
You can use to distribute compilation across multiple computers for faster compiles. The distcc that comes with your version of Linux will work fine for most cases. However, it may be more convenient to instead use the script 'mkdistcc.sh' included with crosstool to install a crosstool-specific distcc (partly because that's what the mkdistcclinks.sh script assumes, and partly because it includes a patch that improves support for large hetrogenous clusters; see below).To install distcc/distccd from source, run
RESULT_TOP=/opt/crosstool \To set up distccd as a service, run
TARBALLS_DIR=$HOME/downloads \
sh mkdistcc.sh
cd /opt/crosstool
sh common/bin/mkdistcclinks.sh
sudo sh /opt/crosstool/common/bin/install-distccd.sh
Regardless of how you installed crosstool-distcc, you then need to edit /opt/crosstool/common/etc/hosts and append the hostnames of all the computers running your distccd.
You can then run the distributed compiler as /opt/crosstool/gcc-3.3.3-glibc-2.3.2/i686-unknown-linux-gnu/distributed/bin/i686-unknown-linux-gnu-gcc. (You might want to put /opt/crosstool/gcc-3.3.3-glibc-2.3.2/i686-unknown-linux-gnu/distributed/bin on your PATH; then you can run the distributed compiler as i686-unknown-linux-gnu-gcc.)
To get any speed benefit, you'll need to run several compiles in parallel. See e.g. . Also note that only simple compiling with the -c option, not linking, is sped up, and that only C and C++ compiles are distributed (fortran and java compiles are not distributed, sorry).
Getting the best performance out of distcc is a fine art. See e.g. Benjamin Meyer's page "".
You can monitor your distcc jobs by running
/opt/crosstool/common/bin/distccmon-test 5This will display a description of your active remote jobs once every five seconds. Here's a scenario sometimes useful at large universities or companies, where one often has a central file server which all clients access. Crosstool is built for multiple versions of gcc and glibc, once for kind of workstation in the cluster, and installed in e.g. /shared/crosstool/`config.guess`. Compilers are invoked via absolute paths so toolchains with different versions of glibc can be distinguished. The absolute path is built using config.guess so, regardless of which kind of workstation the developer is on, he or she can invoke a compiler that can run on their workstation.
For example, when building a C program for modern x86 linux, developers set
CC=/shared/crosstool/`config.guess`/gcc-3.3.3-glibc-2.3.2/i686-unknown-linux-gnu/distributed/bin/i686-unknown-linux-gnu-gccAnd when building a C program for old Red Hat Linux 6.2 x86, developers might set
CC=/shared/crosstool/`config.guess`/gcc-3.3.3-glibc-2.1.3/i686-unknown-linux-gnu/distributed/bin/i686-unknown-linux-gnu-gcc
A tricky part of this scenario is that the distcc server needs to be able to handle absolute paths for *other* architectures, possibly installed at a different location. The patch patches/distcc-2.14/distcc-stringmap.patch, applied by mkdistcc.sh, adds a feature to the distccd server to read a $prefix/etc/distcc/apps file containing absolute paths to all known compilers, and to ignore all but the last N path components when locating the compiler to satisfy received compile requests. The distccd startup scripts created by crosstool's install-distccd.sh turn on that feature.
gcc-3.4.0's precompiled headers and profile-driven optimization features require lockstep synchronization, so they probably work only if the client and the server are the same CPU type and operating system. (And using pch with distcc may require apple's -fpch-preprocess patch; see )
Those long, strange names of the form "i686-unknown-linux-gnu" are called . The GNU build and test scripts use these extensively. When you run the demo-$CPU.sh script, it sources the $CPU.dat file, which sets a variable TARGET containing the GNU configuration name for the target CPU. For instance, i686.dat contains the lineTARGET=i686-unknown-linux-gnuIn the general case, there can be three machine types: the build machine which builds the compilers, the host machine where the compilers will run, and the target machine for which the compilers will generate code.
Building compilers that will run on some other linux system is called a Canadian Cross. It's useful if, say, you're putting together a hetrogenous build cluster consisting of 32 bit and 64 bit workstations, and you want to run natively compiled compilers on each.
To do a Canadian Cross build with crosstool, you have to run it three times:
If you want the use resulting toolchain as a native toolchain, i.e. if you want it to search /lib and /usr/lib, you'll probably need to edit its specs file to set the cross_compiler parameter to 0; see .
The scripts are fairly generic. You may need to tweak the parameters of the script to match your exact CPU type, or add a few patches needed to the patches/* directories, and run the build script again, if your tests indicate that programs built with the new compiler have problems.
In particular, if your CPU lacks an FPU, you might need to tell glibc that by setting before running all.sh. For example, see powerpc-405.dat, which sets
GLIBC_EXTRA_CONFIG="--without-fp"
Once you trust the toolchain can build and run simple statically linked 'hello, world' programs (see e.g. testhello.sh), test it with real applications.
If you use these scripts to build a toolchain, please send a note to the indicating which platform you used it on, and how well it worked for you. Please be sure to mention which release of the crosstool scripts you used.
If you add support for a new CPU type, please send your changes to the crossgcc mailing list so they can be incorporated in a future release.
If you're targeting i686-linux, and are using a released version of gcc and glibc, you probably don't need to worry about testing the toolchain.But if you're using a new or uncommon CPU type, or an unreleased version of gcc or glibc, and want some assurance that you have built a working compiler and C library, you should run the gcc and glibc test suites. See crosstest-howto.html.
all.sh invokes the four scripts that download, build, and test the toolchain. It takes four options:"soinit.c:25: internal compiler error: in named_section_flags, at varasm.c:..."then you may be running into gcc bug . One workaround is to delete the file gcc-pr-9552-workaround.patch from crosstool/patches/glibc-2.3.2, and rerun. Another is to switch to a different version of binutils (2.14 seems to be the dividing line). You'll need to install GNU Diffutils or GNU Patch, since BSD's patch utility doesn't accept the --fuzz parameter. To build gcc and glibc on Mac OS X, you'll need to install a few gnu utilities:
The way I installed them was using , but or installing from tarballs would probably do as well.
One recurring problem is that various Gnu configure scripts assume that 'as' and 'ld' are the Gnu versions, run them with -v to get the version number, and compare it with some gnu version. That doesn't work well on the Mac. You can either hack the configure scripts to not do that, or write wrapper scripts for as and ld. For instance, here's a wrapper script for as that blatantly lies about what version it is, just to make crosstool happy:
test "$1" = -v && echo GNU assembler 2.13 || /usr/bin/as "$@"Nikolaus Schaller tied all the above into a tidy script; see his which both downloads the needed tools and creates the wrappers for as and ld.
On some (older?) versions of Mac OS X, you'll need to raise the stack size with the command
ulimit -s 8192else make may segfault.
When using 2.6 kernel headers on systems (like Mac OS X) where gcc doesn't support the -shared flag, you may see the error
gcc: unrecognized option `-shared'This is a well-known issue (see e.g. Bertrand Marquis a patch that might help . It would be nice if someone figured out a patch that could go into the mainline kernel sources to deal with this issue.
ld: Undefined symbols:
_main
make[1]: *** [scripts/kconfig/libkconfig.so] Error 1
make: *** [oldconfig] Error 2
Another problem building Linux on Mac OS X is described, together with a Mac OS X specific workaround, by .
Crosstool, and probably gcc and glibc's configure scripts, assume that directory names do not contain any spaces. This is often violated on Windows. Please take care to not use directory names with spaces in them when running crosstool. It might work, but if it doesn't, you've been warned. (Same goes for Mac OS X.)crosstool creates some really deeply nested directories while building, so filenames are quite long. This has two consequences:
First, on some versions of Windows, filenames (including directory) can't be longer than 240 chars. To avoid exceeding this limit, don't run crosstool in a directory with a long name.
Second, the maximum length of commandlines is extremely short. Since crosstool uses commandlines that include multiple filenames, they can exceed the limit very quickly. You can avoid this problem by using the "mount" command's options. e.g. mount /bin and /usr/bin with -X or "-o cygexec" (see , and/or mount the crosstool directory with "-o managed" (see ).
Also, this isn't really a crosstool problem, but configuring linux-2.6 on cygwin may fail with the error
$ make menuconfigA possible fix described e.g. is to patch linux-2.6/scripts/kconfig/Makefile to just use libkconfig.o rather than first making a .so.
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/split-include
HOSTCC scripts/basic/docproc
HOSTLD scripts/kconfig/mconf
collect2: ld terminated with signal 11 [Segmentation fault], core dumped
. You can work around this by updating to Cygwin-1.5.10-2.
Crosstool ought to build on Solaris as long as it has been updated with the appropriate set of GNU tools, but this has not been tested.binutils-2.15 may require to work on Solaris, else it is said to segfault when building the Linux kernel.
glibc documents which GNU tools it requires in . The list is roughly: make 3.79, GCC 3.2, binutils 2.13, texinfo 3.12f, awk 3.0, sed 3.02, or newer. gcc documents a few other requirements in , which says that gcc won't build at all with the default solaris shell, and you're supposed to work around it like this:
% CONFIG_SHELL=/bin/kshbefore running crosstool.
% export CONFIG_SHELL
That page also advises that you may need to install some Solaris patches, and install gcc-3.2.3 or newer before trying to build newer versions of gcc.
Little-endian MIPS
To create a toolchain for the Linksys wrt54g, select glibc-2.2.3. See
Note: recent wrt54g firmware uses uclibc, which behaves like a subsetted glibc. There are patches to build uclibc toolchains in the contrib directory, but they're not integrated yet. However, you can still use a glibc toolchain; you'll either have to
SH3 support is untested... it is said to build, and "hello, world" works, but that's all I've heard.
FIXME: The SH3 is supposedly the same as an SH4 but without the floating point unit, so maybe glibc has to be built --without-fp. See powerpc-405.dat and
Note:
CRIS doesn't build with glibc-2.3.2; fails with "errno-loc.c:39: error: `pthread_descr' undeclared" in glibc build. The cris glibc maintainer is aware of the problem and hopes to fix this later in 2004, but we don't know if this has been done.
We removed cris support, demo-cris.sh, from crosstool. If you need it, you may find it in the previous version of crosstool.
gcc-3.3 doesn't support this, need gcc-3.4 or later.
gcc-3.3 doesn't support this, need gcc-3.4 or later.
If the download hangs, and you need to use a proxy, try telling wget about your proxy before running all.sh by doing
$ export http_proxy=If the download still hangs, download the tarball that's causing the hang manually to the directory specified by TARBALLS_DIR.: