Bash程序  |  214行  |  4.67 KB

#!/bin/sh
#
# A small script used to update the content of libcxx/ to a newer
# version of libc++.
#

PROGDIR=$(dirname "$0")
PROGNAME=$(basename "$0")

# Assume this script is under tools/
NDK_LIBCXX_DIR=$(cd "$PROGDIR"/.. && pwd)

# Sanitize environment.
set -e
export LANG=C
export LC_ALL=C

# Helper functions
VERBOSE=1

run () {
  if [ "$VERBOSE" -gt 1 ]; then
    echo "COMMAND: $@"
  fi
  case $VERBOSE in
    0|1)
        "$@" >/dev/null 2>&1
        ;;
    2)
        "$@" >/dev/null
        ;;
    *)
        "$@"
        ;;
  esac
}

log () {
  if [ "$VERBOSE" -gt 1 ]; then
    printf "%s\n" "$@"
  fi
}

get_config_field () {
  cat "$NDK_LIBCXX_DIR"/upstream.config | awk '$1 == "'$1':" { print $2; }'
}

# Process command line.

DO_HELP=
NO_CLEANUP=

for opt; do
  case $opt in
    --verbose)
      VERBOSE=$(( $VERBOSE + 1 ))
      ;;
    --help)
      DO_HELP=true
      ;;
    --no-cleanup)
      NO_CLEANUP=true
      ;;
    -*)
      echo "ERROR: Unknown option '$opt'. See --help."
      exit 1
      ;;
  esac
done

if [ "$DO_HELP" ]; then
    echo "Usage: $PROGNAME [options]"
    echo ""
    echo "This script is used to update the LLVM libc++ sources to a"
    echo "more recent version."
    echo ""
    echo "Valid options:"
    echo "   --help        Print this message."
    echo "   --verbose     Increase verbosity."
    echo "   --no-cleanup  Don't remove build directory on exit."
    echo ""
    exit 0
fi

# Create build directory.
BUILD_DIR=/tmp/ndk-$USER/llvm-libc++/build
mkdir -p "$BUILD_DIR" && rm -rf "$BUILD_DIR"/*

# Ensure it is cleared when this script exits.
run_on_exit () {
  if [ -z "$NO_CLEANUP" ]; then
    # Remove temporary build directory.
    rm -rf "$BUILD_DIR"
  fi
}
trap "run_on_exit \$?" EXIT QUIT HUP TERM INT

# Get upstream SVN and revision number.
SVN_URL=$(get_config_field svn)
if [ -z "$SVN_URL" ]; then
  echo "ERROR: Can't find SVN upstream in upstream.config!"
  exit 1
fi

REVISION=$(get_config_field revision)
if [ -z "$REVISION" ]; then
  echo "ERROR: Can't find upstream revision in upstream.config!"
  exit 1
fi

run cd $BUILD_DIR &&
echo "Checking out $SVN_URL@$REVISION"
run svn co $SVN_URL@$REVISION libcxx > /dev/null
run cd libcxx

echo "Creating git repository and 'master' branch."
run git init
echo \
".gitignore
.svn/
" > .gitignore

run git add .
run git add -f .gitignore
run git commit -m "upstream @$REVISION"

echo "Create 'ndk' branch and apply patches.android/*"
run git branch ndk master
run git checkout ndk
if [ -d "$NDK_LIBCXX_DIR/patches.android" ]; then
  (
    set +e;
    run git am "$NDK_LIBCXX_DIR"/patches.android/*
    if [ "$?" != 0 ]; then
      echo "A problem occured while applying the patches!!"
      exit 1
    fi
  )
fi

echo "Updating to newer upstream revision"
run git checkout master
run git tag revision-$REVISION HEAD

run svn update
NEW_REVISION=$(svn info | awk '$1 == "Revision:" { print $2; }')
echo "Found new revision: $NEW_REVISION (was $REVISION)"

ADDED_FILES=$(git ls-files -o --exclude-standard)
MODIFIED_FILES=$(git ls-files -m)
REMOVED_FILES=$(git ls-files -d)
log "ADDED_FILES='$ADDED_FILES'"
log "MODIFIED_FILES='$MODIFIED_FILES'"
log "REMOVED_FILES='$REMOVED_FILES'"
CHANGED=
if [ -n "$ADDED_FILES" ]; then
  run git add $ADDED_FILES
  CHANGED=true
fi
if [ -n "$MODIFIED_FILES" ]; then
  run git add $MODIFIED_FILES
  CHANGED=true
fi
if [ -n "$REMOVED_FILES" ]; then
  run git rm -f $REMOVED_FILES
  CHANGED=true
fi

if [ -z "$CHANGED" ]; then
  echo "No changes detected. Exiting."
  exit 0
fi

ADDED_COUNT=$(echo "$ADDED_FILES" | wc -l)
MODIFIED_COUNT=$(echo "$MODIFIED_FILES" | wc -l)
REMOVED_COUNT=$(echo "$REMOVED_FILES" | wc -l)
echo "Commiting changes ($ADDED_COUNT new, $MODIFIED_COUNT changed, $REMOVED_COUNT deleted)"
run git commit -m "upstream @$NEW_REVISION"
run git tag revision-$NEW_REVISION

echo "Updating NDK branch."
run git checkout ndk
run git tag android-0 HEAD
run git rebase revision-$NEW_REVISION

echo "Re-creating new Android patches."
run git format-patch -k -o "$BUILD_DIR"/patches.android revision-$NEW_REVISION
run git format-patch -k -o "$BUILD_DIR"/patches.libcxx android-0

echo "Updating local sources"
run cd "$NDK_LIBCXX_DIR"/libcxx
for PATCH in "$BUILD_DIR"/patches.libcxx/*.patch; do
  (
    set +e
    run patch -p1 < "$PATCH"
    if [ $? != 0 ]; then
      echo "ERROR: Can't apply $PATCH properly!"
      exit 1
    fi
  )
done

echo "Updating local patches"
run cd "$NDK_LIBCXX_DIR"
run git rm -f patches.android/*
run cp "$BUILD_DIR"/patches.android/* patches.android/
run git add patches.android/*

echo "Updating upstream.config"
sed -i -e "s|revision: $REVISION|revision: $NEW_REVISION|" "$NDK_LIBCXX_DIR"/upstream.config
git add "$NDK_LIBCXX_DIR"/upstream.config

echo "Done updating to $NEW_REVISION."