LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1933|回复: 15

最新LFS实践播报:SYSROOT Multilib LFS -注意不是CLFS

[复制链接]
发表于 2008-4-18 12:09:49 | 显示全部楼层 |阅读模式
大家好,现在我在试验使用LFS的方法进行LFS,注意不是CLFS——我要构建本机的SYSROOT工具链!

1. 准备工作:请按照LFS BOOK的叙述进行分区添加用户等。因为我们要做Sysroot LFS,因此用户名和组名以及$LFS请改为SLFS。此外,在Multilib的情况下请在设置环境这一步加入
export BUILD32="-m32"
export BUILD64="-m64"

2. Linux Headers 2.6.25
install -dv $SLFS/usr/include &&
make ARCH=x86_64 headers_check &&
make ARCH=x86_64 INSTALL_HDR_PATH=dest headers_install &&
cp -rv dest/include/* $SLFS/usr/include

3. Glibc 2.7 Pass 1
本次编译Glibc是直接使用宿主的GCC进行的,它用于编译随后的Sysroot GCC。在此之后,Glibc Pass2 将使用新的GCC来编译。

a. 32 bit
mkdir -v ../glibc-build
cd ../glibc-build

echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache

echo "install_root=${SLFS}" > configparms
echo "CFLAGS += -march=i686 -fno-stack-protector" >> configparms

注意以上命令,在某些平台如Ubuntu,这个-fno-stack-protector是必须的。你要是没有它也能编译,就不需要加。

BUILD_CC="gcc" CC="gcc ${BUILD32}" \
../glibc-2.7/configure --prefix=/usr --host=i686-pc-linux-gnu \
--libexecdir=/usr/lib/glibc --disable-profile --enable-add-ons --with-tls --enable-kernel=2.6.0 --with-__thread --with-headers=${SLFS}/usr/include --cache-file=config.cache

make && make install

b. 64 bit
确认自己还在glibc-build目录下,
rm -rf *
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache

echo "install_root=${SLFS}" > configparms
echo "slibdir=/lib64" >> configparms
echo "CFLAGS += -fno-stack-protector" >> configparms

BUILD_CC="gcc" CC="gcc ${BUILD64}" \
../glibc-2.7/configure --prefix=/usr --libdir=/usr/lib64 \
--libexecdir=/usr/lib64/glibc --disable-profile --enable-add-ons --with-tls --enable-kernel=2.6.0 --with-__thread --with-headers=${SLFS}/usr/include --cache-file=config.cache

make && make install

4. GCC Requirement
a. GMP 4.2.2
./configure --prefix=/tools --disable-shared
make install
b. MPFR 2.3.1
./configure --prefix=/tools --disable-shared
make install
c. Flex 2.5.35
./configure --prefix=/tools
make install

5. Binutils 2.18
patch -Np1 -i ../binutils-2.18-genscripts_multilib-1.patch
patch -Np1 -i ../binutils-2.18-posix-1.patch
mkdir -v ../binutils-build
cd ../binutils-build

../binutils-2.18/configure --prefix=/tools --with-sysroot=$SLFS \
--disable-nls --enable-shared --with-64-bit-bfd

make && make install

6. GCC 4.3-20080410
mkdir -v ../gcc-build &&
cd ../gcc-build &&

../gcc-4.3-20080410/configure --prefix=/tools \
--with-sysroot=${SLFS} --disable-nls --enable-shared \
--enable-languages=c,c++ --enable-__cxa_atexit \
--enable-c99 --enable-long-long --enable-threads=posix \
--with-gmp=/tools --with-mpfr=/tools &&

make && make install
ln -sv gcc /tools/bin/cc

7. Glibc 2.7 pass 2
a. 32bit
cd glibc-2.7 &&
patch -Np1 -i ~/newsource/glibc-2.7-branch_update-1A.patch
patch -Np1 -i ~/newsource/glibc-2.7-localedef_segfault-1.patch

使用GCC 4.3以上版本需要这个补丁
cp configure{,.orig}
sed -e "/ccheaders=/s@\`\(\$CC.*include\)\`@\"& -isystem \`\1-fixed\`\"@" configure.orig > configure

开始make
mkdir -v ../glibc-build &&
cd ../glibc-build &&
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache

echo "install_root=${SLFS}" > configparms
echo "CFLAGS += -march=i686" >> configparms

BUILD_CC="gcc" CC="gcc ${BUILD32}" \
../glibc-2.7/configure --prefix=/usr --host=i686-pc-linux-gnu \
--libexecdir=/usr/lib/glibc --disable-profile --enable-add-ons --with-tls --enable-kernel=2.6.0 --with-__thread --with-headers=${SLFS}/usr/include --cache-file=config.cache

make && make install
b. 64bit
确认自己还在glibc-build目录下,
rm -rf * &&

echo "libc_cv_forced_unwind=yes" > config.cache &&
echo "libc_cv_c_cleanup=yes" >> config.cache &&

echo "install_root=${SLFS}" > configparms &&
echo "slibdir=/lib64" >> configparms &&

BUILD_CC="gcc" CC="gcc ${BUILD64}" \
../glibc-2.7/configure --prefix=/usr --libdir=/usr/lib64 \
--libexecdir=/usr/lib64/glibc --disable-profile --enable-add-ons --with-tls --enable-kernel=2.6.0 --with-__thread --with-headers=${SLFS}/usr/include --cache-file=config.cache &&

make && make install
c. Glibc config
make localedata/install-locales
cat > ${SLFS}/etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf

passwd: files
group: files
shadow: files

hosts: files dns
networks: files

protocols: files
services: files
ethers: files
rpc: files

# End /etc/nsswitch.conf
EOF

TZDIR="${SLFS}/usr/share/zoneinfo" ${SLFS}/usr/bin/tzselect

cat > ${SLFS}/etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf

/usr/local/lib64
/usr/local/lib

/opt/lib64
/opt/lib

# End /etc/ld.so.conf
EOF

8. Multiarch Wrapper
cat > multiarch_wrapper.c << "EOF"
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#ifndef USE_ARCH
#define USE_ARCH "64"
#endif

int main(int argc, char **argv)
{
  char *filename;
  char *use_arch;

  if(!(use_arch = getenv("USE_ARCH")))
    use_arch = USE_ARCH;

  filename = (char *) malloc(strlen(argv[0]) + strlen(use_arch) + 2);
  strcpy(filename, argv[0]);
  strcat(filename, "-");
  strcat(filename, use_arch);

  execvp(filename, argv);
  perror(argv[0]);
  free(filename);
}
EOF

gcc ${BUILD64} multiarch_wrapper.c -o $SLFS/usr/bin/multiarch_wrapper
发表于 2008-4-18 12:45:54 | 显示全部楼层
Post by 地球发动机;1839559

3. Glibc 2.7 Pass 1
本次编译Glibc是直接使用宿主的GCC进行的,它用于编译随后的Sysroot GCC。


如果host系统是x86_64 multilib,有必要吗?
回复 支持 反对

使用道具 举报

发表于 2008-4-18 12:52:43 | 显示全部楼层
Post by 地球发动机;1839559
8. Multiarch Wrapper
cat > multiarch_wrapper.c << "EOF"
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#ifndef USE_ARCH
#define USE_ARCH "64"
#endif

int main(int argc, char **argv)
{
  char *filename;
  char *use_arch;

  if(!(use_arch = getenv("USE_ARCH")))
    use_arch = USE_ARCH;

  filename = (char *) malloc(strlen(argv[0]) + strlen(use_arch) + 2);
  strcpy(filename, argv[0]);
  strcat(filename, "-");
  strcat(filename, use_arch);

  execvp(filename, argv);
  perror(argv[0]);
  free(filename);
}
EOF

gcc ${BUILD64} multiarch_wrapper.c -o $SLFS/usr/bin/multiarch_wrapper


有必要吗?当你完成base system时,Util-linux-ng 提供有工具setarch
并连接为linux32 linux64,完全可以用来切换系统arch。对比源码,Util-linux-ng 提供的工具比你这里给出的更安全。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-18 13:22:41 | 显示全部楼层
Post by 1987a;1839576
如果host系统是x86_64 multilib,有必要吗?

有必要,因为宿主不一定用4.3或者我们选择的GCC版本编译。pass2的目的就是为了让所有目标机器的可执行代码都在同一个GCC下编译。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-18 13:24:38 | 显示全部楼层
Post by 1987a;1839578
有必要吗?当你完成base system时,Util-linux-ng 提供有工具setarch
并连接为linux32 linux64,完全可以用来切换系统arch。对比源码,Util-linux-ng 提供的工具比你这里给出的更安全。

这里的这个步骤是CLFS multilib所建议的,我一字不改地照抄的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-18 13:27:35 | 显示全部楼层
SYSROOT Multilib LFS第二阶段:打造可以chroot的简易系统
9. Coreutils 6.10
CC="gcc $BUILD64" ./configure --prefix=/usr
make
make DESTDIR=$SLFS install

10. NCurses 5.6
a. 32 bit
patch -Np1 -i ../ncurses-5.6-branch_update-2.patch
CC="gcc ${BUILD32}" CXX="g++ ${BUILD32}" \
   ./configure --prefix=/usr --libdir=/lib \
   --with-shared --without-debug
make
make DESTDIR=$SLFS install
mv -v $SLFS/usr/bin/ncurses5-config{,-32}
mv -v $SLFS/lib/lib{panel,menu,form,ncurses,ncurses++,curses}.a $SLFS/usr/lib

rm -v $SLFS/lib/lib{ncurses,menu,panel,form,curses}.so
ln -svf ../../lib/libncurses.so.5 $SLFS/usr/lib/libcurses.so
ln -svf ../../lib/libncurses.so.5 $SLFS/usr/lib/libncurses.so
ln -svf ../../lib/libmenu.so.5 $SLFS/usr/lib/libmenu.so
ln -svf ../../lib/libpanel.so.5 $SLFS/usr/lib/libpanel.so
ln -svf ../../lib/libform.so.5 $SLFS/usr/lib/libform.so

chmod -v 755 $SLFS/lib/lib{panel,menu,form,ncurses}.so.5.6
b. 64 bit
删除源码目录,然后重新解压
patch -Np1 -i ../ncurses-5.6-branch_update-2.patch

CC="gcc ${BUILD64}" CXX="g++ ${BUILD64}" \
   ./configure --prefix=/usr --libdir=/lib64 \
   --with-shared --without-debug

make
make DESTDIR=$SLFS install

mv -v $SLFS/usr/bin/ncurses5-config{,-64}
ln -sv multilib_wrapper $SLFS/usr/bin/ncurses5-config

mv -v $SLFS/lib64/lib{panel,menu,form,ncurses,ncurses++,curses}.a $SLFS/usr/lib64

rm -v $SLFS/lib64/lib{ncurses,menu,panel,form,curses}.so
ln -svf ../../lib64/libncurses.so.5 $SLFS/usr/lib64/libncurses.so
ln -svf ../../lib64/libncurses.so.5 $SLFS/usr/lib64/libcurses.so
ln -svf ../../lib64/libmenu.so.5 $SLFS/usr/lib64/libmenu.so
ln -svf ../../lib64/libpanel.so.5 $SLFS/usr/lib64/libpanel.so
ln -svf ../../lib64/libform.so.5 $SLFS/usr/lib64/libform.so

chmod -v 755 $SLFS/lib64/lib{panel,menu,form,ncurses}.so.5.6

11. readline 5.2
a. 32bit
patch -Np1 -i ../readline-5.2-fixes-4.patch
CC="gcc ${BUILD32}" CXX="g++ ${BUILD32}" \
   ./configure --prefix=/usr --libdir=/lib
make SHLIB_XLDFLAGS=-lncurses
make DESTDIR=$SLFS install

chmod -v 755 $SLFS/lib/lib{readline,history}.so*

mv -v $SLFS/lib/lib{readline,history}.a $SLFS/usr/lib

rm -v $SLFS/lib/lib{readline,history}.so
ln -svf ../../lib/libreadline.so.5 $SLFS/usr/lib/libreadline.so
ln -svf ../../lib/libhistory.so.5 $SLFS/usr/lib/libhistory.so
b. 64bit
删除源码目录,然后重新解压
patch -Np1 -i ../readline-5.2-fixes-4.patch
CC="gcc ${BUILD64}" CXX="g++ ${BUILD64}" \
   ./configure --prefix=/usr --libdir=/lib64
make SHLIB_XLDFLAGS=-lncurses
make DESTDIR=$SLFS install

chmod -v 755 $SLFS/lib64/lib{readline,history}.so*

mv -v $SLFS/lib64/lib{readline,history}.a $SLFS/usr/lib64

rm -v $SLFS/lib64/lib{readline,history}.so
ln -svf ../../lib64/libreadline.so.5 $SLFS/usr/lib64/libreadline.so
ln -svf ../../lib64/libhistory.so.5 $SLFS/usr/lib64/libhistory.so

12. Bash 3.2
tar -xvf ../bash-doc-3.2.tar.gz
patch -Np1 -i ../bash-3.2-fixes-7.patch
CC="gcc ${BUILD64}" CXX="g++ ${BUILD64}" \
    ./configure --prefix=/usr --bindir=/bin \
    --without-bash-malloc --with-installed-readline
make
make DESTDIR=$SLFS htmldir=$SLFS/usr/share/doc/bash-3.2 install

在本阶段的最后,让我们来检验一下工作成果:
su
chroot /mnt/slfs /bin/bash
在这个简单的chroot环境里面,你应该可以做许多一般的操作,例如cp,mv,ls等等。如果这一切都正常,那么前面的工具链应该就是可靠的。
回复 支持 反对

使用道具 举报

发表于 2008-4-18 13:40:29 | 显示全部楼层
Post by 地球发动机;1839595
有必要,因为宿主不一定用4.3或者我们选择的GCC版本编译。pass2的目的就是为了让所有目标机器的可执行代码都在同一个GCC下编译。


如果host系统是x86_64 multilib,仿照标准LFS的步骤一样可以让所有目标机器的可执行代码都在同一个GCC下编译。
回复 支持 反对

使用道具 举报

发表于 2008-4-18 13:45:42 | 显示全部楼层
Post by 地球发动机;1839596
这里的这个步骤是CLFS multilib所建议的,我一字不改地照抄的。


我们的做法都表明手册只是拿来参考的,我只是给出建议。
CLFS multilib手册我确实没怎么看过。

如果你想象一下自己手头有x86_64 i686 i586等多台机子,你就会理解我为什么那么痛恨multilib了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-18 13:52:27 | 显示全部楼层
Post by 1987a;1839603
如果host系统是x86_64 multilib,仿照标准LFS的步骤一样可以让所有目标机器的可执行代码都在同一个GCC下编译。

当然。但是那意味着Binutils和GCC要编译2次。在标准LFS下选择不多,但是我们是SYSROOT,所以我们可以选择,编译2次Glibc还是2次Binutils/GCC。鉴于GCC编译问题较多(可能牵扯到Multilib配置问题),我觉得还是编2次Glibc较方便些。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-18 14:10:07 | 显示全部楼层
Post by 1987a;1839606
我们的做法都表明手册只是拿来参考的,我只是给出建议。
CLFS multilib手册我确实没怎么看过。

如果你想象一下自己手头有x86_64 i686 i586等多台机子,你就会理解我为什么那么痛恨multilib了。

我看了一下setarch的文档,这个程序的作用和这个multiarch-wrapper根本不同。在multilib下,32位程序和64位程序都可以执行,multiarch-wrapper的作用是当同一个程序既有32位版本又有64位版本时,根据环境变量来选择实际运行的版本。
而setarch是用来蒙骗32位程序使它认为自己在纯32位机器上运行。这可以用来安装一些不支持64位机器的程序。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表