[英]Cross-compile and link libstdc++ for i686-elf (using g++ on Ubuntu 16.04)
相信我,我花了很多时间在Google搜寻上没有多大成果。
我正在编写一个非常基本的OS,作为一个有趣的项目。 由于明显的原因,它需要编译成独立形式(在我的情况下为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++
当我尝试链接那些库(似乎是elf32-i386的libstdc ++和libsupc ++版本)时,我不再获得undefined reference to __gxx_personality_v0
的undefined reference to __gxx_personality_v0
,但是我仍然得到了一些对似乎是C函数的未定义引用。 (中止,strlen,malloc,免费)
可以通过不使用模板,类析构函数和其他一些c ++特定的东西(讽刺地是,类本身在大多数情况下似乎都可以正常工作)来避免整个问题,但这对我来说似乎不是一个很好的解决方案。 我宁愿接触这些东西。
有人可以告诉我我做错了什么吗?
从您的帖子中还不清楚您要获得什么确切结果。 下面是一些观察结果,它们可以帮助您弄清楚真正的问题是什么。
-m32
编译即可。 -march=
,- -mcpu=
和-mtune=
选项。 sudo apt-get install libstdc++-6-dev:i386
,它还将安装所有必需的依赖项。 然后只需使用gcc -m32 -static
编译程序。 -march=i386
选项来构建libc,Ubuntu 16.10使用-march=i686
)。 -nostdlib
和-lstdc++
而不是-lc
。 libstdc++
使用标准C库中的函数,因此您需要它。 -lsupc++ -lgcc
,此外,如果您使用异常处理(并且libgcc_eh.a
是__gxx_personality_v0
来源),则还需要-lgcc_eh
。 不要在独立的环境中使用-lstdc++
! 希望这会有所帮助,并祝您好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.