blob: 056aa0a04c160ba3b45d58f68bec9c44daf4afa7 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/bin/bash
2
3# Used to compare sstate checksums between MACHINES.
4# Execute script and compare generated list.M files.
5# Using bash to have PIPESTATUS variable.
6
7# It's also usefull to keep older sstate checksums
8# to be able to find out why something is rebuilding
9# after updating metadata
10
11# $ diff \
12# sstate-diff/1349348392/fake-cortexa8/list.M \
13# sstate-diff/1349348392/fake-cortexa9/list.M \
14# | wc -l
15# 538
16
17# Then to compare sigdata use something like:
18# $ ls sstate-diff/1349348392/*/armv7a-vfp-neon*/linux-libc-headers/*do_configure*sigdata*
19# sstate-diff/1349348392/fake-cortexa8/armv7a-vfp-neon-oe-linux-gnueabi/linux-libc-headers/3.4.3-r0.do_configure.sigdata.cb73b3630a7b8191e72fc469c5137025
20# sstate-diff/1349348392/fake-cortexa9/armv7a-vfp-neon-oe-linux-gnueabi/linux-libc-headers/3.4.3-r0.do_configure.sigdata.f37ada177bf99ce8af85914df22b5a0b
21# $ bitbake-diffsigs stamps.1349348392/*/armv7a-vfp-neon*/linux-libc-headers/*do_configure*sigdata*
22# basehash changed from 8d0bd67bb1da6f68717760fc3ef43171 to e869fa61426e88e9c30726ba88a1216a
23# Variable TUNE_CCARGS value changed from -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon -mtune=cortex-a8 to -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon -mtune=cortex-a9
24
25# Global vars
26tmpdir=
27machines=
28targets=
29default_machines="qemuarm qemux86 qemux86-64"
30default_targets="core-image-base"
31analyze="N"
32
33usage () {
34 cat << EOF
35Welcome to utility to compare sstate checksums between different MACHINEs.
36$0 <OPTION>
37
38Options:
39 -h, --help
40 Display this help and exit.
41
42 --tmpdir=<tmpdir>
43 Specify tmpdir, will use the environment variable TMPDIR if it is not specified.
44 Something like /OE/oe-core/tmp-eglibc (no / at the end).
45
46 --machines=<machines>
47 List of MACHINEs separated by space, will use the environment variable MACHINES if it is not specified.
48 Default value is "qemuarm qemux86 qemux86-64".
49
50 --targets=<targets>
51 List of targets separated by space, will use the environment variable TARGETS if it is not specified.
52 Default value is "core-image-base".
53
54 --analyze
55 Show the differences between MACHINEs. It assumes:
56 * First 2 MACHINEs in --machines parameter have the same TUNE_PKGARCH
57 * Third optional MACHINE has different TUNE_PKGARCH - only native and allarch recipes are compared).
58 * Next MACHINEs are ignored
59EOF
60}
61
62# Print error information and exit.
63echo_error () {
64 echo "ERROR: $1" >&2
65 exit 1
66}
67
68while [ -n "$1" ]; do
69 case $1 in
70 --tmpdir=*)
71 tmpdir=`echo $1 | sed -e 's#^--tmpdir=##' | xargs readlink -e`
72 [ -d "$tmpdir" ] || echo_error "Invalid argument to --tmpdir"
73 shift
74 ;;
75 --machines=*)
76 machines=`echo $1 | sed -e 's#^--machines="*\([^"]*\)"*#\1#'`
77 shift
78 ;;
79 --targets=*)
80 targets=`echo $1 | sed -e 's#^--targets="*\([^"]*\)"*#\1#'`
81 shift
82 ;;
83 --analyze)
84 analyze="Y"
85 shift
86 ;;
87 --help|-h)
88 usage
89 exit 0
90 ;;
91 *)
92 echo "Invalid arguments $*"
93 echo_error "Try '$0 -h' for more information."
94 ;;
95 esac
96done
97
98# tmpdir directory, use environment variable TMPDIR
99# if it was not specified, otherwise, error.
100[ -n "$tmpdir" ] || tmpdir=$TMPDIR
101[ -n "$tmpdir" ] || echo_error "No tmpdir found!"
102[ -d "$tmpdir" ] || echo_error "Invalid tmpdir \"$tmpdir\""
103[ -n "$machines" ] || machines=$MACHINES
104[ -n "$machines" ] || machines=$default_machines
105[ -n "$targets" ] || targets=$TARGETS
106[ -n "$targets" ] || targets=$default_targets
107
108OUTPUT=${tmpdir}/sstate-diff/`date "+%s"`
109declare -i RESULT=0
110
111for M in ${machines}; do
112 [ -d ${tmpdir}/stamps/ ] && find ${tmpdir}/stamps/ -name \*sigdata\* | xargs rm -f
113 mkdir -p ${OUTPUT}/${M}
114 export MACHINE=${M}
115 bitbake -S none ${targets} 2>&1 | tee -a ${OUTPUT}/${M}/log;
116 RESULT+=${PIPESTATUS[0]}
117 if ls ${tmpdir}/stamps/* >/dev/null 2>/dev/null ; then
118 cp -ra ${tmpdir}/stamps/* ${OUTPUT}/${M}
119 find ${OUTPUT}/${M} -name \*sigdata\* | sed "s#${OUTPUT}/${M}/##g" | sort > ${OUTPUT}/${M}/list
120 M_UNDERSCORE=`echo ${M} | sed 's/-/_/g'`
121 sed "s/${M_UNDERSCORE}/MACHINE/g; s/${M}/MACHINE/g" ${OUTPUT}/${M}/list | sort > ${OUTPUT}/${M}/list.M
122 find ${tmpdir}/stamps/ -name \*sigdata\* | xargs rm -f
123 else
124 printf "ERROR: no sigdata files were generated for MACHINE $M in ${tmpdir}/stamps\n";
125 fi
126done
127
128function compareSignatures() {
129 MACHINE1=$1
130 MACHINE2=$2
131 PATTERN="$3"
132 PRE_PATTERN=""
133 [ -n "${PATTERN}" ] || PRE_PATTERN="-v"
134 [ -n "${PATTERN}" ] || PATTERN="MACHINE"
135 for TASK in do_configure.sigdata do_populate_sysroot.sigdata do_package_write_ipk.sigdata; do
136 printf "\n\n === Comparing signatures for task ${TASK} between ${MACHINE1} and ${MACHINE2} ===\n" | tee -a ${OUTPUT}/signatures.${MACHINE2}.${TASK}.log
137 diff ${OUTPUT}/${MACHINE1}/list.M ${OUTPUT}/${MACHINE2}/list.M | grep ${PRE_PATTERN} "${PATTERN}" | grep ${TASK} > ${OUTPUT}/signatures.${MACHINE2}.${TASK}
138 for i in `cat ${OUTPUT}/signatures.${MACHINE2}.${TASK} | sed 's#[^/]*/\([^/]*\)/.*#\1#g' | sort -u | xargs`; do
139 [ -e ${OUTPUT}/${MACHINE1}/*/$i/*${TASK}* ] || echo "INFO: ${i} task ${TASK} doesn't exist in ${MACHINE1}" >&2
140 [ -e ${OUTPUT}/${MACHINE1}/*/$i/*${TASK}* ] || continue
141 [ -e ${OUTPUT}/${MACHINE2}/*/$i/*${TASK}* ] || echo "INFO: ${i} task ${TASK} doesn't exist in ${MACHINE2}" >&2
142 [ -e ${OUTPUT}/${MACHINE2}/*/$i/*${TASK}* ] || continue
143 printf "ERROR: $i different signature for task ${TASK} between ${MACHINE1} and ${MACHINE2}\n";
144 bitbake-diffsigs ${OUTPUT}/${MACHINE1}/*/$i/*${TASK}* ${OUTPUT}/${MACHINE2}/*/$i/*${TASK}*;
145 echo "$i" >> ${OUTPUT}/failed-recipes.log
146 echo
147 done | tee -a ${OUTPUT}/signatures.${MACHINE2}.${TASK}.log
148 # don't create empty files
149 ERRORS=`grep "^ERROR.*" ${OUTPUT}/signatures.${MACHINE2}.${TASK}.log | wc -l`
150 if [ "${ERRORS}" != "0" ] ; then
151 echo "ERROR: ${ERRORS} errors found in ${OUTPUT}/signatures.${MACHINE2}.${TASK}.log"
152 RESULT+=${ERRORS}
153 fi
154 done
155}
156
157function compareMachines() {
158 [ "$#" -ge 2 ] && compareSignatures $1 $2
159 [ "$#" -ge 3 ] && compareSignatures $1 $3 "\(^< all\)\|\(^< x86_64-linux\)\|\(^< i586-linux\)"
160}
161
162if [ "${analyze}" = "Y" ] ; then
163 compareMachines ${machines}
164fi
165
166if [ "${RESULT}" != "0" -a -f ${OUTPUT}/failed-recipes.log ] ; then
167 cat ${OUTPUT}/failed-recipes.log | sort -u >${OUTPUT}/failed-recipes.log.u && mv ${OUTPUT}/failed-recipes.log.u ${OUTPUT}/failed-recipes.log
168 echo "ERROR: ${RESULT} issues were found in these recipes: `cat ${OUTPUT}/failed-recipes.log | xargs`"
169fi
170
171echo "INFO: Output written in: ${OUTPUT}"
172exit ${RESULT}