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 usable...