+ -
当前位置:首页 → 问答吧 → [原创]从源码构建本地编译GNU/Linux系统(gcc-4.3.1)

[原创]从源码构建本地编译GNU/Linux系统(gcc-4.3.1)

时间:2008-06-24

来源:互联网

从源码构建本地编译GNU/Linux系统(gcc-4.3.1)

2008.07.16 更新 交叉编译工具链 创建方法,升级一个相关软件包file-4.25
2008.06.23 创建

本文解决如下问题:
  1. 以 Sysroot 方式,从源码构建本地编译的 GNU/Linux 系统。
  2. 官方 CLFS-Sysroot x86 方法中 Basic System 为交叉编译产物,本文方法中 Basic System 本地编译生成。
  3. 官方 CLFS-Sysroot 无 x86_64 系统构建方法,本文提供 CLFS-Sysroot x86_64-Pure64 方法,并且 Basic System 本地编译生成。
  4. 理论上,本文提供的方法亦适用其它平台架构。不具备本地编译条件的嵌入式平台请使用官方方法。
  5. 升级到 gcc-4.3.1 。
本文为 Sysroot 方式从源码构建完全本地编译的 GNU/Linux 系统 升级姊妹篇

宿主系统需求:
  • Bash-2.05a
  • Binutils-2.12
  • Bison-1.26a
  • Bzip2-1.0.2
  • Coreutils-5.0
  • Diffutils-2.8
  • Findutils-4.1.20
  • Gawk-3.0
  • Gcc-2.95.3
  • Glibc-2.2.5
  • Grep-2.5
  • Gzip-1.2.4
  • Make-3.79.1
  • Patch-2.5.4
  • Sed-3.0.2
  • Tar-1.14
  • Texinfo
  • file-4.21
  • perl
  • gmp-4.2.2
  • mpfr-2.3.1
具体过程如下:(适用于x86/x86_64,摘自笔者编译脚本)

〇、root用户准备工作
  1. 全局设置
    代码:
    NEW_OS=x86_64-linux-gnu #自定义,用于工作目录、用户名
    NEW_OS_ARCH=x86_64 #处理器架构,x86系统请修改为i386
    NEW_OS_TARGET=x86_64-unknown-linux-gnu #目标系统类型,x86系统请根据自己需要修改,如i686-pc-linux-gnu
    
    NEW_OS_HOST=$(echo ${MACHTYPE} | sed -e "s@$(echo ${MACHTYPE} | cut -d- -f2)@cross@")
    NEW_OS_MARCH=$(echo ${NEW_OS_TARGET} | cut -d- -f1)
    
    NEW_OS_DIR=/${NEW_OS}
    SOURCE=${NEW_OS_DIR}/source
    TOOLS=${NEW_OS_DIR}/tools
    PACKAGE=${NEW_OS_DIR}/package
    MARK=${NEW_OS_DIR}/mark
    ROOTFS=${NEW_OS_DIR}/rootfs
    FAKEROOT=${NEW_OS_DIR}/fakeroot
    
    NEW_OS_NO_LIB64_DIR=yes
    
    NEW_OS_USER=${NEW_OS}
    NEW_OS_ID=1000
  2. 建立工作目录、用户、用户环境
    代码:
    mkdir -pv ${NEW_OS_DIR}/bin \
     ${SOURCE} \
     ${TOOLS} \
     ${PACKAGE} \
     ${MARK} \
     ${ROOTFS} \
     ${FAKEROOT}
    touch ${NEW_OS_DIR}/${NEW_OS_TARGET}
    cp -a ${NEW_OS_SCRIPT_DIR} ${NEW_OS_DIR}/bin
    
    groupadd -o -g ${NEW_OS_ID} ${NEW_OS_USER}
    useradd -o -d ${NEW_OS_DIR} -u ${NEW_OS_ID} -g ${NEW_OS_ID} -s /bin/bash ${NEW_OS_USER}
    passwd ${NEW_OS_USER}
    
    cat > ${NEW_OS_DIR}/.bash_profile << eof
    exec env -i HOME=\${HOME} TERM=\${TERM} PS1='\u@\h:\w\\$ ' /bin/bash
    eof
    
    cat > ${NEW_OS_DIR}/.bashrc << eof
    set +h
    umask 022
    export LC_ALL=POSIX
    export PATH=${TOOLS}/bin:/usr/bin:/bin
    eof
    
    echo "export NEW_OS=${NEW_OS}" >> ${NEW_OS_DIR}/.bashrc
    echo "export NEW_OS_ARCH=${NEW_OS_ARCH}" >> ${NEW_OS_DIR}/.bashrc
    echo "export NEW_OS_TARGET=${NEW_OS_TARGET}" >> ${NEW_OS_DIR}/.bashrc
    echo "export NEW_OS_HOST=${NEW_OS_HOST}" >> ${NEW_OS_DIR}/.bashrc
    echo "export NEW_OS_MARCH=${NEW_OS_MARCH}" >> ${NEW_OS_DIR}/.bashrc
    echo "export NEW_OS_DIR=${NEW_OS_DIR}" >> ${NEW_OS_DIR}/.bashrc
    echo "export SOURCE=${SOURCE}" >> ${NEW_OS_DIR}/.bashrc
    echo "export TOOLS=${TOOLS}" >> ${NEW_OS_DIR}/.bashrc
    echo "export PACKAGE=${PACKAGE}" >> ${NEW_OS_DIR}/.bashrc
    echo "export MARK=${MARK}" >> ${NEW_OS_DIR}/.bashrc
    echo "export ROOTFS=${ROOTFS}" >> ${NEW_OS_DIR}/.bashrc
    echo "export FAKEROOT=${FAKEROOT}" >> ${NEW_OS_DIR}/.bashrc
    
    echo "unset CFLAGS" >> ${NEW_OS_DIR}/.bashrc
    echo "unset CXXFLAGS" >> ${NEW_OS_DIR}/.bashrc
    
    chown -R ${NEW_OS_ID}.${NEW_OS_ID} ${NEW_OS_DIR}
  3. 建立目标系统目录结构
    代码:
     mkdir -pv ${ROOTFS}/{bin,boot,dev,etc/{ramdisk,opt},home,initrd,lib,media,mnt,opt,proc,root,sbin,srv,sys,tmp,usr,var}
     mkdir -pv ${ROOTFS}/usr{,/local}/{bin,include,lib,sbin,share,src}
     mkdir -pv ${ROOTFS}/usr{,/local}/share/{doc,info,locale,man,misc,terminfo,zoneinfo}
     ln -sfv share/{doc,info,man} ${ROOTFS}/usr
     ln -sfv share/{doc,info,man} ${ROOTFS}/usr/local
     mkdir -pv ${ROOTFS}/usr{,/local}/share/man/man{1,2,3,4,5,6,7,8}
     mkdir -pv ${ROOTFS}/var/{cache,lib/{misc,locate},local,lock,log,mail,opt,run,spool,tmp}
     chmod 0750 ${ROOTFS}/root
     chmod 1777 ${ROOTFS}/{,var/}tmp
  4. 宿主安装gmp-4.2.2
    代码:
     ./configure --prefix=/usr \
     --enable-cxx \
     --enable-mpbsd
    
     make
     make install
  5. 宿主安装mpfr-2.3.1
    代码:
     ./configure --prefix=/usr \
     --enable-shared
    
     make
     make install
一、${NEW_OS_USER} 用户建立交叉工具链
  1. linux-header-2.6.25.7
    代码:
    HOMEPAGE="http://www.kernel.org/"
    SOURCE_URL="http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.25.7.tar.bz2
     http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.25.7.tar.bz2.sign"
    SOURCE_MD5=""
    
    PACKAGE_NAME=linux-header
    PACKAGE_VERSION=2.6.25.7
    
    SOURCE_DIR=${SOURCE}/linux-${PACKAGE_VERSION}
    BUILD_DIR=
    
    source_tree()
    {
     cd ${SOURCE}
     tar -xvf linux-${PACKAGE_VERSION}.tar.bz2
    
     cd ${SOURCE_DIR}
     make mrproper
    }
    
    source_config()
    {
     echo "source_config"
    }
    
    source_build()
    {
     cd ${SOURCE_DIR}
     make ARCH=${NEW_OS_ARCH} INSTALL_HDR_PATH=header_dir headers_install
    
     mkdir -pv ${ROOTFS}/usr
     cp -av header_dir/include ${ROOTFS}/usr/
    }
  2. glibc-header-2.7
    代码:
    HOMEPAGE="http://www.gnu.org/software/libc/"
    SOURCE_URL="http://ftp.gnu.org/gnu/glibc/glibc-2.7.tar.bz2
     http://ftp.gnu.org/gnu/glibc/glibc-2.7.tar.bz2.sig
     http://ftp.gnu.org/gnu/glibc/glibc-ports-2.7.tar.bz2
     http://ftp.gnu.org/gnu/glibc/glibc-ports-2.7.tar.bz2.sig"
    SOURCE_MD5=""
    
    SOURCE_DIR=${SOURCE}/glibc-${PACKAGE_VERSION}
    BUILD_DIR=${SOURCE}/glibc-build
    
    source_tree()
    {
     cd ${SOURCE}
     tar -xvf glibc-${PACKAGE_VERSION}.tar.bz2
     tar -xvf glibc-ports-${PACKAGE_VERSION}.tar.bz2
     mv -v glibc-ports-${PACKAGE_VERSION} ${SOURCE_DIR}/ports
    
     cd ${SOURCE_DIR}
    
     sed -i -e "s@/etc/mtab@/etc/ramdisk/mtab@" sysdeps/unix/sysv/linux/paths.h
    
     mkdir -pv ${BUILD_DIR}
    }
    
    source_config()
    {
     cd ${BUILD_DIR}
    
     echo "libc_cv_forced_unwind=yes" >> config.cache
     echo "libc_cv_c_cleanup=yes" >> config.cache
     echo "libc_cv_${NEW_OS_ARCH}_tls=yes" >> config.cache
     if [ "${NEW_OS_ARCH}" = "i386" ]; then
     echo "libc_cv_386_tls=yes" >> config.cache
     echo "CFLAGS+=-march=${NEW_OS_MARCH}" >> configparms
     fi
     echo "install_root=${ROOTFS}" >> configparms
     echo "slibdir=/lib" >> configparms
    
     CC=gcc ${SOURCE_DIR}/configure --prefix=/usr \
     --host=${NEW_OS_TARGET} \
     --build=${NEW_OS_HOST} \
     --with-headers=${ROOTFS}/usr/include \
     --cache-file=config.cache
    }
    
    source_build()
    {
     cd ${BUILD_DIR}
    
     make install-headers
    
     mkdir -pv ${ROOTFS}/usr/include/bits
     cp -v bits/stdio_lim.h ${ROOTFS}/usr/include/bits/
    
     mkdir -pv ${ROOTFS}/usr/include/gnu
     touch ${ROOTFS}/usr/include/gnu/stubs{,-32,-64}.h
    }
  3. binutils-2.18
    代码:
    HOMEPAGE="http://www.gnu.org/software/binutils/"
    SOURCE_URL="http://ftp.gnu.org/gnu/binutils/binutils-2.18.tar.bz2
     http://ftp.gnu.org/gnu/binutils/binutils-2.18.tar.bz2.sig"
    SOURCE_MD5=""
    
    SOURCE_DIR=${SOURCE}/${PACKAGE_NAME}-${PACKAGE_VERSION}
    BUILD_DIR=${SOURCE}/${PACKAGE_NAME}-build
    
    source_tree()
    {
     cd ${SOURCE}
     tar -xvf ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.bz2
    
     cd ${SOURCE_DIR}
    
     #posix
     sed -i -e "s@tail +16c@tail -c +16@g" $(grep -lr "tail +16c" *)
     sed -i -e "s@tail +140@tail -n +140@g" $(grep -lr "tail +140" *)
     sed -i -e "s@head -1@head -n 1@g" $(grep -lr "head -1" *)
    
     #support texinfo 4.11
     sed -i -e "s@4\\\.\[4-9\]@&|4\\\.11@" configure
    
     #--disable-multilib /lib64->/lib
     if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
     sed -i -e "s@/lib64/ld@/lib/ld@g" ld/configure.host
     fi
    
     mkdir -pv ${BUILD_DIR}
    }
    
    source_config()
    {
     cd ${BUILD_DIR}
    
     if [ "${NEW_OS_ARCH}" = "x86_64" ]; then
     CONFPARMS=--enable-64-bit-bfd
     else
     CONFPARMS=
     fi
    
     AR=ar AS=as ${SOURCE_DIR}/configure --prefix=${TOOLS} \
     --build=${NEW_OS_HOST} \
     --host=${NEW_OS_HOST} \
     --target=${NEW_OS_TARGET} \
     --with-sysroot=${ROOTFS} \
     --disable-nls \
     --enable-shared \
     --disable-multilib ${CONFPARMS}
    }
    
    source_build()
    {
     cd ${BUILD_DIR}
    
     make configure-host
     make
     make install
    
     mkdir -pv ${ROOTFS}/usr/include
     cp -v ${SOURCE_DIR}/include/libiberty.h ${ROOTFS}/usr/include/
    }
  4. gcc-static-4.3.1
    代码:
     HOMEPAGE="http://gcc.gnu.org/"
    SOURCE_URL="http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2
     http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2.sig"
    SOURCE_MD5=""
    
    SOURCE_DIR=${SOURCE}/gcc-${PACKAGE_VERSION}
    BUILD_DIR=${SOURCE}/gcc-build
    
    source_tree()
    {
     cd ${SOURCE}
     tar -xvf gcc-${PACKAGE_VERSION}.tar.bz2
    
     cd ${SOURCE_DIR}
    
     #posix
     sed -i -e "s@tail -1@tail -n 1@g" $(grep -lr "tail -1" *)
     sed -i -e "s@tail -3@tail -n 3@g" $(grep -lr "tail -3" *)
     sed -i -e "s@head -1@head -n 1@g" $(grep -lr "head -1" *)
    
     #--disable-multilib /lib64->/lib
     if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
     sed -i -e "s@/lib64/ld@/lib/ld@g" gcc/config/*/linux64.h
     sed -i -e "s@../lib32 ../lib ../lib64@../lib32 ../lib ../lib@g" \
     -e "s@../lib64 ../lib@../lib ../lib@g" \
     -e "s@../lib64@../lib@g" gcc/config/*/t-linux64
     fi
    
     #cross hacking
     sed -i -e "s@/usr/libexec/gcc/@@g" -e "s@/usr/lib/gcc/@@g" gcc/gcc.c
    
     mkdir -pv ${BUILD_DIR}
    }
    
    source_config()
    {
     cd ${BUILD_DIR}
     AR=ar \
     ${SOURCE_DIR}/configure --prefix=${TOOLS} \
     --build=${NEW_OS_HOST} \
     --host=${NEW_OS_HOST} \
     --target=${NEW_OS_TARGET} \
     --with-sysroot=${ROOTFS} \
     --disable-nls \
     --disable-shared \
     --enable-languages=c \
     --disable-multilib
    }
    
    source_build()
    {
     cd ${BUILD_DIR}
     make all-gcc
     make all-target-libgcc
     make install-gcc
     make install-target-libgcc
    }
    代码:
     HOMEPAGE="http://gcc.gnu.org/"
    SOURCE_URL="http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2
     http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2.sig"
    SOURCE_MD5=""
    
    SOURCE_DIR=${SOURCE}/gcc-${PACKAGE_VERSION}
    BUILD_DIR=${SOURCE}/gcc-build
    
    source_tree()
    {
     cd ${SOURCE}
     tar -xvf gcc-${PACKAGE_VERSION}.tar.bz2
    
     cd ${SOURCE_DIR}
    
     #posix
     sed -i -e "s@tail -1@tail -n 1@g" $(grep -lr "tail -1" *)
     sed -i -e "s@tail -3@tail -n 3@g" $(grep -lr "tail -3" *)
     sed -i -e "s@head -1@head -n 1@g" $(grep -lr "head -1" *)
    
     #--disable-multilib /lib64->/lib
     if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
     sed -i -e "s@/lib64/ld@/lib/ld@g" gcc/config/*/linux64.h
     sed -i -e "s@../lib32 ../lib ../lib64@../lib32 ../lib ../lib@g" \
     -e "s@../lib64 ../lib@../lib ../lib@g" \
     -e "s@../lib64@../lib@g" gcc/config/*/t-linux64
     fi
    
     #cross hacking
     sed -i -e "s@/usr/libexec/gcc/@@g" -e "s@/usr/lib/gcc/@@g" gcc/gcc.c
    
     #cross hacking
     sed -i 's@$(GCC_FOR_TARGET) -dumpspecs@echo -n@' gcc/Makefile.in
    
     mkdir -pv ${BUILD_DIR}
    }
    
    source_config()
    {
     cd ${BUILD_DIR}
     AR=ar \
     CC_FOR_TARGET=${NEW_OS_TARGET}-gcc \
     ${SOURCE_DIR}/configure --prefix=${TOOLS} \
     --build=${NEW_OS_HOST} \
     --host=${NEW_OS_HOST} \
     --target=${NEW_OS_TARGET} \
     --with-sysroot=${ROOTFS} \
     --disable-nls \
     --disable-shared \
     --enable-languages=c \
     --disable-multilib
    }
    
    source_build()
    {
     cd ${BUILD_DIR}
     make all-gcc
     make install-gcc
     make all-target-libgcc
     make install-target-libgcc
    }
    注意:
    这里用补丁建立空spec文件,否则交叉编译会出错,伪交叉编译会引人宿主gcc spec。(2008.07.16已废弃)
  5. glibc-2.7
    代码:
     HOMEPAGE="http://www.gnu.org/software/libc/"
    SOURCE_URL="http://ftp.gnu.org/gnu/glibc/glibc-2.7.tar.bz2
     http://ftp.gnu.org/gnu/glibc/glibc-2.7.tar.bz2.sig
     http://ftp.gnu.org/gnu/glibc/glibc-ports-2.7.tar.bz2
     http://ftp.gnu.org/gnu/glibc/glibc-ports-2.7.tar.bz2.sig"
    SOURCE_MD5=""
    
    SOURCE_DIR=${SOURCE}/${PACKAGE_NAME}-${PACKAGE_VERSION}
    BUILD_DIR=${SOURCE}/${PACKAGE_NAME}-build
    
    source_tree()
    {
     cd ${SOURCE}
     tar -xvf ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.bz2
     tar -xvf ${PACKAGE_NAME}-ports-${PACKAGE_VERSION}.tar.bz2
     mv -v ${PACKAGE_NAME}-ports-${PACKAGE_VERSION} ${SOURCE_DIR}/ports
    
     cd ${SOURCE_DIR}
    
     sed -i -e "s@/etc/mtab@/etc/ramdisk/mtab@" sysdeps/unix/sysv/linux/paths.h
    
     #libgcc_eh cross hacking
     sed -i -e "s@-lgcc_eh@@g" Makeconfig
    
     #for gcc-4.3.1
     sed -i 's@-nostdinc -isystem $ccheaders@& -isystem $ccheaders-fixed@' configure
    
     mkdir -pv ${BUILD_DIR}
    }
    
    source_config()
    {
     cd ${BUILD_DIR}
    
     echo "libc_cv_forced_unwind=yes" >> config.cache
     echo "libc_cv_c_cleanup=yes" >> config.cache
     echo "libc_cv_${NEW_OS_ARCH}_tls=yes" >> config.cache
     if [ "${NEW_OS_ARCH}" = "i386" ]; then
     echo "libc_cv_386_tls=yes" >> config.cache
     echo "CFLAGS+=-march=${NEW_OS_MARCH}" >> configparms
     fi
     echo "install_root=${ROOTFS}" >> configparms
     echo "slibdir=/lib" >> configparms
    
     BUILD_CC=gcc \
     CC=${NEW_OS_TARGET}-gcc \
     AR=${NEW_OS_TARGET}-ar \
     RANLIB=${NEW_OS_TARGET}-ranlib \
     CFLAGS="-mtune=generic -g -O2" \
     ${SOURCE_DIR}/configure --prefix=/usr \
     --build=${NEW_OS_HOST} \
     --host=${NEW_OS_TARGET} \
     --target=${NEW_OS_TARGET} \
     --with-headers=${ROOTFS}/usr/include \
     --libdir=/usr/lib \
     --libexecdir=/usr/lib/glibc \
     --disable-profile \
     --enable-add-ons \
     --with-tls \
     --enable-kernel=2.6.0 \
     --with-__thread \
     --with-binutils=${TOOLS}/bin \
     --cache-file=config.cache
    }
    
    source_build()
    {
     cd ${BUILD_DIR}
    
     make
    
     #--disable-multilib /lib64->/lib
     if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
     sed -i -e "s@/lib64/ld@/lib/ld@" elf/ldd
     fi
    
     make install
    
     mkdir -pv ${ROOTFS}/etc/ramdisk
     ln -sfv ramdisk/mtab ${ROOTFS}/etc/mtab
     ln -sfv ramdisk/resolv.conf ${ROOTFS}/etc/resolv.conf
    
     mkdir -pv ${ROOTFS}/lib
     ln -sfv libcrypt-2.7.so ${ROOTFS}/lib/libcrypt.so
    
     cat > ${ROOTFS}/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
    
     cat > ${ROOTFS}/etc/ld.so.conf << eof
    #begin /etc/ld.so.conf
    #end /etc/ld.so.conf
    eof
    }
  6. gcc-4.3.1
    代码:
     HOMEPAGE="http://gcc.gnu.org/"
    SOURCE_URL="http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2
     http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2.sig"
    SOURCE_MD5=""
    
    SOURCE_DIR=${SOURCE}/${PACKAGE_NAME}-${PACKAGE_VERSION}
    BUILD_DIR=${SOURCE}/${PACKAGE_NAME}-build
    
    source_tree()
    {
     cd ${SOURCE}
     tar -xvf ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.bz2
    
     cd ${SOURCE_DIR}
    
     #posix
     sed -i -e "s@tail -1@tail -n 1@g" $(grep -lr "tail -1" *)
     sed -i -e "s@tail -3@tail -n 3@g" $(grep -lr "tail -3" *)
     sed -i -e "s@head -1@head -n 1@g" $(grep -lr "head -1" *)
    
     #--disable-multilib /lib64->/lib
     if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
     sed -i -e "s@/lib64/ld@/lib/ld@g" gcc/config/*/linux64.h
     sed -i -e "s@../lib32 ../lib ../lib64@../lib32 ../lib ../lib@g" \
     -e "s@../lib64 ../lib@../lib ../lib@g" \
     -e "s@../lib64@../lib@g" gcc/config/*/t-linux64
     fi
    
     #cross hacking
     sed -i -e "s@/usr/libexec/gcc/@@g" -e "s@/usr/lib/gcc/@@g" gcc/gcc.c
    
     mkdir -pv ${BUILD_DIR}
    }
    
    source_config()
    {
     cd ${BUILD_DIR}
     AR=ar \
     ${SOURCE_DIR}/configure --prefix=${TOOLS} \
     --build=${NEW_OS_HOST} \
     --host=${NEW_OS_HOST} \
     --target=${NEW_OS_TARGET} \
     --with-sysroot=${ROOTFS} \
     --disable-nls \
     --enable-shared \
     --enable-languages=c,c++ \
     --enable-__cxa_atexit \
     --enable-c99 \
     --enable-long-long \
     --enable-threads=posix \
     --disable-multilib
    }
    
    source_build()
    {
     cd ${BUILD_DIR}
     make
     make install
    }

    注意:
    建立工具链时,这里特别添加了--build=${NEW_OS_HOST},这是gcc-4.3系列与之前版本的区别,之前版本gcc配置时探测到 --host --target 不同,会自动设置--build与--host相同,但gcc-4.3会根据系统信息配置。
    所以伪交叉编译时会出问题,具体见 用GCC 4.3-20040810构造SYSROOT工具链 ,特别说明,这个不是bug,添加--build后可以正常编译不需额外补丁。
    为统一,建立交叉工具链时均加上--build=${NEW_OS_HOST}。
    代码:
     HOMEPAGE="http://gcc.gnu.org/"
    SOURCE_URL="http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2
     http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2.sig"
    SOURCE_MD5=""
    
    SOURCE_DIR=${SOURCE}/${PACKAGE_NAME}-${PACKAGE_VERSION}
    BUILD_DIR=${SOURCE}/${PACKAGE_NAME}-build
    
    source_tree()
    {
     cd ${SOURCE}
     tar -xvf ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.bz2
    
     cd ${SOURCE_DIR}
    
     #posix
     sed -i -e "s@tail -1@tail -n 1@g" $(grep -lr "tail -1" *)
     sed -i -e "s@tail -3@tail -n 3@g" $(grep -lr "tail -3" *)
     sed -i -e "s@head -1@head -n 1@g" $(grep -lr "head -1" *)
    
     #--disable-multilib /lib64->/lib
     if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
     sed -i -e "s@/lib64/ld@/lib/ld@g" gcc/config/*/linux64.h
     sed -i -e "s@../lib32 ../lib ../lib64@../lib32 ../lib ../lib@g" \
     -e "s@../lib64 ../lib@../lib ../lib@g" \
     -e "s@../lib64@../lib@g" gcc/config/*/t-linux64
     fi
    
     #cross hacking
     sed -i -e "s@/usr/libexec/gcc/@@g" -e "s@/usr/lib/gcc/@@g" gcc/gcc.c
    
     mkdir -pv ${BUILD_DIR}
    }
    
    source_config()
    {
     cd ${BUILD_DIR}
     AR=ar \
     CC_FOR_TARGET=${NEW_OS_TARGET}-gcc \
     CXX_FOR_TARGET=${NEW_OS_TARGET}-g++ \
     ${SOURCE_DIR}/configure --prefix=${TOOLS} \
     --build=${NEW_OS_HOST} \
     --host=${NEW_OS_HOST} \
     --target=${NEW_OS_TARGET} \
     --with-sysroot=${ROOTFS} \
     --disable-nls \
     --enable-shared \
     --enable-languages=c,c++ \
     --enable-__cxa_atexit \
     --enable-c99 \
     --enable-long-long \
     --enable-threads=posix \
     --disable-multilib
    }
    
    source_build()
    {
     cd ${BUILD_DIR}
     make
     make install
    }
    
    (2008.07.16已废弃)
二、${NEW_OS_USER} 用户交叉编译临时系统
注意:
为统一,与建立交叉工具链类似,1-4编译时特别添加 --target=${NEW_OS_TARGET}。
交叉编译mpfr-2.3.1时,需要使用--with-gmp-build指明gmp交叉编译目录,否则有恼人的错误引用问题,伪交叉编译时则会连接到宿主libgmp.so。
  1. binutils-2.18
  2. gmp-4.2.2
  3. mpfr-2.3.1
  4. gcc-4.3.1
  5. ncurses-5.6
  6. bash-3.2
  7. bzip2-1.0.4
  8. coreutils-6.9
  9. diffutils-2.8.7
  10. findutils-4.2.33
  11. zlib-1.2.3
  12. file-4.25
  13. gawk-3.1.6
  14. gettext-0.17
  15. grep-2.5.3
  16. gzip-1.3.12
  17. make-3.81
  18. patch-2.5.9
  19. sed-4.1.5
  20. tar-1.20
  21. texinfo-4.11
  22. e2fsprogs-1.40.2
  23. sysvinit-2.86
  24. module-init-tools-3.2.2
  25. util-linux-ng-2.13.1
  26. udev-118
  27. shadow-4.1.1
  28. linux-2.6.25.7
三、root 用户处理交叉编译临时系统
  1. 现在更改临时系统用户、用户组为root
  2. 创建启动必须的设备文件
  3. 安装到新分区或按需定制
  4. 安装一个bootloader(可选)
四、boot/chroot进入交叉编译临时系统,安装本地编译临时perl,测试工具
  1. perl-5.10.0(这里使用正式安装perl时相同编译配置,方便维护)
  2. m4-1.4.10(这里使用正式安装m4时相同编译配置,方便维护,gmp本地编译时需要)
  3. 测试工具(可选)
五、boot/chroot进入交叉编译临时系统,建立本地编译基本系统
  1. base-filesystem-0
  2. linux-header-2.6.25.7
  3. glibc-2.7
  4. binutils-2.18
  5. gmp-4.2.2
  6. mpfr-2.3.1
  7. gcc-4.3.1
  8. man-pages-3.00
  9. sed-4.1.5
  10. e2fsprogs-1.40.2
  11. coreutils-6.9
  12. iana-etc-2.20
  13. m4-1.4.10
  14. bison-2.3
  15. ncurses-5.6
  16. procps-3.2.7
  17. libtool-1.5.26
  18. flex-2.5.35
  19. iproute2-2.6.23
  20. perl-5.10.0
  21. readline-5.2
  22. zlib-1.2.3
  23. autoconf-2.61
  24. automake-1.10.1
  25. bash-3.2
  26. bzip2-1.0.4
  27. diffutils-2.8.7
  28. file-4.25
  29. findutils-4.2.33
  30. gawk-3.1.6
  31. gettext-0.17
  32. grep-2.5.3
  33. groff-1.19.2
  34. gzip-1.3.12
  35. inetutils-1.5
  36. kbd-1.12
  37. less-418
  38. make-3.81
  39. man-1.6f
  40. mktemp-1.5
  41. module-init-tools-3.2.2
  42. patch-2.5.9
  43. psmisc-22.6
  44. Linux-PAM-0.99.10.0
  45. shadow-4.1.1
  46. sysklogd-1.5
  47. sysvinit-2.86
  48. tar-1.20
  49. texinfo-4.11
  50. udev-118
  51. util-linux-ng-2.13.1
  52. vim-7.1
  53. linux-2.6.25.7
  54. iptables-1.4.0
  55. gpm-1.20.5
  56. net-tools-1.60
  57. dhcp-4.0.0
  58. libgpg-error-1.6
  59. libgcrypt-1.4.0
  60. gnutls-2.3.1
  61. openssl-0.9.8g
  62. wget-1.11
  63. lynx2-8-6
  64. openssh-4.7p1
  65. pkg-config-0.23
本文使用的简化编译脚本已附,命名以自解释为原则。
回头看看,自己改的东西太多,一点一点贴上来太麻烦。
使用帮助,请执行./new_os.sh。
不显式挂载分区,重写的简化启动脚本,完全自定制(也就是说不一定适合每个人),请有选择的参考。
另,请不要与官方alfs比较,用途不同。


与gcc-4.3.1不兼容软件包列表:
tar-1.19,升级到tar-1.20解决。
scim-pinyin-0.5.91,添加#include <string.h>解决。
scim-fcitx-3.1.1,添加#include <string.h>解决。
kvm-68,升级到kvm-70解决,使用kernel自带模块代码,不再需要gcc-3.3支持。
qemu-0.9.1,暂未解决,可能是内核头文件引起的,gcc-3.3.6也不行

alsa-tools-1.0.16,升级到alsa-*-1.0.17rc2解决。

下面部分源自xorg-7.3,不影响自己使用,暂不深究。
xf86-input-acecad-1.2.0
xf86-input-calcomp-1.1.0
xf86-input-citron-2.2.0
xf86-input-dmc-1.1.0
xf86-input-dynapro-1.1.0
xf86-input-elo2300-1.1.0
xf86-input-evdev-1.1.2
xf86-input-magellan-1.1.0
xf86-input-microtouch-1.1.0
xf86-input-penmount-1.2.0
xf86-input-spaceorb-1.1.0
xf86-input-vmmouse-12.4.1
xf86-input-void-1.1.0
xf86-video-glide-1.0.0


上传的附件
new_os.tar.gz (26.3 KB, 24 次查看)
new_os_20080716.tar.gz (26.5 KB, 24 次查看)

作者: 聚焦深空   发布时间: 2008-06-24

不错,不错,顶一下。

作者: youbest   发布时间: 2008-06-24

刚刚把你的脚本下载看了一下,你不是说你有采用Fakeroot方式Build的脚本么?好像还是老一套的LFS。

我前段时间试验了一下,所有的安装命令都用make DESTDIR=的方式安装到空目录,然后tar打包保存备份。这样检查依赖性非常方便:只要从空目录开始,把需要的包解开,然后你就可以检查依赖性是否满足了。万一缺少什么,如果有建好的包就用,否则build一遍。

我觉得这种方法应该可以推广开去。这样差不多就是用SLACKWARE的tgz包管理方法了,虽然原始,但非常简单。

作者: 地球发动机   发布时间: 2008-06-25

基本上发行版的包都是用 DESTDIR 类似的东西做出来的吧?
不过有些不太一样,比如 glibc, 用的就是 install_root, 我记得还有个什么包用的是 INSTALL_ROOT, 具体要看 Makefile 了

作者: LanEast   发布时间: 2008-06-25

引用:
刚刚把你的脚本下载看了一下,你不是说你有采用Fakeroot方式Build的脚本么?好像还是老一套的LFS。

我前段时间试验了一下,所有的安装命令都用make DESTDIR=的方式安装到空目录,然后tar打包保存备份。这样检查依赖性非常方便:只要从空目录开始,把需要的包解开,然后你就可以检查依赖性是否满足了。万一缺少什么,如果有建好的包就用,否则build一遍。
前面几步,建立工具链、交叉编译临时系统、临时perl、安装测试工具,我已经用fakeroot方式验证过,这里提供的是简化脚本,所以略去,剩下的自然和官方方法类似了;
从建立基本系统开始,默认使用fakeroot方式打包备份,然后真正安装;
工具链、临时系统,可以整体打包备份,不过我一般不保留,习惯了过河拆桥。

引用:
我觉得这种方法应该可以推广开去。这样差不多就是用SLACKWARE的tgz包管理方法了,虽然原始,但非常简单。
fakeroot方式是标准的软件包维护方法,debian dpkg rules、redhat rpm spec一直在用的方法,我也只是觉得好才拿过来用。

作者: 聚焦深空   发布时间: 2008-06-25

引用:
基本上发行版的包都是用 DESTDIR 类似的东西做出来的吧?
并不是所有的软件包都支持DESTDIR的安装方式,这是fakeroot方式稍显麻烦的地方。当你完成第一遍后,这就是优点了,维护很方便的。

arch的包管理工具好像不是这样运行的,不了解,不多言。

引用:
不过有些不太一样,比如 glibc, 用的就是 install_root, 我记得还有个什么包用的是 INSTALL_ROOT, 具体要看 Makefile 了
glibc交叉编译阶段是这样,系统自举后,一样可以使用标准的fakeroot方式重新安装。

作者: 聚焦深空   发布时间: 2008-06-25

glibc我没交叉编译,不过也还是用的 make install_root=xxx install 安装的- -U

arch 的包管理还真不知道是什么样的,没用过 arch

DESTDIR 就是 fakeroot 的方式吧,还有我说的那个 glibc 的 install_root, 内核头文件的 INSTALL_HDR_PATH 应该都可以看作是 fakeroot 吧,只不过指定方式不同而已, 不过你用的是 sysroot 的方式,也许指定的方式不同,没玩过 CLFS

作者: LanEast   发布时间: 2008-06-25

刚看了一下别人写的 arch 的 PKGBUILD 文件,似乎也用 DESTDIR 这一类方式的,也就是楼主说的 fakeroot

作者: LanEast   发布时间: 2008-06-25

引用:
作者: 聚焦深空
前面几步,建立工具链、交叉编译临时系统、临时perl、安装测试工具,我已经用fakeroot方式验证过,这里提供的是简化脚本,所以略去,剩下的自然和官方方法类似了;
从建立基本系统开始,默认使用fakeroot方式打包备份,然后真正安装;
工具链、临时系统,可以整体打包备份,不过我一般不保留,习惯了过河拆桥。
工具链和临时系统的fakeroot方式在调试、维护、升级的时候也非常有用。比方说,你已经写好一个glibc2.7的脚本,现在要升级glibc 3.0,那么只要直接使用原有binutils pass1 和 gcc static (可能要加上gmp/mpfr)这几个包,就OK了。这样的优点是你调试脚本的时候可能未必能一次完成,如果每次都要从头开始要浪费不少时间。

引用:
fakeroot方式是标准的软件包维护方法,debian dpkg rules、redhat rpm spec一直在用的方法,我也只是觉得好才拿过来用。
我当然知道这是标准方法。不然那些软件包是如何产生的呢?不过我的意思是,单纯的fakeroot出来的包,不含有任何附加功能,跟这最类似的是SLACKWARE的TGZ。要是附加上其它功能,就可以变成RPM或则DEB了。要是做一个网站放这些包,就变成YUM/APT了……

作者: 地球发动机   发布时间: 2008-06-25

fakeroot 出来的包再配上个脚本,就能做简单的包管理了,对于 LFS 来说,应该是很不错的做法了

作者: LanEast   发布时间: 2008-06-25

这个问题难道大家不屑于指正么?

是GNU for GNU's Not Unix
而不是GUN

作者: zhllg   发布时间: 2008-06-25

引用:
作者: zhllg
这个问题难道大家不屑于指正么?

是GNU for GNU's Not Unix
而不是GUN
笔误,笔误,低级错误,已修正,多谢!

作者: 聚焦深空   发布时间: 2008-06-25

引用:
作者: 地球发动机
工具链和临时系统的fakeroot方式在调试、维护、升级的时候也非常有用。比方说,你已经写好一个glibc2.7的脚本,现在要升级glibc 3.0,那么只要直接使用原有binutils pass1 和 gcc static (可能要加上gmp/mpfr)这几个包,就OK了。这样的优点是你调试脚本的时候可能未必能一次完成,如果每次都要从头开始要浪费不少时间。
用我的脚本,满足你想法的命令如下
代码:
#toolchain
/auto.sh toolchain check_mark \
 source_tree \
 fakeroot \
 source_config \
 source_build \
 tarball \
 "ROOTFS=${TOOLS}" \
 install_package \
 mark

/auto.sh toolchain unmark

#cross_system
/auto.sh cross_system check_mark \
 source_tree \
 fakeroot \
 source_config \
 source_build \
 tarball \
 "ROOTFS=${NEW_OS_DIR}/rootfs" \
 install_package \
 mark

/auto.sh cross_system unmark
我自己验证时,使用的命令只是没有打包而已。
代码:
#toolchain
/auto.sh toolchain check_mark \
 source_tree \
 source_config \
 source_build \
 mark

/auto.sh toolchain unmark

#cross_system
/auto.sh cross_system check_mark \
 source_tree \
 source_config \
 source_build \
 mark

/auto.sh cross_system unmark
使用这种格式,中途某个软件包编译失败,自动退出(此时可以修正脚本),
重新执行相同的命令,自动跳过有标记的软件包,从失败的软件包处继续进行。

作者: 聚焦深空   发布时间: 2008-06-25

GCC-static部分:经过试验,在正确添加--build --host --target参数之后,可以不必沿用过去的模式来build GCC,无须设置CC_FOR_TARGET。现在的build模式如下:
1.照常config
2. make all-target-libgcc
3. make install-target-libgcc

作者: 地球发动机   发布时间: 2008-07-06

引用:
作者: 地球发动机
GCC-static部分:经过试验,在正确添加--build --host --target参数之后,可以不必沿用过去的模式来build GCC,无须设置CC_FOR_TARGET。现在的build模式如下:
1.照常config
2. make all-target-libgcc
3. make install-target-libgcc
工具链gcc静态编译部分
如果只是编译安装裸编译器
make all-gcc
make install-gcc
是不需要设置CC_FOR_TARGET的;
编译安装libgcc
make all-target-libgcc
make install-target-libgcc
我这里还是需要设置CC_FOR_TARGET=${NEW_OS_TARGET}-gcc,否则make all-target-libgcc过程中会出错,提示找不到${NEW_OS_TARGET}-cc。

如果真正交叉编译,设置NEW_OS_HOST=${MACHTYPE},重新安装宿主binutils,使在shell搜索路径中可以找到${NEW_OS_HOST}-ar,AR是不需要设置的,但为了支持伪交叉编译,还是现在设置变量的方式好些。

我的方法,用最小安装干净宿主验证过不止一次,所有参数是在建立工具链过程中逐渐添加的,是错误、除错的结果。
我可以肯定的说,你严格按照我的方式做,这些参数是必须的。
我没有故意参考你以前帖子中的过程,正是为了确定所有必须的步骤,而不受任何人,包括自己的影响。
和你原来的方法类似,正说明那些步骤是必须的。

如果你真的做到你所说的,最好说明一下你宿主的情况,你系统变量定义与我不同的地方,以及其他不同的地方,我们好进一步简化步骤。

作者: 聚焦深空   发布时间: 2008-07-07

引用:
作者: 地球发动机
GCC-static部分:经过试验,在正确添加--build --host --target参数之后,可以不必沿用过去的模式来build GCC,无须设置CC_FOR_TARGET。现在的build模式如下:
1.照常config
2. make all-target-libgcc
3. make install-target-libgcc
确定一下,你是不是用的干净宿主?
是不是用之前留下来的工具链,升级到gcc-4.3.1?
是不是伪交叉编译?

我只验证过
i486-pc-linux-gnu -> i686-pc-linux-gnu
i486-pc-linux-gnu -> x86_64-unknown-linux-gnu
都是真正的交叉编译。
正如我之前说的,伪交叉编译方式,在真正交叉编译验证之前不可靠。
我的方法,已经用交叉编译方式验证过,所以进行伪交叉编译也没问题。

如果是伪交叉编译,出现你的情况,
可能是宿主在建立工具链之前,已经存在${NEW_OS_TARGET}-cc,
make all-target-libgcc 时调用的是宿主的 ${NEW_OS_TARGET}-cc,而我们应该用的是新编译出来的${NEW_OS_TARGET}-gcc。
如果真是这样,不会影响使用,但工具链纯度有点问题。

作者: 聚焦深空   发布时间: 2008-07-07

从编译过程看,实验中的CC_FOR_TARGET是自动采用了刚编译的xgcc,所用的参数跟本机编译bootstrap时差不多。

因此,纯度上应该没有问题。

可能这仅能用于伪交叉编译也就是--build和--host相同的情况。

作者: 地球发动机   发布时间: 2008-07-07

引用:
作者: 地球发动机
从编译过程看,实验中的CC_FOR_TARGET是自动采用了刚编译的xgcc,所用的参数跟本机编译bootstrap时差不多。

因此,纯度上应该没有问题。

可能这仅能用于伪交叉编译也就是--build和--host相同的情况。
我刚刚参考你的意见,用伪交叉编译方式验证,是你说的情况。
看来是gcc-4.3系列开发者对伪交叉编译、交叉编译没有平等对待。

作者: 聚焦深空   发布时间: 2008-07-07

让我们解决这个问题。GCC配置脚本的输出中,最后一部分内容非常重要,一般是形如

i686-pc-linux-gnu-cc : pre-installed

这样的形式。对于本机交叉编译即build=host的情况,CC和GCC相应项的输出应该是

i686-pc-linux-gnu-cc : just compiled

如果这里不对,就会出现你所说的问题。请贴出来共同研究一下。不需要Make, configure一下即可

作者: 地球发动机   发布时间: 2008-07-10

伪交叉编译方式,我的机器,不管是宿主还是工具链,都不存在${NEW_OS_TARGET}-cc,但是存在${NEW_OS_TARGET}-c++,不存在just compiled的必要。

PS:我不准备对伪交叉编译方式单独优化:一是自己几乎不使用伪交叉编译方式,二是自己相信给出的方法同样适用伪交叉编译。

PS:一个同时适用交叉编译、伪交叉编译方式,不需要设置CC_FOR_TARGET、CXX_FOR_TARGET,并且比较完美的解决方案是,安装${NEW_OS_TARGET}-gcc之后,手工硬连接一份为${NEW_OS_TARGET}-cc,或者把这种修正合并到相应gcc源码相应Makefile.in。这样可以做到和${NEW_OS_TARGET}-c++对称。

作者: 聚焦深空   发布时间: 2008-07-10

引用:
作者: 地球发动机
可能这仅能用于伪交叉编译也就是--build和--host相同的情况。
更正一点,NEW_OS_HOST、NEW_OS_TARGET事实上相同才是伪交叉编译。
如i686-cross-linux-gnu、i686-pc-linux-gnu。我们建立的交叉编译、伪交叉编译工具链运行于宿主,所以工具链gcc配置时--build和--host相同。
使用gcc-4.3之前版本时只是不需显式指明而已。

大多数人不会疯狂到建立交叉编译的交叉编译工具链,也就是--build、--host、--target都不同的情况。

建立交叉编译工具链时,添加--build是为gcc-4.3系列设置正确的编译系统类型,如MACHTYPE=i486-pc-linux-gnu,cpu为k8,即使使用xxx-i486的内核,gcc-4.3系列自动配置的--build仍为i686-pc-linux-gnu。
所以,建立交叉编译工具链时,需要强制指定--build。

作者: 聚焦深空   发布时间: 2008-07-10

引用:
作者: 聚焦深空
更正一点,NEW_OS_HOST、NEW_OS_TARGET事实上相同才是伪交叉编译。
如i686-cross-linux-gnu、i686-pc-linux-gnu。我们建立的交叉编译、伪交叉编译工具链运行于宿主,所以工具链gcc配置时--build和--host相同。
使用gcc-4.3之前版本时只是不需显式指明而已。

大多数人不会疯狂到建立交叉编译的交叉编译工具链,也就是--build、--host、--target都不同的情况。

建立交叉编译工具链时,添加--build是为gcc-4.3系列设置正确的编译系统类型,如MACHTYPE=i486-pc-linux-gnu,cpu为k8,即使使用xxx-i486的内核,gcc-4.3系列自动配置的--build仍为i686-pc-linux-gnu。
所以,建立交叉编译工具链时,需要强制指定--build。
根据你所做的hack(有些是我之前做的),我断定,你的系统上一定有把原本应该是just-compiled的东西检测为pre-installed的情况。

1、CC_FOR_TARGET 这个什么时候需要呢?GCC编译系统会进行检测,如果build=host,它会检测成just-compiled,也就是说,不用宿主的东西,以保证纯度。如果build不等于host,那么检测结果为pre-installed。这时GCC不得不依赖于宿主提供编译器去编译target上的东西因为编译出来的东西在宿主上(可能)无法运行。

2、由此可见,正常情况下如果CC_FOR_TARGET是just-compiled,那么就不需要在make all-target-libgcc之前先make all-gcc && make install-gcc。因为编译系统应该自动调用新编译出来的编译器进行编译。

3、回头看看关于specs的那个hack,这很明显也跟以上情况有关。原本GCC编译系统在完成gcc之后,需要调用GCC_FOR_TARGET获得一个SPECS。如上所述,如果GCC_FOR_TARGET被检测为just-compiled,那么编译系统将调用刚编译好的xgcc来获得SPECS,否则将依赖于预先安装的交叉编译器。

我刚刚完成一个x86_64 -> i686的build,在注意了确保build=host之后,configure后直接make all-target-libgcc是成功的。

关于build,host和target,我想可以总结如下:
1、build=host=target 是本机原生编译,默认的情况,LFS使用的情况。
2、build=host<>target是本机交叉编译,CLFS交叉编译工具链使用的情况。
3、build<>host=target是交叉原生编译,CLFS原生工具链就是这种情况:依赖于build上的交叉编译工具链,来编译target上的原生工具链
4、build<>host<>target是加拿大式编译,一般很少使用。
由上可见,至少情况3是必须依赖pre-installed cc的。更何况GCC必须支持情况4。所以才有需要设置CC_FOR_TARGET的情况。

作者: 地球发动机   发布时间: 2008-07-12

引用:
根据你所做的hack(有些是我之前做的),我断定,你的系统上一定有把原本应该是just-compiled的东西检测为pre-installed的情况。
哈,要为自己的断言负责。
交叉编译工具链,在创建过程中,其实是不需要考虑just-compiled、pre-installed的,因为宿主一清二白,所有交叉编译工具链需要的东西都是从〇建立起来的。
伪交叉编译工具链,在创建过程中,才需要考虑just-compiled、pre-installed的问题,因为工具链创建过程中可能会错误调用同名宿主程序,影响工具链纯度,所以必须注意安装步骤,要保证创建过程中总能找到合适的程序。

引用:
1、CC_FOR_TARGET 这个什么时候需要呢?GCC编译系统会进行检测,如果build=host,它会检测成just-compiled,也就是说,不用宿主的东西,以保证纯 度。如果build不等于host,那么检测结果为pre-installed。这时GCC不得不依赖于宿主提供编译器去编译target上的东西因为编 译出来的东西在宿主上(可能)无法运行。
我建立交叉编译工具链过程中,
不设置CC_FOR_TARGET 时,make all-target-libgcc开始部分的自动配置过程会出错,提示找不到${NEW_OS_TARGET}-cc,
设置CC_FOR_TARGET后,一切正常,但不会调用xgcc,也就是出现pre-installed的情况,按我的步骤,这个也是正常的,之前的make install-gcc已经安装过裸编译器,到这一步其实使用{NEW_OS_TARGET}-gcc与xgcc没有本质区别,他们事实上一样,只是名字、路径不同。

引用:
2、由此可见,正常情况下如果CC_FOR_TARGET是just-compiled,那么就不需要在make all-target-libgcc之前先make all-gcc && make install-gcc。因为编译系统应该自动调用新编译出来的编译器进行编译。
这里你懒惰了一下,依靠Makefile中依赖关系自动完成这个过程,对你的结果,不感到意外。

我使用的方法沿用gcc-4.2系列方法而来,条理清晰,与你之前hack结果一致。

我不怀疑有更简单方法,在你的贴子中,我曾提到自己用fakeroot方式验证过伪交叉编译方式gcc第一遍make && make install的结果与你的方法(也就是现在我沿用的方法)结果一致。

也许gcc第一遍,交叉编译方式与伪交叉编译方式,都只需make && make install,并且不需设置CC_FOR_TARGET,最初建立gcc-4.3.1的系统时,我怎么忘了验证一下。不过我还是喜欢现在条理清晰的方式。

引用:
3、回头看看关于specs的那个hack,这很明显也跟以上情况有关。原本GCC编译系统在完成gcc之后,需要调用GCC_FOR_TARGET获得 一个SPECS。如上所述,如果GCC_FOR_TARGET被检测为just-compiled,那么编译系统将调用刚编译好的xgcc来获得 SPECS,否则将依赖于预先安装的交叉编译器。
这个有点意思,我会验证一下。

引用:
我刚刚完成一个x86_64 -> i686的build,在注意了确保build=host之后,configure后直接make all-target-libgcc是成功的。
更有理由相信上面红色部分猜想是正确的。

引用:
关于build,host和target,我想可以总结如下:
1、build=host=target 是本机原生编译,默认的情况,LFS使用的情况。
2、build=host<>target是本机交叉编译,CLFS交叉编译工具链使用的情况。
3、build<>host=target是交叉原生编译,CLFS原生工具链就是这种情况:依赖于build上的交叉编译工具链,来编译target上的原生工具链
4、build<>host<>target是加拿大式编译,一般很少使用。
由上可见,至少情况3是必须依赖pre-installed cc的。更何况GCC必须支持情况4。所以才有需要设置CC_FOR_TARGET的情况。
既然讨论到这个,我们更进一步好了:
1、无异议
2、这是只有建立交叉编译工具链binutils、gcc部分才会出现的情况,严格的说不是交叉编译,他们还是宿主上的程序,但gcc中libgcc、libstdc++部分是交叉编译的,libgcc、libstdc++部分的自动配置过程事实是3所描述情况,这个你可以注意一下。我注意到libstdc++编译错误是--build不正确,才注意到gcc-4.3对--build的特殊处理,所以得出要添加--build的结论。
3、这是交叉编译方式,用于交叉编译工具链中glibc、以及上面提到的情况、交叉编译临时系统、或者交叉编译任何想象的到的软件包(只是困难程度不同罢了)。
4、这够疯狂的,这是特殊的交叉编译方式,可以看作是3的叠加,以自己手头的硬件,短期内看不到必要。

作者: 聚焦深空   发布时间: 2008-07-12

因为x86_64 to i686仍有可能调用宿主的东西(我是multilib),所以我刚才实验了一下真正的交叉编译:x86_64 to mips。

这个有些难度,原因是安装Glibc-ports headers for mips需要调用for mips的编译器。这是个死循环。解决方法是在没有Glibc头文件的情况下编译裸编译器。方法:同gcc-static的编译参数,然后make all-gcc && make install-gcc。(现在有点明白为什么新版本需要让make all-gcc不编译libgcc了,因为现在编译libgcc需要Glibc头文件,而之前的版本并不需要)

然后安装Glibc头文件,即可进行下一步安装。因为我全程采用FAKEROOT方式,因此在这个阶段我把TOOLS目录清空然后重新解压binutils+gmp+mpfr,保证之前的GCC裸编译器不会被意外调用。

第二次编译GCC相当于正常编译GCC的第一次static。经过验证,make all-target-libgcc可以一次成功,但是make install-target-libgcc只会安装libgcc,不安装编译器。所以编译安装方式是
make all-target-libgcc
make install-gcc
make install-target-libgcc

随后glibc可以正常安装(我懒得打那个includes补丁,直接下了一个snapshot;不过那个libeh_a的补丁跑不了)。
而这时进行gcc final编译,一次通过,没有任何问题。

顺便说一句,对于一般的交叉编译,我觉得可能在4.3系列可能真的需要三遍gcc才能完成:第一遍没有glibc的naked gcc,第二遍static with libgcc,第三遍final。换句话说,你的脚本还不够通用,还只能在x86上面跑。

作者: 地球发动机   发布时间: 2008-07-12

也许gcc第一遍,交叉编译方式与伪交叉编译方式,都只需make && make install,并且不需设置CC_FOR_TARGET,最初建立gcc-4.3.1的系统时,我怎么忘了验证一下。不过我还是喜欢现在条理清晰的方式。

[/quote]

要指出的是这并不正确。第一遍无论如何也不能直接make && make install。因为即使--enable-languages=c,但是除了libgcc之外还有一个libmud什么的需要编译,那个东西第一遍编译不出来。

经我验证configure之后最简单的编译安装方式是make all-target-libgcc && make install-gcc && make install-target-libgcc。

作者: 地球发动机   发布时间: 2008-07-12

以帖子中方法新建的系统移植到其他机器为宿主,重新用帖子中方法建立新系统—— i686-pc-linux-gnu -> x86_64-unknown-linux-gnu,在工具链部分binutils->libbfd.la过程中出现oom kill(Out of memory)。目前,我正在尝试解决这个问题,验证过程要延误一下。

引用:
因为x86_64 to i686仍有可能调用宿主的东西(我是multilib),所以我刚才实验了一下真正的交叉编译:x86_64 to mips。

这个有些难度,原因是安装Glibc-ports headers for mips需要调用for mips的编译器。这是个死循环。
查看CLFS、还有 youbest 关于mips的帖子,应当没有这样的问题的。是不是什么地方出错了?

引用:
make all-target-libgcc
make install-gcc
make install-target-libgcc
这样看起来是简单一点,真正的编译过程并没有减少。
实际上,我觉得挺丑陋的。

引用:
顺便说一句,对于一般的交叉编译,我觉得可能在4.3系列可能真的需要三遍gcc才能完成:第一遍没有glibc的naked gcc,第二遍static with libgcc,第三遍final。
你说的前两遍,是第一遍的两个步骤,没必要看作两遍吧。

引用:
换句话说,你的脚本还不够通用,还只能在x86上面跑。
这都被你看出来了。
我确实是想用一个脚本搞定尽可能多的目标架构,所以glibc部分把ports也整合进来,虽然x86、x86_64用不到。
官方手册CLFS、CLFS-Sysroot,arm、ppc、mips部分补丁、软件版本,我顺过一遍,我的脚本应该是适用的,只是没验证而已,即使真的不适用,需要修正的地方也不会很多。
早几年,想用相同版本的软件包编译x86、arm、ppc是不可能的,不同平台软件开发进度不同,现在的情况好多了。

引用:
但是除了libgcc之外还有一个libmud什么的需要编译
这个有些印象,验证时,我会关注一下。

作者: 聚焦深空   发布时间: 2008-07-16

参考 地球发动机 意见,经验证,创建交叉编译工具链gcc部分可作如下修正,不需要设置CC_FOR_TARGET、CXX_FOR_TARGET,不需要空spec。

回头看看,出现这种情况的过程是:
最初沿用gcc-4.2系列方法,第一遍gcc通过,glibc无法编译,缺少libgcc,
回头编译libgcc,make all-target-libgcc,出现错误,要调用不存在的${NEW_OS_TARGET}-cc,查看Makefile自然想到要添加CC_FOR_TARGET,再次编译通过,故添加CC_FOR_TARGET到gcc配置部分,
恢复到第一遍gcc之前状态,再次编译,make all-gcc过程中出现错误,要调用不存在的{NEW_OS_TARGET}-gcc生成spec,自然想到要用空spec修正,忽略了最初是可以通过的,也没有注意到是pre installed的问题,更没考虑make all-gcc之后,先不安装直接make all-target-libgcc,
该方法被保留,
到了第二遍gcc时,注意力集中在解决libstdc++的循环依赖问题,发现要添加--build,配置部分想当然参考gcc第一遍添加了CC_FOR_TARGET、CXX_FOR_TARGET,编译通过,
为美观对称,工具链部分统统添加--build,清空工具链,重新验证一遍通过,定型。

第一遍
代码:
HOMEPAGE="http://gcc.gnu.org/"
SOURCE_URL="http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2
 http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2.sig"
SOURCE_MD5=""

SOURCE_DIR=${SOURCE}/gcc-${PACKAGE_VERSION}
BUILD_DIR=${SOURCE}/gcc-build

source_tree()
{
 cd ${SOURCE}
 tar -xvf gcc-${PACKAGE_VERSION}.tar.bz2

 cd ${SOURCE_DIR}

 #posix
 sed -i -e "s@tail -1@tail -n 1@g" $(grep -lr "tail -1" *)
 sed -i -e "s@tail -3@tail -n 3@g" $(grep -lr "tail -3" *)
 sed -i -e "s@head -1@head -n 1@g" $(grep -lr "head -1" *)

 #--disable-multilib /lib64->/lib
 if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
 sed -i -e "s@/lib64/ld@/lib/ld@g" gcc/config/*/linux64.h
 sed -i -e "s@../lib32 ../lib ../lib64@../lib32 ../lib ../lib@g" \
 -e "s@../lib64 ../lib@../lib ../lib@g" \
 -e "s@../lib64@../lib@g" gcc/config/*/t-linux64
 fi

 #cross hacking
 sed -i -e "s@/usr/libexec/gcc/@@g" -e "s@/usr/lib/gcc/@@g" gcc/gcc.c

 mkdir -pv ${BUILD_DIR}
}

source_config()
{
 cd ${BUILD_DIR}
 AR=ar \
 ${SOURCE_DIR}/configure --prefix=${TOOLS} \
 --build=${NEW_OS_HOST} \
 --host=${NEW_OS_HOST} \
 --target=${NEW_OS_TARGET} \
 --with-sysroot=${ROOTFS} \
 --disable-nls \
 --disable-shared \
 --enable-languages=c \
 --disable-multilib
}

source_build()
{
 cd ${BUILD_DIR}
 make all-gcc
 make all-target-libgcc
 make install-gcc
 make install-target-libgcc
}
第二遍
代码:
HOMEPAGE="http://gcc.gnu.org/"
SOURCE_URL="http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2
 http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2.sig"
SOURCE_MD5=""

SOURCE_DIR=${SOURCE}/${PACKAGE_NAME}-${PACKAGE_VERSION}
BUILD_DIR=${SOURCE}/${PACKAGE_NAME}-build

source_tree()
{
 cd ${SOURCE}
 tar -xvf ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.bz2

 cd ${SOURCE_DIR}

 #posix
 sed -i -e "s@tail -1@tail -n 1@g" $(grep -lr "tail -1" *)
 sed -i -e "s@tail -3@tail -n 3@g" $(grep -lr "tail -3" *)
 sed -i -e "s@head -1@head -n 1@g" $(grep -lr "head -1" *)

 #--disable-multilib /lib64->/lib
 if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
 sed -i -e "s@/lib64/ld@/lib/ld@g" gcc/config/*/linux64.h
 sed -i -e "s@../lib32 ../lib ../lib64@../lib32 ../lib ../lib@g" \
 -e "s@../lib64 ../lib@../lib ../lib@g" \
 -e "s@../lib64@../lib@g" gcc/config/*/t-linux64
 fi

 #cross hacking
 sed -i -e "s@/usr/libexec/gcc/@@g" -e "s@/usr/lib/gcc/@@g" gcc/gcc.c

 mkdir -pv ${BUILD_DIR}
}

source_config()
{
 cd ${BUILD_DIR}
 AR=ar \
 ${SOURCE_DIR}/configure --prefix=${TOOLS} \
 --build=${NEW_OS_HOST} \
 --host=${NEW_OS_HOST} \
 --target=${NEW_OS_TARGET} \
 --with-sysroot=${ROOTFS} \
 --disable-nls \
 --enable-shared \
 --enable-languages=c,c++ \
 --enable-__cxa_atexit \
 --enable-c99 \
 --enable-long-long \
 --enable-threads=posix \
 --disable-multilib
}

source_build()
{
 cd ${BUILD_DIR}
 make
 make install
}

作者: 聚焦深空   发布时间: 2008-07-16

oom kill的问题最新进展如下:
1、怀疑作为宿主的移植过来的i686-pc-linux-gnu系统没有针对目标机优化编译、出现了不兼容的情况,把宿主工具链部分重新本地编译一遍,重新建立交叉编译工具链问题依旧。
2、启动移植过来的i686-pc-linux-gnu系统,chroot到一个已知可进行交叉编译的系统——debian etch i386,以此为宿主,用贴子中方法验证通过,顺便验证了一下建立交叉编译工具链的更好的方法,同时也排除了移植过来的i686-pc-linux-gnu系统内核问题。

作者: 聚焦深空   发布时间: 2008-07-16

引用:
作者: 聚焦深空
查看CLFS、还有 youbest 关于mips的帖子,应当没有这样的问题的。是不是什么地方出错了?
首先CLFS并没有SYSROOT版本的MIPS。非SYSROOT版本的CLFS是不需要Glibc头文件的,直接在static GCC上就可以编译Glibc。
其次youbest做的是64位龙芯。
而我build的是32位的MIPS,所以Glibc会使用一个-mabi32的参数调用宿主GCC。这个参数在x86机器上是不支持的,x86_64版本相应的参数是-m32。这就是为什么我会遇到这个问题,而别人没有。解决的方法只能是先build出一个支持该参数的GCC。


引用:
这样看起来是简单一点,真正的编译过程并没有减少。
实际上,我觉得挺丑陋的。
我同意。这个仅供参考了。


引用:
你说的前两遍,是第一遍的两个步骤,没必要看作两遍吧。
这是两遍。因为完整的顺序是
naked GCC
Glibc-headers
static GCC
Glibc
GCC final
如果把GCC final看作单独的步骤,那么naked也应该是单独的步骤。

作者: 地球发动机   发布时间: 2008-07-17

引用:
首先CLFS并没有SYSROOT版本的MIPS。非SYSROOT版本的CLFS是不需要Glibc头文件的,直接在static GCC上就可以编译Glibc。
其次youbest做的是64位龙芯。
而我build的是32位的MIPS,所以Glibc会使用一个-mabi32的参数调用宿主GCC。这个参数在x86机器上是不支持的,x86_64版本相应的参数是-m32。这就是为什么我会遇到这个问题,而别人没有。解决的方法只能是先build出一个支持该参数的GCC。
引用:
这是两遍。因为完整的顺序是
naked GCC
Glibc-headers
static GCC
Glibc
GCC final
如果把GCC final看作单独的步骤,那么naked也应该是单独的步骤。
严重怀疑与你宿主的mulitlib有关,youbest已做过64位龙芯Sysroot方式交叉编译,等会我做一下i486-pc-linux-gnu -> mips-unknown-linux-gnu 的验证。
如果是因为mulitlib引起的,你的第一遍,我会看作是对宿主的要求,不算在工具链部分。

引用:
我同意。这个仅供参考了。
已参考,前面验证贴中使用的是:
代码:
make all-gcc 
make all-target-libgcc
make install-gcc
make install-target-libgcc

作者: 聚焦深空   发布时间: 2008-07-17

引用:
作者: 地球发动机
这是两遍。因为完整的顺序是
naked GCC
Glibc-headers
static GCC
Glibc
GCC final
如果把GCC final看作单独的步骤,那么naked也应该是单独的步骤。
有点明白你的意思了,我们x86/x86_64方法配置安装Glibc-headers时,要使用宿主gcc代替仍不存在的交叉编译工具链中的${NEW_OS_TARGET}-gcc,这个只要宿主gcc支持配置安装Glibc-headers过程中的参数即可。

i486-pc-linux-gnu -> mips-unknown-linux-gnu验证表明,需要宿主gcc支持参数“-mabi=32”,所以解决方法有三,一是给宿主编译一个支持这个参 数的编译器,二是给glibc源码打补丁暂时屏蔽对-mabi=32参数的调用,三是使用--with-newlib编译第一遍gcc,跳过glibc- header。
i486-pc-linux-gnu -> mips64-unknown-linux-gnu验证结果类似。

我会优选方法二,youbest也是使用的方法二,你可以参考一下“sed -i 's/-mabi=$mips_config_abi//g' ports/sysdeps/mips/preconfigure“

事实是仅需要编译gcc两遍,配置安装Glibc-headers过程中,欺骗一下就可以的,并不需要真正的交叉编译。

作者: 聚焦深空   发布时间: 2008-07-17

引用:
作者: 聚焦深空
有点明白你的意思了,我们x86/x86_64方法配置安装Glibc-headers时,要使用宿主gcc代替仍不存在的交叉编译工具链中的${NEW_OS_TARGET}-gcc,这个只要宿主gcc支持配置安装Glibc-headers过程中的参数即可。

i486-pc-linux-gnu -> mips-unknown-linux-gnu验证表明,需要宿主gcc支持参数“-mabi=32”,所以解决方法有三,一是给宿主编译一个支持这个参 数的编译器,二是给glibc源码打补丁暂时屏蔽对-mabi=32参数的调用,三是使用--with-newlib编译第一遍gcc,跳过glibc- header。
i486-pc-linux-gnu -> mips64-unknown-linux-gnu验证结果类似。

我会优选方法二,youbest也是使用的方法二,你可以参考一下“sed -i 's/-mabi=$mips_config_abi//g' ports/sysdeps/mips/preconfigure“

事实是仅需要编译gcc两遍,配置安装Glibc-headers过程中,欺骗一下就可以的,并不需要真正的交叉编译。
谢谢指教。方法三在GCC 4.2系列是好使的,但到了4.3就不行了。

作者: 地球发动机   发布时间: 2008-07-17

引用:
作者: 地球发动机
谢谢指教。方法三在GCC 4.2系列是好使的,但到了4.3就不行了。
没道理,如果我真的准备用newlib的c库怎么办?回头研究下。

作者: 聚焦深空   发布时间: 2008-07-17

oom kill的问题最新进展如下: 升级到binutils-2.18.50解决。

作者: 聚焦深空   发布时间: 2008-07-18

引用:
作者: 聚焦深空
没道理,如果我真的准备用newlib的c库怎么办?回头研究下。
经过最新研究,阻止GCC 4.3在没有头文件的情况下静态编译的因素有两个:
1、decimal-float的支持需要宿主头文件FENV.h。这可以通过参数--enable-decimal-float=no禁止掉。
2、现在Linux下编译的线程模型默认为posix。且即使使用--disable-threads或者--enable-threads=no 甚至--enable-threads=single都会被忽略。这一点在本机编译的情形下验证。这个需要一个补丁:
cp gcc/configure{,.orig}
sed -e s/x\$\{thread_file\}/x/ gcc/configure.orig >gcc/configure

目前还在研究这样编译的gcc是否能编译glibc。

顺便说一下,我觉得第二点绝对是一个BUG,因为configure.ac的相关内容如下
if test x${thread_file} = x; then
# No thread file set by target-specific clauses in config.gcc,
# so use file chosen by default logic above
thread_file=${target_thread_file}
fi
这里指出:仅当config.gcc文件里面没有设置线程库的时候,才会根据“以上逻辑”设置变量thread_file。但所谓“以上逻辑”正是检查用户设置的代码。因此,如果config,gcc能够检测到线程库,用户指定的设置就不再起作用。

更新:最新研究发现,GCC4.3比以前的版本更依赖于--build的设定。关于线程的设置,如果没有--build参数,则以上提到的config.gcc脚本会强行设置thread_file参数,把用户设置覆盖掉。
结论是:在GCC4.3即使要进行本机编译,最好也加上--build参数。采用这种方法,就不需要补丁。

作者: 地球发动机   发布时间: 2008-07-20

引用:
作者: 地球发动机
结论是:在GCC4.3即使要进行本机编译,最好也加上--build参数。
本地编译时,没必要添加--build,除非想移植系统到新机,并保持兼容性,这样还需要CFLAGS="-mtune=xxx -march=xxx"、CXXFLAGS=$CFLAGS配合。

作者: 聚焦深空   发布时间: 2008-07-21

引用:
作者: 聚焦深空
本地编译时,没必要添加--build,除非想移植系统到新机,并保持兼容性,这样还需要CFLAGS="-mtune=xxx -march=xxx"、CXXFLAGS=$CFLAGS配合。
我不是说了吗?4.3要是不加--build,那么--disable-thread参数可能不能生效。为了在没有头文件的情况下编译4.3,就要加--build。

作者: 地球发动机   发布时间: 2008-07-21

引用:
作者: 地球发动机
我不是说了吗?4.3要是不加--build,那么--disable-thread参数可能不能生效。为了在没有头文件的情况下编译4.3,就要加--build。
呵呵,你前面说的是本机编译,我理解为本地编译不为过吧。
我帖子中给出的建立交叉编译工具链的方法一直有加--build,目的只是保持一致和对称,顺便也省去你上面的麻烦。

其实,没必要与glibc-header较劲的,本质上,安装glibc-header是为了解决gcc glibc循环依赖问题,后面步骤安装glibc时,会把前面安装的glibc-header覆盖,第二次安装的glibc-header才是我们真正需要的。

参考 google 到的资料http://gcc.gnu.org/ml/gcc/2008-06/msg00181.html,CLFS-1.x,gcc-4.3.1源代码,还有你的帖子。
经验证,sysroot方式,不安装glibc-header的情况下,gcc第一遍配置时需添加下面参数,应当也适用于gcc-4.2.x:
代码:
 --with-newlib \
 --disable-threads \
 --disable-decimal-float \
除了上面变动,建立交叉编译工具链的其他步骤不需改变,已建立完整交叉编译工具链验证。
下次全面升级系统时,我会考虑使用这种方法,到时再合并到第一贴。

其间,曾尝试古老的libchack方案,通不过。

作者: 聚焦深空   发布时间: 2008-07-22