Chinaunix首页 | 论坛 | 博客
  • 博客访问: 993097
  • 博文数量: 200
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 2479
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-27 15:07
文章分类

全部博文(200)

文章存档

2009年(12)

2008年(190)

我的朋友

分类:

2008-07-10 18:15:37

crosstool脚本注视分析-getandpatch.sh
    这个文件定义了下载,解压缩,打补丁的脚本.已经加了中文注释在里面.

#!/bin/sh
# Download and unpack gnu toolchain source tarballs, and apply any local patches.
# Local patches are found in subdirectories of patches/ with the same name as the tarball but without .tar.gz
# Copyright 2003 Ixia Communications
# Licensed under the GPL
set -xe

abort() {
    echo $@
    exec false
}

# Meant to be invoked from another shell script.

# To disable all downloads, and use only already-downloaded tarballs,
# set NO_DOWNLOAD to a nonempty string.
# To just download tarballs and not unpack or patch,
# set JUST_DOWNLOAD to a nonempty string.

test -z "$NO_DOWNLOAD" || echo "NO_DOWNLOAD set, not downloading"
test -z "$JUST_DOWNLOAD" || echo "JUST_DOWNLOAD set, not unpacking"

# Usage: set the following environment variables:
test -z "${BINUTILS_DIR}"  && abort "Please set BINUTILS_DIR to the bare filename of the binutils tarball or directory"
test -z "${JUST_DOWNLOAD}" && test -z "${SRC_DIR}"  && abort "Please set SRC_DIR to the directory where the source tarballs are to be unpacked"
test -z "${GCC_DIR}"       && abort "Please set GCC_DIR to the bare filename of the gcc tarball or directory"
test -z "${GCC_CORE_DIR}"  && echo "GCC_CORE_DIR not set, so using $GCC_DIR for bootstrap compiler"
test -z "${GDB_DIR}"       && echo "GDB_DIR not set, so not downloading gdb sources"

# When building a cygwin target the following are not needed.
if test "${CYGWIN_DIR}" = ""; then
  test -z "${GLIBC_DIR}"        && abort "Please set GLIBC_DIR to the bare filename of the glibc tarball or directory"
  test -z "${LINUX_SANITIZED_HEADER_DIR}" && echo "Not downloading linux-libc-headers. Set LINUX_SANITIZED_HEADER_DIR to do so"
  test -z "${LINUX_DIR}"        && echo "Not downloading kernel sources. Set LINUX_DIR if you want to do so"
  # And one is derived if not set explicitly.
  test -z "${GLIBCTHREADS_FILENAME}" &&
  GLIBCTHREADS_FILENAME=`echo $GLIBC_DIR | sed 's/glibc-/glibc-linuxthreads-/'`
fi

test -z "${TARBALLS_DIR}"     && abort "Please set TARBALLS_DIR to the directory to download tarballs to."

# Make all paths absolute (it's so confusing otherwise)
# FIXME: this doesn't work well with some automounters
test -z "$JUST_DOWNLOAD" || SRC_DIR=`cd $SRC_DIR; pwd`

# Check if extractions should be verbose.
if test -z "$QUIET_EXTRACTIONS"; then VERBOSE=-v;else VERBOSE=; fi

# Pattern in a patch log to indicate failure
PATCHFAILMSGS="^No file to patch.  Skipping patch.|^Hunk .* FAILED at"

# Get a well-defined sort order so patches always in same order
LANG=C
export LANG

# Download the given file to $TARBALLS_DIR
downloadFile()
{
    echo downloadFile $1

    # Hacky little kludge.  Useful during buildsrpms.sh to avoid redownloading over and over.
    if test -n $TARBALLS_CACHE_DIR && test -f $TARBALLS_CACHE_DIR/`basename $1`; then
        cp $TARBALLS_CACHE_DIR/`basename $1` $TARBALLS_DIR
        return
    fi

    # If downloads are disabled, just fail
    test -z "$NO_DOWNLOAD" || return 1

    case $1 in

    *glibc-200*gz)
        wget --tries=5 -P ${TARBALLS_DIR} -c $1 || wget --tries=5 --passive-ftp -P ${TARBALLS_DIR} -c $1 || \
        (cd $TARBALLS_DIR; sh $TOP_DIR/glibc-get.sh $1; )
        ;;
    *)
        # Note: if you need to use a proxy, try
        # export http_proxy=:
# -P 指定了保存文件的路径,-c指定续传, --passive-ftp指定采用被动模式的ftp传输
#        
        wget --tries=5 -P ${TARBALLS_DIR} -c $1 || wget --tries=5 --passive-ftp -P ${TARBALLS_DIR} -c $1
        # FIXME: support curl on systems that don't have wget
# wget一般只支持下载,而curl支持上传和下载
        ;;
    esac
}


# Download, unpack, and patch a tarball from any one of the given URLs.
# If the directory already exists, don't download and unpack it.
# If the tarball already exists, don't download it.
# Assumes that the tarball unpacks to a name guessable from its url,
# and that patches already exist locally in a directory named after the tarball.
# 这个函数一般接受多个参数,且这些参数其实对应了一个文件的多个下载mirror,
# 因此,如果其中一个下载成功,就会跳出对于arg的循环,然后去unpack,patch。
# 如果没有下载顺利,会下载下一个.
getUnpackAndPatch() {
    set -x
    # Check to see if the tarball already exists
    exists=""
# 当for name [ in words ] 语句中没有使用in words时,默认使用的是in $@即arg默认
# 使用函数参数.   
    for arg; do

# 检查文件后缀,如不支持,abort,如支持,什么也不作.
        case $arg in
        *.gz|*.bz2|*.tgz) ;;
        *) abort "unknown suffix on url $arg" ;;
        esac
# 因为sed中,可以使用其他字符代替'/'作为分割符,因此sed 's,.*/,,;' 可以被理解
# 为sed 's/.*\///;',注意,之所以sed 's,.*/,,;' 中的/不用backslash将其转义是因为
# 我们使用,作为分割符的,/已经不在作为分割符使用,因此他没有了特殊含义,因此只是
# 个普通字符,因此直接拿来用就可以了,这条命令的意思是将字串中目录部分替换成空.
# 从而的到了archive_name
        ARCHIVE_NAME=`echo $arg | sed 's,.*/,,;'`
# basename是将文件名中的后缀去掉后的名字.       
        BASENAME=`echo $ARCHIVE_NAME | sed 's,\.tar\.gz$,,;s,\.tar\.bz2$,,;s,\.tgz,,;'`

        # Done if already unpacked
# 尽管    echo "directory $BASENAME already present"; return 0 放在了一个{}里面,
# 即指令执行的时候是在一个subshell里面,但是其echo输出还是会输出到当前的console
# 并且return 0还是回导致本函数的返回,即本函数接下来的指令不会被执行了.       

        test -z "${JUST_DOWNLOAD}" && test -d ${SRC_DIR}/$BASENAME && { echo "directory $BASENAME already present"; return 0 ; }
# 如果我们已经通过别的途径下载了需要的archive文件,那么exists就不会为空.
# 就没有必要调用downloadFile了.
        if test -f $TARBALLS_DIR/$ARCHIVE_NAME; then
            exists=$TARBALLS_DIR/$ARCHIVE_NAME
        break
        fi
    done

# 去下载没有的文件
    if test "x$exists" = "x"; then
        # Doesn't exist, so try urls until we fetch one
# 循环下载每个文件,知道我们成功下载了一个文件.       
        for arg; do
            ARCHIVE_NAME=`echo $arg | sed 's,.*/,,;'`
            BASENAME=`echo $ARCHIVE_NAME | sed 's,\.tar\.gz$,,;s,\.tar\.bz2$,,;s,\.tgz,,;'`
            if downloadFile $arg && test -f ${TARBALLS_DIR}/$ARCHIVE_NAME ; then
                # we got it!
                break
            fi
        done
    fi
# 如果至少成功下载了一个文件的话,我们就继续,如果没有 ,就abort。
    test -f ${TARBALLS_DIR}/$ARCHIVE_NAME || abort "file $ARCHIVE_NAME not found"
# 如果只是just downloading,即不再解压,那么JUST_DOWNLOAD就不为空
    # If we're just downloading, don't unpack
    test -n "$JUST_DOWNLOAD" && return 0
# 进入SRC_DIR,在这个目录下面调用解压缩命令,那么被解压后生成的文件
# 会放置在SRC_DIR目录下.
    cd $SRC_DIR

    echo hmm maybe cd
    case $ARCHIVE_NAME in
    glibc-[a-z]*-2*) echo "It's a glibc addon, so cd into glibc"; cd $GLIBC_DIR ;;
    *) ;;
    esac
# set +x 取消了x的作用,即不再显示命令的扩展结果       
    set +x
# 依据格式进行解压缩操作
    case $ARCHIVE_NAME in
    *.gz|*.tgz)
        tar $VERBOSE -xzf $TARBALLS_DIR/$ARCHIVE_NAME || abort cannot unpack $TARBALLS_DIR/$ARCHIVE_NAME ;;
    *.bz2)
        tar $VERBOSE -xjf $TARBALLS_DIR/$ARCHIVE_NAME || abort cannot unpack $TARBALLS_DIR/$ARCHIVE_NAME ;;
    *)
        abort "Unrecognized suffix for tarball $ARCHIVE_NAME" ;;
    esac

    # Fix path of old linux source trees
# 如果我们解出来的东西是linux,那么会生成linux或者kernel目录,我们将这个目录
# 移动到BASENAME里面去.
# 等价于 if test -d linux 其中,linux可以用""括起来.       
    if [ -d linux ]; then
        mv linux $BASENAME
    fi
    # A few special distributions name the tree just kernel.
    if [ -d kernel ]; then
        mv kernel $BASENAME
    fi

    # Apply any patches for this component
    # -f is required for patches that delete files, like
    # patches/glibc-2.2.5/hhl-powerpc-fpu.patch,
    # else patch will think the patch is reversed :-(
    # Since -f tells patch to ignore failures, grep log to look for errors
    # use max --fuzz=1 since default fuzz is too dangerous for automation
    # Use -g0 else patch-2.5.8 on MacOSX tries to run perforce!
# perforce是一个类似于SVN的版本控制系统           
    if test -d $TOP_DIR/patches/$BASENAME; then
        case $ARCHIVE_NAME in
        glibc-[a-z]*-2*) ;;              # glibc addon, so we're already in right directory
        *)           cd $BASENAME ;;
        esac

        for p in $TOP_DIR/patches/$BASENAME/*patch* \
             $TOP_DIR/patches/$BASENAME/*.diff; do
        if test -f $p; then
            echo "applying patch $p"
# patch -g0, -g0告诉patch,就算文件不存在也不要去访问source control system,
# 当-gNum中的num<0时,会ask用户是否要访问source control来获取文件.
# --fuzz=1告诉patch,在使用由diff生成的patch的时候,在比较context时,可以忽略
# 的不匹配的context的行数,这个数值越大,越容易出错.
# 2>&1 表示将错误输出重定向到标准输出.
            patch -g0 --fuzz=1 -p1 -f < $p > patch$$.log 2>&1 || { cat patch$$.log ; abort "patch $p failed" ; }
            cat patch$$.log
# $PATCHFAILMSGS 是一个使用egrep时候的pattern.    -q 代表quietly       
            egrep -q "$PATCHFAILMSGS" patch$$.log && abort "patch $p failed"
            rm -f patch$$.log
        fi
        done
    fi
}

# Remember where source is.
# 这个命令的使用类似于${TOP_DIR:-`pwd`},其作用是:
# 当TOP_DIR是空时,取pwd的值,否则,取TOP_DIR的值
TOP_DIR=${TOP_DIR-`pwd`}

mkdir -p $TARBALLS_DIR
test -z "${JUST_DOWNLOAD}" || mkdir -p $SRC_DIR

# Download, unpack, and patch all the needed source tarballs,

# Grab it if we want to build userland...
if test -n "$PTXDIST_DIR" ; then
   getUnpackAndPatch
fi

if test -n "$GDB_DIR"; then
# 提供的这几个参数其实都对应了一个文件,但是有可能有的下不动阿,所以提供了多个选择.
    getUnpackAndPatch ftp://ftp.gnu.org/pub/gnu/gdb/$GDB_DIR.tar.bz2 \
                      ftp://sources.redhat.com/pub/gdb/releases/$GDB_DIR.tar.bz2 \
                      ftp://sources.redhat.com/pub/gdb/old-releases/$GDB_DIR.tar.bz2 \
                      ftp://sources.redhat.com/pub/gdb/snapshots/current/$GDB_DIR.tar.bz2
fi

# No glibc for cygwin.
if test "${CYGWIN_DIR}" = ""; then
   case $GLIBC_DIR in
      glibc-200*)
        getUnpackAndPatch \
        ftp://gcc.gnu.org/pub/glibc/snapshots/$GLIBC_DIR.tar.bz2 \
        ftp://gcc.gnu.org/pub/glibc/snapshots/$GLIBC_DIR.tar.gz ;;
      *) 
        getUnpackAndPatch \
        ftp://ftp.gnu.org/pub/gnu/glibc/$GLIBC_DIR.tar.bz2 \
        ftp://ftp.gnu.org/pub/gnu/glibc/$GLIBC_DIR.tar.gz \
        ftp://gcc.gnu.org/pub/glibc/releases/$GLIBC_DIR.tar.bz2 \
        ftp://gcc.gnu.org/pub/glibc/releases/$GLIBC_DIR.tar.gz ;;
   esac
else
  getUnpackAndPatch ${CYGWIN_URL}/${CYGWIN_DIR}-src.tar.bz2
fi
if test x"$BINUTILS_URL" = x; then
   case $BINUTILS_DIR in
      binutils-2.*.9*.0*)
          BINUTILS_URL=http://www.kernel.org/pub/linux/devel/binutils ;;   # H.J.Lu's branch
      binutils-2.*.9*|binutils-05*)   
          BINUTILS_URL=ftp://gcc.gnu.org/pub/binutils/snapshots ;;
      *)  BINUTILS_URL=ftp://gcc.gnu.org/pub/binutils/releases ;;
   esac
fi
getUnpackAndPatch $BINUTILS_URL/$BINUTILS_DIR.tar.bz2 $BINUTILS_URL/$BINUTILS_DIR.tar.gz

for gcc in $GCC_DIR $GCC_CORE_DIR; do
 case $gcc in
   gcc-2.95.3)
      getUnpackAndPatch ftp://ftp.gnu.org/pub/gnu/gcc/$gcc.tar.gz ;;
   #gcc-3.3.3)
   #   getUnpackAndPatch ftp://ftp.gnu.org/pub/gnu/gcc/releases/$gcc/$gcc.tar.bz2 ;;
   gcc-3.3.5)
      getUnpackAndPatch ftp://gcc.gnu.org/pub/gcc/releases/$gcc/$gcc.tar.bz2 ;;
   gcc-4.[01234].[012345]-200*)
      dir=`echo $gcc | sed s/gcc-/prerelease-/`
      getUnpackAndPatch    ftp://gcc.gnu.org/pub/gcc/$dir/$gcc.tar.bz2 \
            ftp://gcc.gnu.org/pub/gcc/$dir/$gcc.tar.gz ;;
   gcc-4.[01234]-200*)
      snapshotdir=`echo $gcc | sed s/gcc-//`
      getUnpackAndPatch    ftp://gcc.gnu.org/pub/gcc/$dir/$gcc.tar.bz2 \
            ftp://gcc.gnu.org/pub/gcc/$dir/$gcc.tar.gz \
            ftp://gcc.gnu.org/pub/gcc/snapshots/$snapshotdir/$gcc.tar.bz2 ;;
   gcc-3.[3456]-200*|gcc-4.0-200*|gcc-4.1-200*)
      dir=`echo $gcc | sed 's/gcc-//'`
      getUnpackAndPatch ftp://gcc.gnu.org/pub/gcc/snapshots/$dir/$gcc.tar.bz2 \
            ftp://gcc.gnu.org/pub/gcc/snapshots/$dir/$gcc.tar.gz ;;
   *)
      getUnpackAndPatch ftp://ftp.gnu.org/pub/gnu/gcc/$gcc/$gcc.tar.bz2 \
            ftp://ftp.gnu.org/pub/gnu/gcc/$gcc/$gcc.tar.gz \
                        ftp://gcc.gnu.org/pub/gcc/releases/$gcc/$gcc.tar.bz2 \
            ftp://gcc.gnu.org/pub/gcc/releases/$gcc/$gcc.tar.gz ;;
 esac
done

# Linux and glibc addons not needed if building a cygwin target.
if test "${CYGWIN_DIR}" = ""; then
  case $LINUX_DIR in
    *2.4*) getUnpackAndPatch ;;
    *2.6*) getUnpackAndPatch ;;
    "") ;;
    *) abort "unknown version $LINUX_DIR of linux, expected 2.4 or 2.6 in name?" ;;
  esac
  # Fetch linux-libc-headers, if requested
  test -n "${LINUX_SANITIZED_HEADER_DIR}" && getUnpackAndPatch \
    ~mmazur/linux-libc-headers/${LINUX_SANITIZED_HEADER_DIR}.tar.bz2 \
    ftp://ftp.lfs-matrix.net/pub/linux-libc-headers/${LINUX_SANITIZED_HEADER_DIR}.tar.bz2
  # Glibc addons must come after glibc
  getUnpackAndPatch     \
       ftp://ftp.gnu.org/pub/gnu/glibc/$GLIBCTHREADS_FILENAME.tar.bz2 \
       ftp://ftp.gnu.org/pub/gnu/glibc/$GLIBCTHREADS_FILENAME.tar.gz \
       ftp://gcc.gnu.org/pub/glibc/releases/$GLIBCTHREADS_FILENAME.tar.bz2 \
       ftp://gcc.gnu.org/pub/glibc/releases/$GLIBCTHREADS_FILENAME.tar.gz

  test x$GLIBCCRYPT_FILENAME = x || getUnpackAndPatch     ftp://ftp.gnu.org/pub/gnu/glibc/$GLIBCCRYPT_FILENAME.tar.gz ftp://ftp.gnu.org/pub/gnu/glibc/$GLIBCCRYPT_FILENAME.tar.bz2
fi

if test -z "$JUST_DOWNLOAD"; then
  # gcc's contrib/test_summary expects version stamp, normally created by contrib/update_gcc
  test -f $SRC_DIR/$GCC_DIR/LAST_UPDATED || echo $GCC_DIR > $SRC_DIR/$GCC_DIR/LAST_UPDATED

  # binutils-2.14.90.0.3 and up want you to apply a patch
  if grep -q "/bin/sh patches/README" $SRC_DIR/$BINUTILS_DIR/patches/README; then
    if test '!' -f $SRC_DIR/$BINUTILS_DIR/patches/README.done; then
      cd $SRC_DIR/$BINUTILS_DIR
      /bin/sh patches/README
      touch patches/README.done
    fi
  fi
fi

阅读(2030) | 评论(0) | 转发(0) |
0

上一篇:find, xargs的使用

下一篇:关于NPTL和TLS库

给主人留下些什么吧!~~