GCC cross compiler tutorial: full freestanding C++ toolchain
Posted: Wed Aug 03, 2011 10:35 am
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:
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:
(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:
The error occurs when make invokes configure in the libstdc++-v3 subdirectory:
I found this interesting comment in libstdc++-v3/acinclude.m4:
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?
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.
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: Select all
../gcc-x.x.x/configure --target=$TARGET --prefix=$PREFIX --disable-nls --enable-languages=c,c++ --without-headers --disable-hosted-libstdcxx
Code: Select all
make all-target-libstdc++-v3 install-target-libstdc++-v3
Code: Select all
checking for shl_load... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
make[1]: *** [configure-target-libstdc++-v3] Error 1
Code: Select all
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