Believe me I've spent quite some time Googling without much of an outcome.
I'm writing a very basic OS as a fun project. It, for obvious reasons, needs to be compiled into a standalone form (i686-elf in my case). However I've decided that pure C isn't enough for me and that I'd love to use C++. So I've written a bit of code and it seemed to work, so I went on and all of sudden I kept getting the same error despite no obvious problem with the code.
./sh/../obj/class_string.o:(.eh_frame+0x4f): undefined reference to __gxx_personality_v0'
./sh/../obj/kernel.o:(.eh_frame+0x13): undefined reference to __gxx_personality_v0'
/home/natiiix/crosscompiler/out/path/bin/../lib/gcc/i686-elf/6.1.0/libgcc.a(unwind-dw2.o): In function read_encoded_value_with_base':
/home/natiiix/crosscompiler/out/src/build-gcc/i686-elf/libgcc/../../../gcc-6.1.0/libgcc/unwind-pe.h:257: undefined reference to abort'
After a bit of Googling I've figured out the problem must be that my g++ cross-compiler lacks c++ libs, which turned out to be true. It indeed contains just libgcc and libgcov. So I've figured out I'd get them somehow, but it turned out to be quite a difficult task to do. It's virtually impossible to find the already compiled libstdc++.a. So I had to compile it myself and as I'm not particularly familiar with makefile it definitely wasn't easy to figure out.
Finally I've found a bash script that somewhat allowed me to do what I needed. It downloads gcc 6.1.0, binutils, configures both and runs make, make install. That would be really nice if it actually worked. The compiler itself works like a charm as far as I can tell at least, but the library won't work no matter what I do since, at least I suspect, it is being built for a different target platform for some reason. It appears that libstdc++ simply cannot be built for i686-elf or something along the lines.
gccbuild.sh:
#!/bin/bash
set -e
if [ "$#" -ne 1 ]; then
echo "Supply one parameter: the target to use!!"
exit 1
fi
sudo apt install libgmp3-dev libmpfr-dev libisl-dev libcloog-isl-dev libmpc-dev texinfo -y
cd "$(dirname "$0")"
rm -rfv out/
mkdir out/
cd out/
rm -rfv path/
mkdir path/
rm -rfv src/
mkdir src/
cd src/
wget ftp://ftp.gnu.org/gnu/binutils/binutils-2.26.tar.gz
wget ftp://ftp.gnu.org/gnu/gcc/gcc-6.1.0/gcc-6.1.0.tar.gz
tar -xvzf binutils-2.26.tar.gz
tar -xvzf gcc-6.1.0.tar.gz
export PREFIX="$(pwd)/../path/"
export TARGET=$1
export PATH="$PREFIX/bin:$PATH"
rm -rfv build-binutils/
mkdir build-binutils/
cd build-binutils/
../binutils-2.26/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --disable-werror
make
make install
cd ..
rm -rfv build-gcc/
mkdir build-gcc/
cd build-gcc/
../gcc-6.1.0/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc
../gcc-6.1.0/libstdc++-v3/configure --host=$TARGET --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --disable-libstdcxx-threads
make
make install
My compile / link script (so that you can see the g++ arguments):
${BASH_SOURCE%/*}/../../crosscompiler/out/path/bin/i686-elf-g++ -c ${BASH_SOURCE%/*}/../src/*.cpp --std=c++11 -ffreestanding -O2 -Wall -Wextra
echo moving object files from active directory to obj/
mv *.o ${BASH_SOURCE%/*}/../obj/
${BASH_SOURCE%/*}/../../crosscompiler/out/path/bin/i686-elf-g++ -T ${BASH_SOURCE%/*}/../src/linker.ld -o ${BASH_SOURCE%/*}/../bin/kokos.bin -ffreestanding -O2 -nostdlib ${BASH_SOURCE%/*}/../obj/*.o -lgcc -lstdc++ -lsupc++
When I try to link those libraries (versions of libstdc++ and libsupc++ that appear to be elf32-i386, which is as close as they get to the i686-elf) I stop getting the undefined reference to __gxx_personality_v0
, but I still get a handful of undefined references to what appear to be C functions. (abort, strlen, malloc, free)
The whole problem can be avoided by not using templates, class destructors and some more c++ specific stuff (ironically classes alone seem to work just fine for the most part), but it doesn't seem like a very good solution to me. I'd rather have access to such things.
Could someone please explain to me what have I done wrong?