Building the toolchain

Kai Ruottu
Wed Jul 2 14:32:00 GMT 2008

Rob Emanuele wrote:

> I'm looking for the best way to compile the toolchain from scratch
> with recent versions of binutils (2.18), gcc/g++ (4.2.2), and newlib
> (20080125_cvs_import).  Target is arm-elf which I use on bare metal.
> What I have works great but I have to compile g++ separately and
> disable libssp (see below)
> I compile g++ separately because it goes looking for sys/types.h
> during the build and can't find it if gcc and newlib aren't compiled
> and installed first.  Is that normal?

Yes, producing GCC for system targets - those which have the native GCC
as the default GCC type - requires the target C library (this including
the target headers and target libraries) during the GCC build. Producing
GCC for embedded targets - those which have the cross GCC as the default
GCC type because there cannot be a "native GCC" for these targets -
needs only the target headers during the GCC build. Here the term
"embedded" also means "which uses newlib as its C library"...

Copying the newlib headers from the GCC sources shouldn't require any
"rocket science" but anyhow this seems to be very hard for many, there
seems to be some kind of attitude problem, writing "make install" is OK
but using "cp -r <from> <to>" is something which cannot be written. The
generic newlib headers are in a single include, 'newlib/libc/include' in
the newlib-x.y.z sources. Of course it is expected that a cross GCC
builder knows where the headers should go just a car builder knows
where, in which side of the car, the gasoline tank should be put (inside
the car, not outside... :) If one doesn't know, one then asks...  As
funny as it may sound, there really seems to be some ignorancy about
this very simple fact, just as there is with the gasoline tank in a car
or van (I once found it on the left front side, a little before the
driver's door, not the usual right back side...). For all sanity the
documented '$tooldir/include' aka '$prefix/$target/include' should be
the place (newlib install puts the final headers there) but the GCC
build expects to find the headers (for fixing etc) in the
'$tooldir/sys-include'. So people usually make the 'sys-include' to
be a symlink to the 'include'...

Another possibility is to copy / symlink the 'newlib' and 'libgloss'
subdirectories into the GCC sources, so these would be seen where all
the other target library sources (libiberty, libstdc++, libssp,...) are
seen... Then producing newlib happens during the GCC build.

One thing more to remember is that the "bootstrap" aka "from scratch"
situation happens only once with a toolchain!  After that the situation
is "normal", there already are the target binutils, target GCC and
target C library when one day a new bugfix release appears for binutils,
GCC or C library and one must update this component or them all. The GCC
may have produced bad code in some situations and this could have
happened inside the C library, so after getting a bugfixed GCC, one also
updates the C library with it...

> I still have to disable libssp in the gcc/g++ build because I get
> configure warnings and then compiler errors.  I reported it a while
> ago on the gcc list and in a PR. If it hasn't been fixed, then I'll
> keep working the way I am.
> Libssp warnings from configure:
> checking limits.h usability... no
> checking limits.h presence... yes
> configure: WARNING: limits.h: present but cannot be compiled
> configure: WARNING: limits.h:     check for missing prerequisite headers?
> configure: WARNING: limits.h: see the Autoconf documentation
> configure: WARNING: limits.h:     section "Present But Cannot Be Compiled"
> configure: WARNING: limits.h: proceeding with the preprocessor's result
> configure: WARNING: limits.h: in the future, the compiler will take precedence
> configure: WARNING:     ## --------------------------------- ##
> configure: WARNING:     ## Report this to the libssp lists.  ##
> configure: WARNING:     ## --------------------------------- ##
> checking for limits.h... yes

Seeing whether the target headers have 'limits.h' is one phase in the
'check for existence' operations. As told, this check happens in the
'$tooldir/sys-include'.  If it is there, the GCC's own 'limits.h' will
be edited to '#include_next' the target's own 'limits.h'... If one
hasn't copied/preinstalled the newlib headers (because of that attitude
problem), then of course the newlib's 'limits.h' was found...

> cross-gcc: cross-binutils
>         mkdir -p build/gcc && cd build/gcc && \
>         (./config.status || ../../gcc/configure --prefix=$(PREFIX)
> --target=$(TARGET) --enable-languages="c" --with-gnu-ld --with-gnu-as
> --with-newlib --disable-libssp) && \
>         $(MAKE) && \
>         $(MAKE) install
> cross-g++: cross-binutils cross-gcc cross-newlib
>         mkdir -p build/g++ && cd build/g++ && \
>         (./config.status || ../../gcc/configure --prefix=$(PREFIX)
> --target=$(TARGET) --enable-languages="c++" --with-gnu-ld
> --with-gnu-as --with-newlib --disable-libssp) && \
>         $(MAKE) && \
>         $(MAKE) install

Using '--enable-languages=c,c++' should work and because of the
'--with-newlib', also the 'libssp' configure should succeed with
the bare generic newlib headers being present (preinstalled).

> cross-newlib: cross-binutils cross-gcc
>         mkdir -p build/newlib && cd build/newlib && \
>         (./config.status || ../../newlib/configure --prefix=$(PREFIX)
> --target=$(TARGET)) && \
>         $(MAKE) -j$(PROCS) && \
>         $(MAKE) install

If you look at where those target headers will go, then old advices
like "use the '--with-headers=' when configuring" (this causes the
pointed ('generic headers') being copied to '$tooldir/sys-include'),
be very dangerous because those "system headers" in 'sys-include'
will always be found before the "standard headers" in 'include' !
Some targets will require "target dependent" replacements for some
generic headers and these will be installed into 'include' and then
will not be found if the 'sys-include' still has those generic ones
with the same names :(

You can try to report all these here mentioned "insanities", like the
mess with the include/sys-include but I would be very pessimistic...
What has been there since 1995 totally unfixed, cannot just be "fixed"
until someone of the GCC developers understands that the 'sys-include'
really isn't the install place for the target headers but the 'include'
is that... Or that the normal "target headers" are called as "standard
headers", not "system headers". A native C library installation doesn't
usually have something like "/usr/sys-include" for the "system headers",
although having this kind of header place is possible via defining the
SYSTEM_INCLUDE_DIR in the target configure headers.  But in a cross GCC
the equivalents to the "native" standard and system headers are always

More information about the Newlib mailing list