Skip to content
Snippets Groups Projects
vendorsetup.sh 10.80 KiB
# Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of The Linux Foundation nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#
# Environment variables influencing operation:
#    B2G_TREE_ID - Defines the tree ID, used to determine which patches to
#        apply.  If unset, |treeid.sh| is run to identify the tree
#    B2G_USE_REPO - If set, use |repo manifest| to determine when the Android
#                   tree has changed.  Disabled by default for performance
#                   reasons.
#    REPO - Path to repo executable (default: repo)

B2G_TREEID_SH=${B2G_TREEID_SH:-device/qcom/b2g_common/treeid.sh}
B2G_HASHED_FILES="${B2G_HASHED_FILES:-"device/qcom/b2g_common/vendorsetup.sh ${B2G_TREEID_SH}"}"
REPO="${REPO:-repo}"

# Look for patch trees
B2G_PATCH_DIRS=$(LANG=C sort -u <( \
  test -d device && find -L device -maxdepth 4 -type d -name patch ; \
  test -d vendor && find -L vendor -maxdepth 4 -type d -name patch \
) 2> /dev/null)

__tree_md5sum()
{
   (
      export LANG=C
      FILELIST="$(find $@ -type f ! -path "*/.*" 2>/dev/null | sort -fs) ${B2G_HASHED_FILES}"
      if [[ -n "${B2G_USE_REPO}" ]]; then
         ${REPO} manifest -r -o - 2>/dev/null
      fi
      cat ${FILELIST}
   ) | openssl dgst -md5
}


__abandon_branch()
{
  local branch=$1
  local FORCE="$2"

  if [[ -n "$(git branch --list b2g_autogen_ephemeral_branch)" ]]; then
    if [[ "$FORCE" != "force" && $(whoami) != "lnxbuild" ]]; then
      if [[ -n $(git status --porcelain) ]]; then
         echo
         echo "ERROR: Uncommitted changes found in $branch/"
         echo "       You may force overwriting these changes"
         echo "       with |source build/envsetup.sh force|"
         echo
         return 1
      fi
    fi
    git reset --hard HEAD
    git clean -dfx
    ${REPO} abandon b2g_autogen_ephemeral_branch .
  fi
}


__abandon_tree()
{
   local FORCE="$1"
   rm -f out/lastpatch.md5sum
   if [[ -d .repo ]]; then
     if [[ -f out/lastpatch.projects ]]; then
       local projects=$(cat out/lastpatch.projects)
     else
       local projects=$(repo forall -c pwd)
     fi

     for p in $projects; do
       cd $p ; __abandon_branch $p "$FORCE" ; cd $OLDPWD
     done
   fi
}


__patch_tree()
{
   (
      export GIT_COMMITTER_NAME=nobody
      export GIT_COMMITTER_EMAIL=nobody

      cd $(gettop)
      local TREE_ID=${B2G_TREE_ID:-$(${B2G_TREEID_SH})}

      if [[ $(pwd) =~ .*\-L.* ]]; then
        echo
        echo "ERROR: Build root contains '-L': $(pwd)"
        echo "       Some versions of gecko are known to fail to build when"
        echo "       this character sequence is present.  Please relocate the"
        echo "       source tree to continue."
        echo
        exit 1
      fi

      echo "Tree IDs: ${TREE_ID}"
      echo "Patch directories: "
      for d in ${B2G_PATCH_DIRS}; do
        echo "  $d"
      done

      if [[ -z "$B2G_PATCH_DIRS" ]]; then
        exit
      fi

      set -e
      local LASTMD5SUM=invalid
      local MD5SUM=unknown
      if [[ -f out/lastpatch.md5sum ]]; then
         LASTMD5SUM=$(cat out/lastpatch.md5sum)
         MD5SUM=$(__tree_md5sum ${B2G_PATCH_DIRS})
      fi
      FORCE=
      if [[ $1 == "force" ]]; then
        FORCE=force
      fi

      if [[ "$LASTMD5SUM" != "$MD5SUM" || "force" == "$FORCE" ]]; then

         branch() {
            [[ -d $1 ]] || return 1

            echo $1 >> out/lastpatch.projects
            pushd $1 > /dev/null
            echo
            echo [entering $1]
            if [[ -d .git ]]; then
               if [[ -d .git/rebase-apply ]]; then
                 git am --abort
               fi

               __abandon_branch $1 "$FORCE"
               ${REPO} start b2g_autogen_ephemeral_branch .
            else
               read -p "Project $1 is not managed by git. Modify anyway?  [y/N] "
               if [[ ${REPLY} != "y" ]]; then
                  echo "No."
                  popd > /dev/null
                  return 1
               fi
            fi
         }
         am() {
            if [[ -d .git ]]; then
               git am $1
            else
               patch -p1 < $1
            fi
         }
         cherrypick() {
            cat $1 | cut -c 1-7 | xargs -n 1 git cherry-pick
         }
         git_rm() {
            if [[ -d .git ]]; then
               git rm -q $@
            else
               rm $@
            fi
         }
         git_add() {
            if [[ -d .git ]]; then
               git add $@
            fi
         }
         commit() {
            if [[ -d .git ]]; then
               git commit --all -m "$1" -q
            fi
         }

         # Find all of the patches for TREE_ID
         # and collate them into an associative array
         # indexed by project
         declare -a PRJ_LIST
         declare -a PATCH_LIST
         for DIR in ${B2G_PATCH_DIRS} ; do
            for ID in ${TREE_ID} ; do
               local D=${DIR}/${ID}
               [[ -d $D ]] || continue
               PATCHES=$(find $D/ -type f | sort -fs)
               for P in ${PATCHES}; do
                  PRJ=$(dirname ${P#${DIR}/${ID}/})
                  PATCH_ADDED=0
                  for (( I=0 ; I<${#PRJ_LIST[@]} ; I++ )) ; do
                     if [[ ${PRJ_LIST[$I]} == ${PRJ} ]]; then
                        PATCH_ADDED=1
                        PATCH_LIST[$I]="${PATCH_LIST[$I]} $P"
                        break
                     fi
                  done
                  if [[ ${PATCH_ADDED} -eq 0 ]]; then
                     PRJ_LIST=("${PRJ_LIST[@]}" "${PRJ}")
                     PATCH_LIST=("${PATCH_LIST[@]}" "$P")
                  fi
               done
            done
         done

         # Only abandon if there are any patches that need to be applied.
         if [[ ${#PRJ_LIST[@]} -gt 0 ]] ; then
           __abandon_tree "$FORCE"
           rm -f out/lastpatch.projects
         fi

         # Run through each project and apply patches
         ROOT_DIR=${PWD}
         for (( I=0 ; I<${#PRJ_LIST[@]} ; I++ )) ; do
            local PRJ=${PRJ_LIST[$I]}
            local FAILED_PRJ=${PRJ}
            set +e
            (
               set -e
               if branch ${PRJ} ; then
                  if [[ "$FORCE" != "yes" && $(whoami) != "lnxbuild" ]]; then
                     if [[ -n $(git status --porcelain) ]]; then
                        echo
                        echo "ERROR: Uncommitted changes found in ${PRJ}/"
                        echo "       You may force overwriting these changes"
                        echo "       with |source build/envsetup.sh force|"
                        echo
                        exit 1
                     fi
                  fi
                  # Ensure the project is clean before applying patches to it
                  git reset --hard HEAD
                  git clean -dfx

                  declare -a PATCHNAME
                  for P in ${PATCH_LIST[$I]} ; do
                     # Skip patches that have already been applied by an earlier ID
                     local PATCH_APPLIED=0
                     for APPLIED in ${PATCHNAME} ; do
                        if [[ ${APPLIED} == $(basename $P) ]]; then
                           PATCH_APPLIED=1
                        fi
                     done
                     if [[ ${PATCH_APPLIED} -eq 1 ]]; then
                        continue
                     else
                        PATCHNAME="${PATCHNAME} $(basename $P)"
                     fi

                     echo "  ${P}"
                     case $P in
                     *.patch)  am ${ROOT_DIR}/$P ;;
                     *.sh)     source ${ROOT_DIR}/$P ; commit $P ;;
                     *.sha1)   cherrypick ${ROOT_DIR}/$P ;;
                     *)        echo ERROR: Unrecognized patch format ; exit 1 ;;
                     esac
                  done
                  popd > /dev/null
               fi
            )
            local ERR=$?
            if [[ ${ERR} -ne 0 ]]; then
               echo
               echo ERROR: Patching of ${FAILED_PRJ}/ failed.
               echo
               exit ${ERR}
            fi
            set -e
         done

         mkdir -p out
         echo $(__tree_md5sum ${B2G_PATCH_DIRS}) > out/lastpatch.md5sum
      fi
   )
   ERR=$?

   if [[ ${ERR} -ne 0 ]]; then
      echo ERROR: B2G PATCHES FAILED TO APPLY
      lunch() { echo ERROR: B2G PATCHES FAILED TO APPLY;  return 1; }
      choosecombo() { lunch; }
   fi
   return ${ERR}
}

# Stub out all java compilation.
export JAVA_HOME=$(gettop)/device/qcom/b2g_common/faketools/jdk
export ANDROID_JAVA_HOME=${JAVA_HOME}

flash()
{
   ( cd $(gettop)/device/qcom/b2g_common && ./flash.sh $@ )
}

rungdb()
{
   ( cd $(gettop)/device/qcom/b2g_common && ./run-gdb.sh $@ )
}


if [[ -z $1 ]]; then
   __patch_tree
else
   case $1 in
   clean) __abandon_tree force ;;
   force) __patch_tree force ;;
   np) echo "Skipping patch tree step...";;
   *) [[ -z "$PS1" ]] && __patch_tree || echo Error: Unknown command: $1
   esac
fi

# Use a local B2G SDK if possible instead of downloading it
if [[ -d prebuilts/b2g_sdk/$(uname)/.git ]]; then
   export USE_LOCAL_XULRUNNER_SDK=1
   export XULRUNNER_DIRECTORY="$(gettop)/prebuilts/b2g_sdk/$(uname)"
else
   echo =================================================================
   echo Notice: Local B2G SDK was not found, fetching it now if necessary
   echo =================================================================
   make -s -C gaia b2g_sdk
fi

# Don't build sources.xml
export DISABLE_SOURCES_XML=true
export LEGACY_USE_JAVA6=true