菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
308
0

LFS实践

原创
05/13 14:22
阅读数 69567

用了三天,编译了两次LFS,把LFS的基本流程和原理都弄清了。用的是LFS 6.3,使用的教程是LFS速成手册(6.3) ,感觉很不错,如果按照它的做法,一步一步来,基本都能编译成功而且没什么错误。不过做LFS的目的就是学习,如果没有错误,也就起不到学期的目的的。

 

1.LFS会多次编译binutils,gcc和glibc,原因是令目标系统消除与宿主系统的关系,这里的宿主系统是指liveCD的系统,目标系统是指我们做LFS最终编译出来的系统。引用网上的人的说法:宿主系统就像是母体,目标系统像它的儿子,对这个母体,那是既爱又恨呀,没有她,目标无从生起,有了她,就有了她的血(glibc提供的库)和肉(那套编译工具)。所以lfs中需要多次编译binutils,gcc和glibc,以令目标系统消除与宿主系统的关系。

2.首先介绍一下binutils,gcc和glibc:Binutils 是一组开发工具,包括连接器,汇编器和其它用于目标文件和档案的工具。GCC 软件包包含 GNU 编译器,其中有 C 和 C++ 编译器。 Glibc 包含了主要的C库。这个库提供了基本的例程,用于分配内存、搜索目录、打开关闭文件、读写文件、字串处理、模式匹配、数学计算等等。其它的工具必须在他们的基础上建立。

3.制作工具链的精髓是在.bashrc里面的PATH=/tools/bin:/bin:/usr/bin,原理是首先去/tools/bin(这是我们创建的目录)找工具,没有就去/bin,/usr/bin(这两个是宿主系统的目录),开始编译时由于/tools/bin没有工具,所以会使用宿主系统的工具,编译成功后,/tools/bin就有工具了,然后再次编译,编译就会使用之前编译的工具。从而逐渐减少,最后消除与宿主系统的关系。

4.chroot "$LFS" /tools/bin/env -i HOME=/root TERM="$TERM" PS1='\u:\w\$ ' PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin  /tools/bin/bash --login +h进入chroot环境  这里这是/mnt/lfs(即"$LFS")为默认的根目录。PATH设置为优先去lfs目录下的bin等目录找工具,最后才是/tools/目录,跟第3点的设置类似。

5.LFS编译的步骤以及原理:

步骤 1 2 3 4 5 6 7
编译的软件
binutils(第一遍)
gcc(第一遍)
glibc(第一遍)
调整工具链,由/lib/ld-linux.so.2改到/tools/lib/ld-linux.so.2
gcc(第二遍)
 
binutils(第二遍)
 
安装软件Ncurses
    ,Bash ,Bzip2 ,Coreutils ,Diffutils ,Findutils ,Gawk ,Gettext ,Grep   ,Gzip,Make,Patch,Perl,Sed,Tar,Texinfo,Util-linux
编译的目标目录
/tools
/tools
/tools
/tools
/tools
使用谁的工具
宿主系统
宿主系统
宿主系统
/tools
/tools
步骤 8 9 10 11 12 13  
编译的软件
 
进入chroot环境
glibc(第二遍) 调整工具链,由/tools/lib/ld-linux.so.2改到/lib/ld-linux.so.2(这里的/lib与第一次调整时的/lib不同,因为chroot改变了根目录的位置,这里的/lib是指向目标系统的)
 
binutils(第三遍)
gcc(第三遍)
至此目标系统的编译工具编译完成,下面的软件都用目标系统的编译工具进行编译  
编译的目标目录
  /usr /usr /usr
使用谁的工具  
/tools
目标系统
目标系统

 

6.LFS过程中遇到的问题:

1.编译要在source里面进行,而不是tools
2.在编译内核的时候,输入make mrproper,显示 make mrproper gcc: Internal error: Segmentation fault (program cc1) 即gcc断裂,而且用gcc编译c文件不成功
解决方法是:
    1)调整工具链 1 (使系统用回tools/目录下面的编译器)
代码:
mv -v /tools/bin/{ld,ld-old}
mv -v /tools/$(gcc -dumpmachine)/bin/{ld,ld-old}
mv -v /tools/bin/{ld-new,ld}
ln -sv /tools/bin/ld /tools/$(gcc -dumpmachine)/bin/ld
gcc -dumpspecs | sed 's@^/lib/ld-linux.so.2@/tools&@g' > `dirname $(gcc -print-libgcc-file-name)`/specs
GCC_INCLUDEDIR=`dirname $(gcc -print-libgcc-file-name)`/include &&
find ${GCC_INCLUDEDIR}/* -maxdepth 0 -xtype d -exec rm -rvf '{}' \; &&
rm -vf `grep -l "DO NOT EDIT THIS FILE" ${GCC_INCLUDEDIR}/*` &&
unset GCC_INCLUDEDIR
    2)GCC-4.1.2 - Pass 2 (重复第二次安装gcc的步骤)
代码:
tar xvf /lfs-sources/gcc-4.1.2.tar.bz2
cd gcc-4.1.2
cp -v gcc/Makefile.in{,.orig}
sed 's@\./fixinc\.sh@-c true@' gcc/Makefile.in.orig > gcc/Makefile.in
cp -v gcc/Makefile.in{,.tmp}
sed 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in.tmp \
> gcc/Makefile.in
patch -Np1 -i /lfs-sources/gcc-4.1.2-specs-1.patch
mkdir -v ../gcc-build
cd ../gcc-build
../gcc-4.1.2/configure --prefix=/tools \
--with-local-prefix=/tools \
--enable-clocale=gnu --enable-shared \
--enable-threads=posix --enable-__cxa_atexit \
--enable-languages=c,c++ --disable-libstdcxx-pch
make
make install
cd ..
rm -rf gcc-build
rm -rf gcc-4.1.2
    3)验证gcc安装
echo 'main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep 'tools'
    4)再次调整工具链(用/usr下的编译器)
mv -v /tools/bin/{ld,ld-old}
mv -v /tools/$(gcc -dumpmachine)/bin/{ld,ld-old}
mv -v /tools/bin/{ld-new,ld}
ln -sv /tools/bin/ld /tools/$(gcc -dumpmachine)/bin/ld
    5)再次安装gcc
GCC-4.1.2
代码:
tar xvf $LFS/gcc-4.1.2.tar.bz2
cd gcc-4.1.2
sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in
sed -i 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in
sed -i 's@\./fixinc\.sh@-c true@' gcc/Makefile.in
sed -i 's/@have_mktemp_command@/yes/' gcc/gccbug.in
mkdir -v ../gcc-build
cd ../gcc-build
../gcc-4.1.2/configure --prefix=/usr \
--libexecdir=/usr/lib --enable-shared \
--enable-threads=posix --enable-__cxa_atexit \
--enable-clocale=gnu --enable-languages=c,c++
make
测试:
代码:
make -k check
这里check时间比较长,可能会有一些错误发生
代码:
make install
ln -sv ../usr/bin/cpp /lib
ln -sv gcc /usr/bin/cc
cd ..
rm -rf gcc-build
rm -rf gcc-4.1.2
 
3.grub 中 需要 root (hd0,1) setup(hd0),(hd0,4)等于linux系统中的sda5,0相当于a,4相当于5(从0开始)
4.设置完gurb后重启,从硬盘启动,直接进入grub界面,而不是进入linux系统,后来进入liveCD重装一个grub和内核后,成功解决
 

发表评论

0/200
308 点赞
0 评论
收藏