【发布时间】:2017-03-15 23:52:01
【问题描述】:
相信我,我已经花了很长时间在谷歌上搜索,但没有什么结果。
我正在编写一个非常基本的操作系统作为一个有趣的项目。由于显而易见的原因,它需要编译成一个独立的形式(在我的例子中是 i686-elf)。但是我已经决定纯 C 对我来说是不够的,我很想使用 C++。所以我写了一些代码,它似乎工作了,所以我继续,尽管代码没有明显的问题,但突然间我一直收到同样的错误。
./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'
经过一番谷歌搜索后,我发现问题一定是我的 g++ 交叉编译器缺少 c++ 库,事实证明这是真的。它确实只包含 libgcc 和 libgcov。所以我想我会以某种方式得到它们,但结果证明这是一项相当困难的任务。几乎不可能找到已经编译的 libstdc++.a。所以我不得不自己编译它,由于我对 makefile 不是特别熟悉,所以肯定不容易弄清楚。
最后,我找到了一个 bash 脚本,它可以让我做我需要做的事情。它下载 gcc 6.1.0、binutils,配置两者并运行 make、make install。如果它真的有效,那就太好了。至少据我所知,编译器本身就像一个魅力,但无论我做什么,这个库都不会工作,因为至少我怀疑它是为不同的目标平台构建的,出于某种原因。看来 libstdc++ 根本无法为 i686-elf 或类似的东西构建。
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
我的编译/链接脚本(这样你就可以看到 g++ 参数):
${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++
当我尝试链接这些库(libstdc++ 和 libsupc++ 的版本似乎是 elf32-i386,与 i686-elf 最接近)时,我停止收到 undefined reference to __gxx_personality_v0,但我仍然收到少数似乎是 C 函数的未定义引用。 (abort, strlen, malloc, free)
不使用模板、类析构函数和更多特定于 c++ 的东西可以避免整个问题(具有讽刺意味的是,单独的类似乎在大多数情况下都可以正常工作),但对我来说这似乎不是一个很好的解决方案.我宁愿接触这些东西。
有人可以向我解释我做错了什么吗?
【问题讨论】:
-
" 几乎不可能找到已经编译好的 libstdc++.a" 嗯,不。这很容易(对于任何给定的发行版)。但是该死的,你似乎在跳过箍来解决你不应该遇到的问题。事情通常没有那么难(除非 ylu 只是“做错了”)。
-
错误信息显示了答案。 stackoverflow.com/questions/6045809/…
-
@jesper 怎么这么容易?如果你能找到它,请给我链接 i686-elf 的库。至少一个小时我根本找不到任何东西。
-
@sailfish009 不,它没有,它实际上什么也没说。我无法让 libstdc++ 工作,因此我无法链接它。
标签: c++ linux linker g++ libstdc++