Chinaunix首页 | 论坛 | 博客
  • 博客访问: 200531
  • 博文数量: 62
  • 博客积分: 725
  • 博客等级: 上士
  • 技术积分: 746
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-09 17:07
个人简介

exyz

文章分类

全部博文(62)

分类: LINUX

2013-05-19 15:13:16

    第一部分:准备工作----

  1. =====================LFS 学习日志=============================
  2. 第一章:LFS准备
  3. 一:笔记本里安装了CentOS 6.0【大小20G】 ,通过putty登录CentOS,通过SSH传递文件。
  4.   关于笔记本如何与虚拟机里面的CentOS主机进行通信,本次步骤如下:
  5.     ①设置:
  6.         开启虚拟机前,将网络设置选择自定义虚拟网络(Custom Virtual Network)里面的VMnet8(NAT)
  7.         同时确保笔记本的VMnet8已经开启。
  8.     ②配置:
  9.         在笔记本cmd下,输入ipconfig /all,查找VMnet8的ip地址,如本次的192.168.13.,掩码值为255.255.255..
  10.         然后在设置了第①步的虚拟机中的CentOS终端下输入:ifconfig eth0 192.168.13.2 netmask 255.255.255.0 (eth0为默认的以太网卡)以给其配置一个ip。
  11.     ③测试:
  12.         在笔记本cmd下,ping 192.168.13.,该ip为CentOS的ip地址,如果通表示虚拟机与笔记本建立通信成功。


  13. 二:安装完系统后将CentOS 6.0 安装ISO文件用ssh传上去,默认传到/media/uploas目录中,然后挂载到/media/CentOS上,修改了/etc/yum.respon.d下的文件,建立的CentOS的yum源。
            挂载CentOS镜像到系统本地
                #mkdir /media/CentOS
                #mount -o loop /media/uploads/CentOS-6.0-i386-bin-DVD.iso  /media/CentOS/
                #echo "mount -o loop /media/uploads/CentOS-6.0-i386-bin-DVD.iso  /media/CentOS/" > mountOS    ;生成脚本供下次使用
                #cd /etc/yum.repos.d/
                #mv CentOS-Base.repo CentOS-Base.repo.bak
                #vi CentOS-Media.repo 
                    ----------------------------
                        [c6-media]
                        name=CentOS-$releasever - Media
                        baseurl=file:///media/CentOS/                ;这个是重点
                        file:///media/cdrom/
                        file:///media/cdrecorder/
                        gpgcheck=1
                        enabled=1                                    ;这个要改的
                        gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
                    ----------------------------


  1.     紧接着,进行宿主系统需求检测了,把命令用ssh传上去一执行就出现了一坨的错误了。
  2.     首先是export LC_ALL=C,它在直接执行下木得问题,但放在script中就一直说它用不了什么的,然后就不用这个脚本了,一行一行的执行。
  3.     CentOS 6.0 的软件包版本基本是符合LFS 7.2的软件要求的,除了xz的版本稍稍低了点,相关版本对比文件查看version.sh文件。
  4.     
  5.     !!!    #yum install bison         ;解决找不到bison程序问题,因centos 6.0默认不安装此软件
  6.     !!!    #yum install byacc        ;解决找不到yacc程序问题,
  7.     !!!    #yum install texinfo         ;解决找不到textinfo程序问题,

  8.     完成之后可以检查了:
  9.   
    #cat > version-check.sh << "EOF" 
    #!/bin/bash
    # Simple script to list version numbers of critical development tools
    
    export LC_ALL=C
    bash --version | head -n1 | cut -d" " -f2-4
    echo "/bin/sh -> `readlink -f /bin/sh`"
    echo -n "Binutils: "; ld --version | head -n1 | cut -d" " -f3-
    bison --version | head -n1
    if [ -e /usr/bin/yacc ];
      then echo "/usr/bin/yacc -> `readlink -f /usr/bin/yacc`"; 
      else echo "yacc not found"; fi
    
    bzip2 --version 2>&1 < /dev/null | head -n1 | cut -d" " -f1,6-
    echo -n "Coreutils: "; chown --version | head -n1 | cut -d")" -f2
    diff --version | head -n1
    find --version | head -n1
    gawk --version | head -n1
    if [ -e /usr/bin/awk ];
      then echo "/usr/bin/awk -> `readlink -f /usr/bin/awk`"; 
      else echo "awk not found"; fi
    
    gcc --version | head -n1
    ldd --version | head -n1 | cut -d" " -f2-  # glibc version
    grep --version | head -n1
    gzip --version | head -n1
    cat /proc/version
    m4 --version | head -n1
    make --version | head -n1
    patch --version | head -n1
    echo Perl `perl -V:version`
    sed --version | head -n1
    tar --version | head -n1
    echo "Texinfo: `makeinfo --version | head -n1`"
    xz --version | head -n1
    
    echo 'main(){}' > dummy.c && gcc -o dummy dummy.c
    if [ -x dummy ] 
      then echo "gcc compilation OK";
      else echo "gcc compilation failed"; fi
    rm -f dummy.c dummy EOF
    #bash version-check.sh     //测试是否有通过!!!


  10. ********** written at 2013-01-19 23:23 ************
  11.     


  12. 三:LFS系统的分区已经文件格式的建立
            
  1. 3.1   分区废话说明

  2.     分区大小至少10G,要创建swap分区,以弥补RAM(内存)的不足,其实swap分区完全可以使用宿主系统的。
  3.     使用cdisk或fdisk创建分区。更多的关于 RAID和 LVM分区的创建,不在此涉及。
  4.     记住分区的名字,稍后在 /etc/fstab 文件中会被用到。
  5.     必备分区:    
  6.         /     根分区(而不是 /root 分区),10G大小足够,但是用于扩展的话是不够的。
  7.         swap    交换分区,一般为物理内存(RAM)的两倍,如果磁盘空间受限,创建2G好了,
  8.             然后使用模拟的磁盘交换空间。
  9.     可选分区:
  10.         /boot    推荐,用来存储内核和引导信息,100 mb 足够的,确保这个物理分区在第一块磁盘上。
  11.         /home    推荐,这个分区应该大点,用于存储文件。
  12.         /usr    瘦客户端和无盘工作站的服务器的使用目录,对LFS不使用,5GB足够。
  13.         /opt    对于BLFS用来安装Gnome或者KDE是需要大的空间的,通常5~10GB是足够的。
  14.         /tmp    一个独立的/tmp 目录是很少的,但是它常用于配置瘦客户端,如果用不需要超过2G。
  15.         /usr/src对于BLFS的文件存储和对构造LFS共享是有用的,大约30~50GB吧。
  16.     任何单独的分区需要挂载的话,可以在文件 /etc/fstab 中声明。

        3.2分区开始了
             在虚拟机中新加了一块硬盘,大小为30G,类型为SCSI。
  1.     (/dev/sda 为宿主系统的磁盘名, /dev/sdb 为要建立LFS系统的磁盘名,即目标磁盘)
  2.     ①分区:
  3.         #fdisk /dev/sdb
  4.             ):m    //请求帮助
  5.             ):p    //打印分区表
  6.     [因为默认使用的新盘符,如果是使用过的,使用d+n(n为分区序号)]删除再操作    
  7.         #    ):):p    ):1     ):【Enter】 (使用默认的起始位置) )+100M (作为/boot分区)
  8.         #    ):):p    ):2     ):【Enter】 (使用承接上面的位置) )+2048M (作为swapt分区)
  9.         #    ):):p    ):3     ):【Enter】 (使用承接上面的位置) ):【Enter】 (默认使用后面所有的空间)
  10.         >write     保存退出! 
  11.     ②创建文件系统:
  12.         #mke2fs -jv /dev/sdb1
  13.         #mkswap /dev/sdb2
  14.         #mke2fs -jv /dev/sdb3
  15.             使用 #debugfs -R feature /dev/sdb1 或者 /dev/sdb3 可以看到与下面的内容相同:
  16.             has_journal, ext_attr, resize_inode, dir_index, filetype, sparse_super, large_file or needs_recovery。
  17.     ③挂载各分区(挂载分区如果与selinux相冲突的话,可将sellinux关闭重启再进行挂载)
  18.         # export LFS=/mnt/lfs            设置环境变量,expor导入到全局变量中
  19.         # mkdir -pv $LFS            创建/ 目录挂载点,-p 可以一次建立多个目录,-v versbos 表示回显信息
  20.         # mount --t ext3 /dev/sdb3 $LFS    挂载/ 目录
  21.         # mkdir -pv $LFS/boot            创建/boot 挂载点
  22.         # mount --t ext3 /dev/sdb1 $LFS/boot    挂载/boot 目录
  23.         # /sbin/swapon -/dev/sdb2        激活swap分区

  24.     ④下载包和补丁
  25.         #mkdir -v $LFS/sources            创建存储源代码的地方
  26.         #chmod -a+wt $LFS/sources        使这个目录具有可写和黏着性
  27.         将包和md5sums文件下载到 $LFS/sources目录中:
  28.         #pushd $LFS/sources            存储一个目录以备用户使用
  29.         #md5sum -c md5sums            用md5程序检验下载包的每个md5值是否正确
  30.         #popd                    将当前目录更改到最近, pushd命令存储目录

  31.  四:最后的准备

  32.      1.因为 $LFS 变量有一直在用,所有要时刻确保 改变的存在,已经正确的存在。
                    #echo $LFS
                   同时也确保它的子目录 $LFS/boot 、$LFS/sources 的存在。
                尤其在你用 su 切换用户的时候!!!

         2.创建 $LFS/tools 目录,它是独立的,在第6章会被抛弃,为什么?因为它的诞生只是为了使得lfs初期的构造能够使用宿主系统的编译器,链接器等工具罢了。
                    #mkdir -v $LFS/tools
                  然后为它创建到宿主系统的符号链接,那么它会被指向系统的 /tools 分区
                    #ln -sv $LFS/tools  /
                 
                ********** modified at 2013-05-17 20:14 ************

             3.增加 lfs 用户
                    使用lfs用户而不是用root是为了将系统的可能造成的损失降到最小,同时在增加lfs用户名也会新增lfs用户组。
                    #groupadd lfs
                    
#useradd -s /bin/bash -g lfs -m -k /dev/null lfs
                        解释:-s shell,-g group,-m 用户登录目录,-k 重写/etc/login.defs内容
                    #passwd lfs
                    #chown -v lfs $LFS/tools
                    #chown -v lfs $LFS/sources
                    #su - lfs        
                    为lfs用户设置密码,赋权之后,切换到lfs用户。
             4.最后的准备:设置环境
                    创建2个新的启动脚本,能够让lfs用户登录的时候用到。
                    # cat > ~/.bash_profile << "EOF"
                    > exec env -i HOME=$HOME TERM=$TERM PS1='\u:\v\$' /bin/bash
                    > EOF
                    当用户登录时替换成一个新的bash环境,而不会替换掉 HOME、TERM、PS1变量。这样确保不想要的和垃圾环境变量从宿主系统中泄露到构造环境中,这样确保构造的 lfs 系统是干净的。
                    新的 shell 是一个 non-login shell,它不会读取 /etc/profile 或 .bash_profile ,但是会立即读取.bashrc 文件。创建 .bashrc 文件:
                      #cat > ~/.bashrc << "EOF"
                      set +h
                      umask 022
                      LFS=/mnt/lfs
                      LC_ALL=POSIX
                      LFS_TGT=$(uname -m)-lfs-linux-gnu PATH=/tools/bin:/bin:/usr/bin
                      export LFS LC_ALL LFS_TGT PATH
                      EOF   
               
                        解释: set +h ,关闭了bash的hash功能,hash是bash用来建立hash表,以减少搜索可执行文件位置花费的时间。
                        因为新的工具在 $LFS/tools 中会不断的增加,我们需要它不断的去搜索,而不是去查表,避免它搜索不到我们需要的命令。
                       umask 022  ,新的文件和文件夹,只能被所有者读写和执行,所属组和其它用户只读写。
                       LC_ALL=POSIX    ,LC (Location Of Certain Program)特定程序的本土化。 “POSIX” or “C” 是等价的,它确保所有的事物能在chroot环境中正常工作。
                       LFS_TGT   ,设置了非默认的机器称呼。
                       PATH 结合关闭了bash的hash功能,同时限制lfs从宿主系统搜索老的程序的问题。
                
                       脚本写完,立即启用:
                       #source ~/.bash_profile  

                5.关于 SBUs(标准构造单元)
                        想要酷睿 2支持2个处理器同时工作:#export MAKEFLAGS='-j 2' 或者构造时用 #make -j2

                6.关于测试事宜
                        大部分包提供了测试。新安装的包测试下是有好处的,它可以提供完整性检查。
                        有些包是必须测试的,如GCC, Binutils, 和 Glibc,虽然过程很慢,但是这是必须的。
                        在第5章,不建议每一个人都运行测试,因为那一章常常会导致很多费解的错误出现。那些测试指导是给测试人员和开发者受益的,所以,记住,它们是可选的。
                        关于Binutils 和 GCC 在伪终端的测试大多数问题是由于没有正确的安装devpts文件系统,。
                        一些包的测试失败,可以相关的日志看看这些包错误是否为预期的。
                 ********** written at 2013-05-18 11:07 ************



    温馨提示:   每次宿主机器重启之后要做的设置(●表示必须做的设置)[ 这些设置是以 root 身份才能干的事 ]


  1. ●export LFS=/mnt/lfs         设置环境变量
  2.     #mkdir -pv $LFS         创建/ 目录挂载点(此命令貌似也不再需要了
  3. ●mount -v -t ext3 /dev/sdb3 $LFS     挂载/ 目录(以下目录貌似都自动挂载好了!)
  4.     #mkdir -pv $LFS/boot      创建/boot 挂载点
  5.     #mount -v -t ext3 /dev/sdb1 $LFS/boot 挂载/boot 目录
  6. /sbin/swapon -v /dev/sdb2      激活swap分区


  7. 检查
  8. #echo $LFS
  9. #ls /mnt/lfs            确保能看到 boot、lost+found、sources、tools
  10. #ls /tools            如果没有,“#ln -sv $LFS/tools /



    第五章:构造一个临时的系统

  1. 5.1 介绍
  2.         这章主要是构造一个最小的系统。这个系统提供了必要的工具能够在第六章构造最终的LFS系统。
  3.         分2个步骤走:
  4.                 第一步:构造一个新的依赖宿主系统的工具链(toolchain);
  5.                 第二步:用这个工具链(toolchain去构造一些其它的必要的工具。
  6.         这章主要在 $LFS/tools 目录中进行工作,让它们与在下章安装的文件进行分离,它们是临时的,而不应该有污染到新的LFS系统。


       
  1. 5.2 Toolchain 技术笔记
  2.        这章内容应该随时用来进行参考!
  3.        第五章的整体目标是构造一个临时的区域,这个区域包含了一套有效的工具链,它能够从宿主系统中独立出来。
  4.        使用chroot来进入这个区域,确保拥有一个干净的、无故障的LFS系统。
  5.             1.稍微的调整工作平台的名称,它存在LFS_TGT中。第一次的Glibc和Binutils能产生一个兼容性的交叉链接器和交叉编译器。这个交叉工具能产生适应当前硬件的二进制文件。
  6.             2.这个临时的类库是交叉编译的。交叉编译器按道理是不依赖于宿主系统的。

  7.       编译的东东有Binutils->GCC->Glibc->Binutils->GCC
  8.        Binutils首先安装因为configure运行GCC和Glibc上执行各种功能的测试,以确定哪些软件功能来启用或禁用的汇编器和链接。如果一个不正确的Gcc和Glibc的安装可能在你整个构造的最后才会表现出来,所以建议测试Binutils的安装。
  9.        Binutils安装它的编译器和链接器在2个地方,/tools/bin、/tools/$LFS_TGT/bin,它们是以链接形式存在的。
  10.                 它有个类库搜索顺序,查看使用 #ld --verbose | grep SEARCH 
  11.                 #gcc dummy.c -Wl,--verbose 2>&1 | grep successed 会显示在执行过程中成功链接的文件。 
  12.  
  13.         接下来是GCC的安装。
  14.         在执行 configure 的时候可能看到的样子是:
  15.          checking what assembler to use... /tools/i686-lfs-linux-gnu/bin/as
             checking what linker to use... /tools/i686-lfs-linux-gnu/bin/ld
  16.         为了确认gcc使用的是哪个链接器,使用:#gcc -print-prog-name=ld 。

  17.        接下来要安装的是标准的Linux API 头文件,它提供了标准的C类库(Glibc) 来接口Linux内核提供的特征。
  18.        所以要安装的是Glibc了。它主要考虑的是编译器,二进制工具和内核头文件。
  19.             对于编译器,不是一个问题,需要在脚本中设置--host参数指向我们的编译器脚本即可。
  20.             对于二进制工具和内核头文件,可能麻烦点。在运行configure 之后检查glibc-build目录中的config.make文件以查找所有有用的信息。注意,用 CC=“i686-lfs-gun-gcc” 来控制哪一个二进制工具会被使用,用 -nostdinc 和 -isystem标识来控制编译器包含的搜索路径。

  21.         第二次 Binutils编译通过,我们才能够用 --with-lib-path来配置控制ld的类库搜索路径。
  22.        第二次的GCC的通过,它的源码需要修改来告诉GCC使用心得动态链接器,如果修改失败会导致GCC使用宿主系统的/lib目录类库来嵌入它自身中。这样就脱离不了宿主系统了。
  23.        到这里了,核心的 toolchain 能够自给了,同时不依赖宿主机了。
  24.     
  25.        到第六章用chroot进入环境时,第一个要安装的包就是Glibc了,因为它需要自给。一旦Glibc安装在/urs 目录中,需要立即切换默认的工具链(toolchain),然后才能够继续下面的工作。



  1.  5.3 通用的编译指导
  2.     * 对于一些包需要 Patch ,不能够忽视它们,当应用Patch时会有offset和fuzz,不要担心这些警告,这些Patch仍然能成功的应用。
  3.     * 编译大部分的包时,可能会有警告信息滚动在屏幕上。它们可以正常和安全的被忽略掉。这不是问题,但确实是提示警告。
  4.     * 最后一次确认 LFS 在变量环境中有效 #echo $LFS ,显示的应该是 /mnt/lfs
  5.     
  6.     重要的提示::
  7.         1.将所有的资源文件和patches放到一个能chroot环境中的目录,如 /mnt/lfs/sources/ 。 不要放在 /mnt/lfs/tools中。
  8.         2.切换到 资源目录。
  9.         3.对于每一个包:
  10.             a。 使用 tar 程序,解压要构造的包。 在第 5 章中,确保你使用 lfs 用户解压构造这些包。
  11.             b。 切换到包解压后所在的目录
  12.             c。 安装本指导构造这些包
  13.             d。 切回资源目录
  14.             e。 删除解压后的资源目录和任何在构造过程中产生 >-build 目录,除了指导中特别说明不能删的。 
  15.  
  16.  5.4    
  17. =======================================
     ***** binutils 第一次编译
    =======================================

  18.             /**/安装binutils的patch            
  19.             #patch -Np1 -i ../binutils-2.22-build_fix-1.patch
  20.                 有提示的输入时候,输入binutils的包名: 
  21.             
  22.             /**/创建需要的编译目录,配置——>安装
                #mkdir -v  ../binutils-build
                #cd ../binutils-build
                #../binutils-2.22/configure     \
                    --prefix=/tools            \
                    --with-sysroot=$LFS        \
                    --with-lib-path=/tools/lib \
                    --target=$LFS_TGT          \
                    --disable-nls              \
                    --disable-werror
                #make
                #make install


    =======================================
     ***** GCC 第一次编译
    =======================================
  23.             gcc 需要GMP、MPFR、MPC包。它们将和GCC一起编译。
  24.             将它们分别解压到GCC的目录中,去掉各版本。

  25.             /**/解压gcc包
                #cd  ..
                #tar xvf gcc.4.7.1.tar.bz2

                /**/解压mpfr包
                #tar -Jxf mpfr-3.1.1.tar.xz
                #mv  mpfr-3.1.1  gcc-4.7.1/mpfr

                /**/解压gmp包
                #tar -Jxf  gmp-5.0.5.tar.xz
                #mv -v gmp-5.0.5 gcc-4.7.1/gmp

                /**/解压mpc包
                #tar -zxf  mpc-1.0.tar.gz
                #mv -v mpc-1.0 mpc

  26.             -------------------------------------
                改变GCC的默认动态链接器的位置,使用在/tools目录中的
                同时移除了GCC包含的搜索路径 /usr/include 
                -------------------------------------
                #for file in \
                 $(find gcc/config -name linux64.h -o -name linux.h -o -name sysv4.h)
                  do
                    cp -uv $file{,.orig}
                    sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \
                        -e 's@/usr@/tools@g' $file.orig > $file
                    echo '
                  #undef STANDARD_STARTFILE_PREFIX_1
                  #undef STANDARD_STARTFILE_PREFIX_2
                  #define STANDARD_STARTFILE_PREFIX_1 "/tools/lib/"
                  #define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
                    touch $file.orig
                  done


                -------------------------------------
                GCC 不会正确检测堆栈保护,会导致Glibc
                构造出错,用下面的命令修正
                -------------------------------------
                #sed -i '/k prot/agcc_cv_libc_provides_ssp=yes' gcc/configure

                /**/编译(编译这货真的要很久很久。。。。)->安装
                #mkdir -v ../gcc-build
                #cd ../gcc-build
                #../gcc-4.7.1/configure         \
                    --target=$LFS_TGT          \
                    --prefix=/tools            \
                    --with-sysroot=$LFS        \
                    --with-newlib              \
                    --without-headers          \
                    --with-local-prefix=/tools \
                    --with-native-system-header-dir=/tools/include \
                    --disable-nls              \
                    --disable-shared           \
                    --disable-multilib         \
                    --disable-decimal-float    \
                    --disable-threads          \
                    --disable-libmudflap       \
                    --disable-libssp           \
                    --disable-libgomp          \
                    --disable-libquadmath      \
                    --enable-languages=c       \
                    --with-mpfr-include=$(pwd)/../gcc-4.7.1/mpfr/src \
                    --with-mpfr-lib=$(pwd)/mpfr/src/.libs

  27.             #make 
                #make install 
                #ln -vs libgcc.a `$LFS_TGT-gcc -print-libgcc-file-name | sed 's/libgcc/&_eh/'`

  28.  
    =======================================
     **** 安装 Linux-3.5.2 API 头文件
    =======================================

    #make mrproper
    #make headers_check
    #make INSTALL_HDR_PATH=dest headers_install
    #cp -rv dest/include/* /tools/include

  29. =======================================
      *****  安装Glibc
    =======================================

    /* 确保rpc存在于宿主系统中 */
    #if [ ! -r /usr/include/rpc/types.h ]; then 
      su -c 'mkdir -p /usr/include/rpc'
      su -c 'cp -v sunrpc/rpc/*.h /usr/include/rpc'
    fi

    /* 用GCC-4.7.1修补构造Glibc-2.16.0的一个小问题 */
    #sed -i 's/ -lgcc_s//' Makeconfig

  30. #mkdir -v ../glibc-build
    #cd ../glibc-build
    #../glibc-2.16.0/configure                             \
          --prefix=/tools                                 \
          --host=$LFS_TGT                                 \
          --build=$(../glibc-2.16.0/scripts/config.guess) \
          --disable-profile                               \
          --enable-add-ons                                \
          --enable-kernel=2.6.25                          \
          --with-headers=/tools/include                   \
          libc_cv_forced_unwind=yes                       \
          libc_cv_ctors_header=yes                        \
          libc_cv_c_cleanup=yes
    #make
    #make install

  31. /* 善后处理,因为编译此包有留过2个文件夹,所以2个都有删除掉! */
  32. #cd /mnt/lfs/sources
  33. #rm  -rf  glibc-build
  34. #rm  -rf glibc-2.16.0


  1. *******************************************
      测试编译器和链接器能正常工作 
    *******************************************
    #echo 'main(){}' > dummy.c
    #$LFS_TGT-gcc dummy.c
    #readelf -l a.out | grep ': /tools'

    如果工作正常,应该没有错误,输出的最后一个命令会是:
        [Requesting program interpreter: /tools/lib/ld-linux.so.2]
    如果没有输出出现或者压根没有输出,那么表示出问题了。
    追究每步,然后找到问题出在哪里,然后纠正它。这个问题必须更正!
    如果都好了,清楚测试文件:
    #rm -v dummy.c a.out
    如果Binutils 构造是不,那么预测者之前的Binutils、 GCC或者Glibc安装失败了。
  2.         
  3.     ********** written at  2013-05-20  21:26 ************
  4.  

  1.    =======================================
       ***** binutils 第二次编译
       ======================================= 
  2.     Binutils需要一个链接器、编译器和其它的工具来处理对象文件。
        使用编译器优化时应用一个模块防止构造失败:

        #tar xvf /mnt/lfs/sources/binutils-2.22.tar.bz2
        #cd /mnt/lfs/sources/binutils-2.22/
        #patch -Np1 -i ../binutils-2.22-build_fix-1.patch


        /* 同样的创建独立的构造目录: */
        #mkdir -v ../binutils-build
        #cd ../binutils-build


        /* 为Binutils预编译 */
        #CC=$LFS_TGT-gcc            \
        AR=$LFS_TGT-ar             \
        RANLIB=$LFS_TGT-ranlib     \
        ../binutils-2.22/configure \
            --prefix=/tools        \
            --disable-nls          \
            --with-lib-path=/tools/lib

        /* 解释下参数 */
        CC=$LFS_TGT-gcc AR=$LFS_TGT-ar RANLIB=$LFS_TGT-ranlib
        因为是在本地编译,设定这些变量确保构造系统能使用交叉编译器和相关的工具而不是宿主系统的东西。
        --with-lib-path=/tools/lib
        这告诉配置脚本在编译Binutils时具体化类库搜索路径,产生在 /tools/lib 的东西传递给链接器。
        这样子防止链接器从宿主系统搜索类库的目录。

        /* 安装 */
        #make 
        #make install

        /* 现在为下章[提前调整]阶段准备编译器 */
        #make -C ld clean
        #make -C ld LIB_PATH=/usr/lib:/lib
        #cp -v ld/ld-new /tools/bin

        -C ld clean  ;这告诉make程序移除所有在ld子目录中所有已编译的文件
        -C ld LIB_PATH=/usr/lib:/lib ;这个选项重新构造在ld子目录中的东西。
        具体化命令行 LIB_PATH Makefile变量允许我们覆盖在临时工具目录中的默认值,然后将它指向正确的合适的最终路径。
        这个变量的值具体化了链接器的默认类库的搜索路径。这个准备会在下章使用。
  3.     /* 善后处理 */
        #cd /mnt/lfs/sources
  4.     #rm -rf binutils-2.22   


    =======================================
     ***** GCC 第二次编译
    ======================================= 
            GCC含GNU编译器集,包含C和C++编译器。
            我们第一次构造GCC已经安装了一些内部系统头部。  
  5.          
  6.     #tar xvf gcc-4.7.1.tar.bz2
  7.     #cd  gcc-4.7.1
  8.     #cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
          `dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include-fixed/limits.h

        /* 对于X86机器,GCC使用 -fomit-frame-pointer 编译标识来构造GCC引导;
        非引导编译默认会忽略这个标识,这个目标应该产生一个编译器能够让它完全自己引导;
        应用sed命令来强制构造使用这些标识 */
        #cp -v gcc/Makefile.in{,.tmp}
        #sed 's/^T_CFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in.tmp \
          > gcc/Makefile.in

        /* 改变GCC的默认动态链接器位置为 /tools */
        #for file in \
          $(find gcc/config -name linux64.h -o -name linux.h -o -name sysv4.h)
         do
           cp -uv $file{,.orig}
           sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \
           -e 's@/usr@/tools@g' $file.orig > $file
           echo '
         #undef STANDARD_STARTFILE_PREFIX_1
         #undef STANDARD_STARTFILE_PREFIX_2
         #define STANDARD_STARTFILE_PREFIX_1 "/tools/lib/"
         #define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
           touch $file.orig
         done

        /* 就像第一次构造GCC,需要GMP、MPFR、MPC包,然后将它们融入需要它们的目录,同时更名 */
        #tar -Jxf ../mpfr-3.1.1.tar.xz
        #mv -v mpfr-3.1.1 mpfr 
        #tar -Jxf ../gmp-5.0.5.tar.xz
        #mv -v gmp-5.0.5 gmp
        #tar -zxf ../mpc-1.0.tar.gz
        #mv -v mpc-1.0 mpc

        /* 再次创建一个独立的目录 */
        #mkdir -v ../gcc-build
        #cd ../gcc-build

        在开始构造GCC之前,记住取消任何环境变量能覆盖默认的优化标志。
        /* 为gcc编译准备 */
        #CC=$LFS_TGT-gcc \
        AR=$LFS_TGT-ar                  \
        RANLIB=$LFS_TGT-ranlib          \
            ../gcc-4.7.1/configure          \
            --prefix=/tools             \
            --with-local-prefix=/tools  \
            --with-native-system-header-dir=/tools/include \
            --enable-clocale=gnu        \
            --enable-shared             \
            --enable-threads=posix      \
            --enable-__cxa_atexit       \
            --enable-languages=c,c++    \
            --disable-libstdcxx-pch     \
            --disable-multilib          \
            --disable-bootstrap         \
            --disable-libgomp           \
            --with-mpfr-include=$(pwd)/../gcc-4.7.1/mpfr/src \
            --with-mpfr-lib=$(pwd)/mpfr/src/.libs

        #make
        #make install

         /* 创建符号链接,很多程序和脚本用cc而不是gcc */
        #ln -vs gcc /tools/bin/cc

    *******************************************
         测试编译器和链接器能正常工作 
    *******************************************
        /* 现在应该确认编译器和链接器能够正常工作 */
        #echo 'main(){}' > dummy.c
        #cc dummy.c
        #readelf -l a.out | grep ': /tools'
        /* 测试的结果应该如下:*/
        [Requesting program interpreter: /tools/lib/ld-linux.so.2]

        /* 如果测试正常的话,那么清除测试文件吧 */
        #rm -v dummy.c a.out

  9. /* 善后处理 */
  10. #cd /mnt/lfs/sources
  11. #rm -rf gcc-4.7.1
  12. #rm -rf gcc-build
  13.   ********** written at  2013-05-21  18:56 ************
  14.  
  15.  
  16. =======================================
            ***** Tcl-8.5.12的安装
    =======================================
    这个包和下面的三个(Expect、DejaGNU、Check)安装用来支持测试GCC和Binutils以及其它的包。
    这个确保它们能正常工作是灰常重要的,虽然它们看起来是那么的多余。


    /* 为编译准备 */
  17. # tar xvf tcl8.5.12-src.tar.gz
    #cd tcl8.5.12/unix/ 
    #./configure --prefix=/tools
    #make

    /* 要运行Tcl测试的话,需要有下面的命令先 */
    #TZ=UTC make test
    /* Tcl测试事宜可能在特定是宿主机环境没有完全的理解而失败。所以测试失败了,别太惊讶。
       TZ=UTC ,Coordinated Universal Time (UTC),就像GMT(Greenwich Mean Time)一样它只适合这一段的测试运行。
       这是为了确保时钟测试能够更准确。在第七章TZ环境变量将会提供更详细的信息。 
     */

    #make install

    /* 确保已安装的类库可写,这样debug调试链接能够在稍后移除 */
    #chmod -v u+w /tools/lib/libtcl8.5.so

    /* Tcl的头部,下一包需要它们来编译 */
    #make install-private-headers

    /* 必要的符号链接 */
    #ln -sv tclsh8.5 /tools/bin/tclsh

    /* 解释:
    安装的程序:tclsh(到tclsh8.5的链接) 和 tclsh8.5
    安装的类库:libtcl8.5.so, libtclstub8.5.a
     tclsh8.5, tcl的shell命令;tclsh ,tclsh8.5的符号链接;libtcl8.5.so ,Tcl的类库;libtclstub8.5.a,Tcl的存根类库 
    */

  1. /* 善后处理 */
  2. #cd /mnt/lfs/sources
  3. #rm -rf tcl8.5.12

  1.   ********** written at  2013-05-23  14:56 ************
  2.  
  3.  =======================================
            ***** Expect-5.45的安装
     =======================================
    这个软件包包含了用来执行脚本对话和其它的交互程序的程序。
     
    /* 强制Expect的配置脚本为/bin/stty而不是 /usr/local/bin/stty ,它可能在宿主系统上去找 */
    #tar xvf expect5.45.tar.gz
    #cd expect5.45


    #./configure --prefix=/tools --with-tcl=/tools/lib \
      --with-tclinclude=/tools/include
    #make
    /* 测试,在此测试的也并不是完全的无错误的,于不同的宿主机有不同的结果,so,在这测试失败并无多大关系 */
    #make test
    #make SCRIPTS="" install
    /* SCRIPTS="",防止Expect的补充安装脚本,它们不是必要的 */

  4. /* 善后处理 */
  5. #cd /mnt/lfs/sources
  6. #rm -rf expect5.45

  7. /*
    已安装的程序:expect
    已安装的类库:libexpect-5.45.a
    expect 用脚本和其它交互式程序交流
    libexpect-5.45.a 包含让Expect使用Tcl扩展或直接从C或C++使用而没有Tcl的功能
    */
  8.  
  9. ********** written at  2013-05-23  20:07 ************ 
  10.  


  1. /*************************************************严重声明***********************************************/

    对于每一个包,姑且命名其为 Package_name ,所作的操作都大致如下。
    那么一坨的问号中为不省略的内容,所以省略的内容都是下面已经写出的内容。
    省略的都是对一个包解压,进入包解压后的目录,然后操作(正文内容),然后出包目录,然后删除刚退出来的目录。
    以下内容按此操作解读!!!!!!!!!!
    #cd /mnt/lfs/sources
    #tar xvf Package_name.tar.gz
    #cd Package_name
    ??????????????????
    #cd ..
    #rm -rf Package_name
  2. /********************************************************************************************************/



  1. =======================================
    *****                      DejaGNU-1.5
    =======================================

    这个软件包包含了测试其它程序的框架。

    #./configure --prefix=/tools
    /* 构造安装包 */
    #make installl
    #make check

    /*
    已安装的程序:runtest
    runtest 一个定位适当的 expect 包装shell脚本然后运行 DejaGNU
    */


    =======================================
    *****                      Check-0.9.8
    =======================================

    #./configure --prefix=/tools
    #make
    /* 编译完成,来个长长的测试吧,时间有点长 */
    #make check
    #make install

    /*
    已安装的类库:libcheck.{a,so}
    libcheck.{a,so} 包含让 Check 从测试程序调用的函数
    */


     =======================================
     *****                      Ncurses-5.9
     =======================================
    这个 Ncurses 包含有终端字符处理依赖的类库。

    #./configure --prefix=/tools --with-shared \
        --without-debug --without-ada --enable-overwrite
    /* 
    --without-ada
    确保 Ncurse 构造不会寻找存在宿主系统中 Ada 编译器的支持,因为一旦我们进入chroot环境,这个Ada将不复存在。
    --enable-overwrite
    它告诉 Ncurse将它的头文件放入 /tools/include,而不是 /tools/include/ncurses,这样确保其他的包能找到Ncurses的头文件。
    */

    #make 
    /* 这个包有个测试套件,但是只能在安装完成之后进行。在 test/ 目录中。查看那个目录中的README文件查找更多的信息。 */
    #make install



    =======================================
    *****                         Bash-4.2
    =======================================
    ;打下补丁
    #patch -Np1 -i ../bash-4.2-fixes-8.patch

    #./configure --prefix=/tools --without-bash-malloc
    /*
    --without-bash-malloc
    这个选项关闭了Bash的内存分配(malloc)的功能,这个功能能导致分段的错误。
    关闭这个选项之后,bash将会更稳定的为Glibc使用malloc功能。
    */

    #make
    #make tests
    #make install

    ;为用 sh shell的程序创建链接
    #ln -vs bash /tools/bin/sh
      
  2. ********** written at  2013-05-25  21:08 ************



  3.  
  4. =======================================
     ***** Bzip2-1.0.6
     =======================================
    该包用户压缩和解压缩文件。压缩文本文件用bzip2会比传统的gzip的压缩率更好。

    包中不含configure文件,编译然后测试:
    #make
    #make PREFIX=/tools install


    ///////////////////////////////////////////////////////////////////////////
    在这里有遇到提示:
    make: warning:  Clock skew detected.  Your build may be incomplete
    原因是你的系统时钟与硬件时钟不一致导致的。
    解决方式:# hwclock –hctosys (或# hwclock –systohc)
    即要同步软硬件时钟!
    ///////////////////////////////////////////////////////////////////////////


     =======================================
     ***** Coreutils-8.19
     =======================================
    该包含显示和设置基本系统字符的使用工具。

    #./configure --prefix=/tools --enable-install-program=hostname
        --enable-install-program=hostname 
            这个参数使得hostname二进制文件将会被编译和安装,它默认是不需要的,但是在Perl的测试时要用到。
    #make 
    ;;测试下吧!!!
    #make RUN_EXPENSIVE_TESTS=yes check
        RUN_EXPENSIVE_TESTS=yes
            这个参数告诉测试工具多运行一些额外的看起来相当的耗费资源的测试。
    #make install


     =======================================
     ***** Diffutils-3.2
     =======================================
    该包含显示文件和目录不同之处的程序。

    为了解决它与Glibc-2.16.0的不兼容问题:
    #sed -i -e '/gets is a/d' lib/stdio.in.h
    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** File-5.11
     =======================================
    该包含决定一个给定的文件的文件类型的程序。

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Findutils-4.4.2
     =======================================
    该包含查找文件的程序。它提供递归的查找一个目录树和创建,维持和搜索一个文件数据库(这样比递归查找更快,但更新慢的话就不可靠了).

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Gawk-4.0.1
     =======================================
    该包含操作文本文件的程序。

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Gettext-0.18.1.1
     =======================================
    该包含国际化和本地化的工具。这使得程序能用NLS(本地语言支持)进行编译,让它们的输出信息中显示的是本地语言。

    根据我们的工具套,我们只需要从Gettext中构造和安装一个二进制文件。

    解决它与Glibc-2.16.0的不兼容问题:
    #sed -i -e '/gets is a/d' gettext-*/*/stdio.in.h
    #cd gettext-tools
    #EMACS="no" ./configure --prefix=/tools --disable-shared
       EMACS="no" 这个参数防止配置脚本决定在哪里安装Emacs Lisp文件作为测试挂在系统上。
       --disable-shared 我们现在不需要Gettext的共享库,所以没有必要构造它们。
    ;;编译
    #make -C gnulib-lib
    #make -C src msgfmt

    由于只有一个二进制文件被编译,在没有从Gettext包编译额外的类库支持的话,它不足以支持这个测试工具套运行。因此此时不建议尝试运行测试。

    安装 msgfmt类库:
    #cp -v src/msgfmt /tools/bin


     =======================================
     ***** Grep-2.14
     =======================================
    该包含从整个文件搜索的程序。

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Gzip-1.5
     =======================================
    该包含压缩和解压缩文件的程序。

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** M4-1.4.16
     =======================================
    该包含一个宏处理器。

    修补与包Glibc-2.16.0的兼容问题:
    #sed -i -e '/gets is a/d' lib/stdio.in.h

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Make-3.82
     =======================================
    该包含编译包的程序,即编译器。

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Patch-2.6.1
     =======================================
    该包含通过diff程序应用一个"patch"文件修改或者创建文件的程序。

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Perl-5.16.1
     =======================================
    该包含实用萃取与报告的语言。

    首先应用下面的模块来适应到C类库的硬接线路径。
    #patch -Np1 -i ../perl-5.16.1-libc-2.patch
    #sh Configure -des -Dprefix=/tools
    #make

    尽管Perl伴随着一个测试工具,但是最好等在在下一章进行。

    在这里只有一些工具和类库需要安装:
    #cp -v perl cpan/podlators/pod2man /tools/bin
    #mkdir -pv /tools/lib/perl5/5.16.1
    #cp -Rv lib/* /tools/lib/perl5/5.16.1


     =======================================
     ***** Sed-4.2.1
     =======================================
    该包含一个流编辑器。

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Tar-1.26
     =======================================
    该包含一个归档程序。

    修补与包Glibc-2.16.0的兼容问题:
    #sed -i -e '/gets is a/d' gnu/stdio.in.h

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Texinfo-4.13a
     =======================================
    该包含读、写和转换页面信息的程序。

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install


     =======================================
     ***** Xz-5.0.4
     =======================================
    该包含压缩和解压缩文件的程序。它为lzma 和更新的xz压缩格式提供了兼容性。压缩文本文件使用xz会比传统的gzip或者zip2产生更好的压缩率.

    #./configure --prefix=/tools
    #make
    ;;测试下吧!!!
    #make check
    #make install
     
  5.  
  6.  
  7.   
  8.  =======================================
     ***** Stripping(拆分______节省空间)
     =======================================
    这个步骤是可选的,如果LFS分区相当小的话,可以把一些不必要的项目移除掉!
    可执行文件和类库文件到目前为止含70 MB不需要的调试符号。可以移除这些符号:
    #strip --strip-debug /tools/lib/*
    #strip --strip-unneeded /tools/{,s}bin/*

    这些命令将会忽略一些文件,报告显示它未记住它们的格式。大部分的这些是类库的脚本。
    记住不要在类库上用 --strip-unneeded 。 这些静态的类库将会被破坏,toolchain包就需要重新构造一遍。
    为节省更多的空间,移除文档:
    #rm -rf /tools/{,share}/{info,man,doc}

    这时,你在 $LFS 分区上至少还有850 MB大小的空间可以在下一阶段使用来构造Glibc。
    如果你能构造和安装Glibc,你可以继续构造和安装剩下的。




    ///////////////////////////////////////////////////
    改变所有权
    注意: 在本书的剩下的所有命令必须以root省份执行而不再使用lfs作为登录用户。
    同时记住仔细检查 $LFS 变量是否有在root的环境变量中设置。


    到目前为止,目录 $LFS/tools 是用户 lfs 所有,lfs是只存在在宿主系统中的用户。
    这样子的话,$LFS/tools 目录被一个不正确的账号所有,假如一个用户创建了拥有同样的ID的话,那么他就拥有了这个 $LFS/tools 目录的所有权,
    也就拥有了里面的所有的文件,他就可能恶意操作这些文件。
    解这个问题,一是可以把 lfs 用户添加到新的 LFS系统中到 /etc/passwd 文件中,把宿主机上同样的用户名和组ID赋给它。
    还有一种更好的办法是改变目录 $LFS/tools 目录的所有者,命令如下:

    #chown -R root:root $LFS/tools

    尽管 $LFS/tools 目录可以删掉一旦 LFS 系统完成之后,它可以继续保留来构造更多的基于LFS系统之外的版本。
    如何更好的备份目录 $LFS/tools 是个人爱好的问题。
    如果想继续保留该目录以后用,开始备份吧!!!
    在第六章的命令将会改变目前的工具位置,使它们无法用于将来的版本!!!
    ///////////////////////////////////////////////////
  9. ********** written at  2013-06-01  15:15 ************







阅读(1864) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~