scripts/patch-rework.sh
author Remy Bohmer <linux@bohmer.net>
Thu May 27 23:18:19 2010 +0200 (2010-05-27)
changeset 2060 51e4597b07fc
child 2147 0ec4491d6496
permissions -rwxr-xr-x
scripts: add option to strip all toolchain executables

To reduce filesizes of the toolchain and even improve build times
of projects to be build with this toolchain it is usefull to strip
the delivered toolchain executables. Since it is not likely that we
will debug the toolchain executables itself we do not need the
debug information inside the executables itself.

Signed-off-by: Remy Bohmer <linux@bohmer.net>
yann@1624
     1
#!/bin/sh
yann@1624
     2
yann@1624
     3
# Get our required options
yann@1624
     4
base="$1"
yann@1624
     5
src="$2"
yann@1624
     6
dst="$3"
yann@1624
     7
shift 3
yann@1624
     8
yann@1624
     9
# The remainder is for diff
yann@1624
    10
diff="$@"
yann@1624
    11
yann@1624
    12
# This function checks that the files listed in the file in "$1"
yann@1624
    13
# do exist, at the given depth-stripping level (aka diff -p#)
yann@1624
    14
do_check_files_at_depth() {
yann@1624
    15
  local flist="$1"
yann@1624
    16
  local depth="$2"
yann@1624
    17
  local ok=0  # 0: OK,  !0: KO
yann@1624
    18
yann@1624
    19
  exec 6<&0
yann@1624
    20
  exec 7<"${flist}"
yann@1624
    21
yann@1624
    22
  while read -u7 f; do
yann@1624
    23
    f="$( echo "${f}" |sed -r -e "s:^([^/]+/){${depth}}::;" )"
yann@1624
    24
    [ -f "${f}" ] || ok=1
yann@1624
    25
  done
yann@1624
    26
yann@1624
    27
  exec 7<&-
yann@1624
    28
  exec <&6
yann@1624
    29
yann@1624
    30
  return ${ok}
yann@1624
    31
}
yann@1624
    32
yann@1624
    33
mkdir -p "${dst}"
yann@1624
    34
dst="$( cd "${dst}"; pwd )"
yann@1624
    35
yann@1624
    36
# Iterate through patches
yann@1624
    37
for p in "${src}/"*.patch; do
yann@1624
    38
  pname="$( basename "${p}" )"
yann@1624
    39
yann@1624
    40
  printf "Handling patch '${pname}'...\n"
yann@1624
    41
yann@1624
    42
  printf "  creating reference..."
yann@1624
    43
  cp -a "${base}" "${base}.orig"
yann@1624
    44
  printf " done\n"
yann@1624
    45
yann@1624
    46
  printf "  retrieving patch comment..."
yann@1624
    47
  comment="$( awk '
yann@1624
    48
BEGIN { mark=0; }
yann@1624
    49
$0~/^diff --/ { nextfile; }
yann@1624
    50
$1=="---" { mark=1; next; }
yann@1624
    51
$1=="+++" && mark==1 { nextfile; }
yann@1624
    52
{ mark=0; print; }
yann@1624
    53
' "${p}" )"
yann@1624
    54
  printf " done\n"
yann@1624
    55
yann@1624
    56
  printf "  creating patched file list..."
yann@1624
    57
  diffstat -f 4 -r 2 -u -p 0 "${p}"                         \
yann@1624
    58
  |head -n -1                                               \
yann@1624
    59
  |awk '{ for(i=NF;i>=NF-5;i--) { $(i) = ""; } print; }'    \
yann@1624
    60
  |sort                                                     \
yann@1624
    61
  >"diffstat.orig"
yann@1624
    62
  printf " done\n"
yann@1624
    63
yann@1624
    64
  pushd "${base}" >/dev/null 2>&1
yann@1624
    65
yann@1624
    66
  # Check all files exist, up to depth 3
yann@1624
    67
  printf "  checking depth:"
yann@1624
    68
  for((d=0;d<4;d++)); do
yann@1624
    69
    printf " ${d}"
yann@1624
    70
    if do_check_files_at_depth "../diffstat.orig" ${d}; then
yann@1624
    71
      printf " ok, using depth '${d}'\n"
yann@1624
    72
      break
yann@1624
    73
    fi
yann@1624
    74
  done
yann@1624
    75
  if [ ${d} -ge 4 ]; then
yann@1624
    76
    printf "\n"
yann@1624
    77
    printf "  checking depth failed\n"
yann@1624
    78
    read -p "  --> enter patch depth (or Ctrl-C to abort): " d
yann@1624
    79
  fi
yann@1624
    80
yann@1624
    81
  # Store the original list of fiels touched by the patch,
yann@1624
    82
  # removing the $d leading components
yann@1624
    83
  sed -r -e "s:^([^/]+/){${d}}::;" "../diffstat.orig" >"${dst}/${pname}.diffstat.orig"
yann@1624
    84
yann@1624
    85
  # Apply the patch proper, and check it applied cleanly.
yann@1624
    86
  # We can't check with --dry-run because of patches that
yann@1624
    87
  # contain multiple accumulated patches onto a single file.
yann@1624
    88
  printf "  applying patch..."
yann@1624
    89
  if ! patch -g0 -F1 -f -p${d} <"${p}" >"../patch.out" 2>&1; then
yann@1624
    90
    printf " ERROR\n"
yann@1624
    91
    # Revert the patch
yann@1624
    92
    popd >/dev/null 2>&1
yann@1624
    93
    printf "  restoring '${base}'..."
yann@1624
    94
    rm -f "diffstat.tmp"
yann@1624
    95
    rm -rf "${base}"
yann@1624
    96
    mv "${base}.orig" "${base}"
yann@1624
    97
    printf " done\n\n"
yann@1624
    98
    printf "There was an error while applying:\n  -->  ${p}  <--\n"
yann@1624
    99
    printf "'${base}' was restored to the state it was prior to applying this faulty patch.\n"
yann@1624
   100
    printf "Here's the 'patch' command, and its output:\n"
yann@1624
   101
    printf "  ----8<----\n"
yann@1624
   102
    printf "  patch -g0 -F1 -f -p${d} <'${p}'\n"
yann@1624
   103
    cat "patch.out" |(IFS=$(printf "\n"); while read line; do printf "  ${line}\n"; done)
yann@1624
   104
    rm -f "patch.out"
yann@1624
   105
    printf "  ----8<----\n"
yann@1624
   106
    exit 1
yann@1624
   107
  fi
yann@1624
   108
  printf " done\n"
yann@1624
   109
yann@1624
   110
  printf "  removing '.orig' files..."
yann@1624
   111
  find . -type f -name '*.orig' -exec rm -f {} +
yann@1624
   112
  printf " done\n"
yann@1624
   113
yann@1624
   114
  popd >/dev/null 2>&1
yann@1624
   115
yann@1624
   116
  printf "  re-diffing the patch..."
yann@1624
   117
  printf "%s\n\n" "${comment}" >"${dst}/${pname}"
yann@1624
   118
  diff -durN "${base}.orig" "${base}" >>"${dst}/${pname}"
yann@1624
   119
  printf " done\n"
yann@1624
   120
yann@1624
   121
  if [ -n "${diff}" ]; then
yann@1624
   122
    printf "  applying diff filter..."
yann@1624
   123
    filterdiff -x "${diff}" "${dst}/${pname}" >"tmp-diff"
yann@1624
   124
    mv "tmp-diff" "${dst}/${pname}"
yann@1624
   125
    printf " done\n"
yann@1624
   126
  fi
yann@1624
   127
yann@1624
   128
  printf "  creating new patched file list..."
yann@1624
   129
  diffstat -f 4 -r 2 -u -p 1 "${dst}/${pname}"              \
yann@1624
   130
  |head -n -1                                               \
yann@1624
   131
  |awk '{ for(i=NF;i>=NF-5;i--) { $(i) = ""; } print; }'    \
yann@1624
   132
  |sort                                                     \
yann@1624
   133
  >"${dst}/${pname}.diffstat.new"
yann@1624
   134
  printf " done\n"
yann@1624
   135
yann@1624
   136
  printf "  removing temporary files/dirs..."
yann@1624
   137
  rm -f "patch.out"
yann@1624
   138
  rm -f "diffstat.tmp"
yann@1624
   139
  rm -rf "${base}.orig"
yann@1624
   140
  printf " done\n"
yann@1624
   141
done
yann@1624
   142
yann@1624
   143
# Scan all new patches to see if they touch
yann@1624
   144
# more files than the original patches
yann@1624
   145
printf "\nChecking resulting patchset:\n"
yann@1624
   146
for p in "${dst}/"*.patch; do
yann@1624
   147
  pname="$( basename "${p}" )"
yann@1624
   148
yann@1624
   149
  if ! cmp "${p}.diffstat.orig" "${p}.diffstat.new" >/dev/null; then
yann@1624
   150
    printf "  --> '${pname}' differ in touched files <--\n"
yann@1624
   151
  fi
yann@1624
   152
done
yann@1624
   153
printf "  done.\n"