This post is based on a discussion in
this thread. The basic problem is the following:
In order to use C effectively and in a compiler independent fashion for OS development / writing a kernel, one does not only need a cross compiler for the desired target architecture, but a complete
freestanding environment - that is, a C cross compiler plus a few header files, such as stdint.h, as defined by the C standard (C90, C99 - whatever you prefer). These header files contain things like typedefs for types such as uint32_t, which are hard to define in a compiler independent fashion without these headers (recall that sizeof(int) is implementation defined and not guaranteed to be 32 bits). Fortunately, you get all these C header files for free when you compile and install your GCC cross compiler.
The same problem applies to C++. Standards such as
C++0x define a number of freestanding headers such as cstdint, which basically cover the same typedefs as the C headers, plus / minus some changes. However, unfortunately these header are
not installed if one follows the instructions in the wiki. They are not part of the GCC C++ cross compiler, but instead part of the C++ standard library. GCC comes with its version of the C++ library (called libstdc++-v3), which is not covered by the cross compiler tutorial in the wiki.
Digging through the wiki, I found 3 pages that contain relevant information:
- GCC Cross-Compiler deals with compiling a bare metal cross compiler for both C and C++. While this is sufficient to build a freestanding C compiler environment, it does not suffice for a freestanding C++ compiler environment because it lacks the C++ header files.
- C++ briefly mentions that one needs to port an STL implementation in order to use STL functions in native applications - in other words, it discusses the need for a hosted STL implementation once the kernel is done - but it does not contain any information on the freestanding part of the C++ runtime (i.e., the freestanding headers).
- OS Specific Toolchain also discusses compilation of a hosted version of libstdc++-v3, which requires porting something like glibc or newlib first. Again this is not of much use if one is still in the first stages of kernel development.
So I came to the conclusion that the wiki does not contain a tutorial how to build a full freestanding C++ compiler environment, and I decided to write one on my own. This seemed to be rather simple, because the only thing that's missing in the wiki is how to install the freestanding C++ headers along with a newly built cross compiler. I tried to install these headers with my cross compiler toolchain - and I failed. Maybe someone has already encountered the same problem and can help me figure out how to do it. So here's what I've done:
In the
libstdc++-v3 docs I found that the configure switch "--disable-hosted-libstdcxx" should disable installation of a hosted libstdc++, and enable installation of the freestanding headers only. That's perfectly fine, as this is exactly what I want to do. So I used the following configure command:
Code:
../gcc-x.x.x/configure --target=$TARGET --prefix=$PREFIX --disable-nls --enable-languages=c,c++ --without-headers --disable-hosted-libstdcxx
(with appropriate target (i686-pc-elf), prefix and gcc version (4.5.3), of course) and it worked fine. However, it turned out that even though this switch disables
installing a hosted libstdc++, it still insists on
building a hosted libstdc++ - which of course fails without porting glibc or newlib first. So the following failed:
Code:
make all-target-libstdc++-v3 install-target-libstdc++-v3
The error occurs when make invokes configure in the libstdc++-v3 subdirectory:
Code:
checking for shl_load... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
make[1]: *** [configure-target-libstdc++-v3] Error 1
I found this interesting comment in libstdc++-v3/acinclude.m4:
Code:
dnl
dnl Check if the user only wants a freestanding library implementation.
dnl
dnl --disable-hosted-libstdcxx will turn off most of the library build,
dnl installing only the headers required by [17.4.1.3] and the language
dnl support library. More than that will be built (to keep the Makefiles
dnl conveniently clean), but not installed.
dnl
So does that mean that GCC will try to build the full hosted libstdc++ anyway, just to keeps the Makefiles simpler? By the way, the situation is still the same with the most recent GCC version. Any ideas?