1#!/bin/bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright(c) 2021 Intel Corporation. All rights reserved. 4 5# This builds SOF twice with some environment variations and then 6# compares the binary outputs. 7 8# Big caveats: 9# 10# - Only -g0 is supported, no BUILD_PATH_PREFIX_MAP 11# - rimage uses the current date (day month year) in the 12# signature. 13# - Starting from TGL, signatures also include a random salt. 14# 15# rimage makes sof.ri non-deterministic even when sof.elf is 16# deterministic. See https://github.com/thesofproject/rimage/issues/41 17# and below for more details and future directions. 18 19# The following, basic environment variations are currently tested: 20# 21# - timestamps (obviously) 22# - source directory 23# - disorderfs 24 25# For a list of other, non-tested environment variations check the 26# "Achieve deterministic builds" list found at 27# https://reproducible-builds.org/docs/ 28 29 30set -e 31 32 33SOF_TOP=$(cd "$(dirname "$0")"/.. && /bin/pwd) 34SOF_PARENT=$(cd "$SOF_TOP"/.. && /bin/pwd) 35 36 37SOF2="$SOF_PARENT"/sof-bind-mount-DO-NOT-DELETE 38# To avoid ripple effects and reduce the number of differences 39# considerably, replace "sof" with something of the same length: 40# SOF2="$SOF_PARENT"/sog 41 42PLATFS=(tgl) 43 44# diffoscope is great but it has hundreds of dependencies, too long to 45# install for CI so we don't use it here. This is just an alias 46# suggestion for local use. Requires less -R. 47diffo () 48{ 49 # Omitting $2 ("and") allows copy/paste of the output of diff -r 50 diffoscope --exclude-directory-metadata=recursive \ 51 --text-color=always "$1" "$3" 52} 53 54hexdiff () 55{ 56 # cut -b10 removes the offset 57 diff --color=auto -U20 \ 58 <(hexdump -vC "$1" | cut -b10- ) \ 59 <(hexdump -vC "$2" | cut -b10- ) | less 60} 61 62init() 63{ 64 # -E(xtended) regex 65 local excluded_endings=( 66 '\.log' /deps 67 '\.c?make' '\.ninja' /TargetDirectories.txt 68 /CMakeCache.txt /progress.marks /CMakeRulesHashes.txt /Makefile 69 /CMakeRuleHashes.txt /Makefile2 70 '/depend\.internal' /link.txt '\.includecache' 71 '/.ninja_deps' '/.ninja_log' 72 '.*\.c\.o\.d' 73 '/rimage_ep.*' 74 '/smex_ep.*' 75 ) 76 77 # The signing process is not deterministic. 78 # Keep 'reproducible.ri' INCLUDED! 79 excluded_endings+=('/sof-[a-z-]{,6}\.rix?') 80 excluded_endings+=('/sof\.ri' '/sof-no-xman\.ri' ) 81 82 GREP_EXCLUDE_ARGS=() 83 for fpath in "${excluded_endings[@]}"; do 84 GREP_EXCLUDE_ARGS+=('-e' "$fpath differ\$") 85 done 86 87 # For debug 88 # declare -p GREP_EXCLUDE_ARGS # exit 89} 90 91 92trap _unmount EXIT 93 94_unmount() 95{ 96 set +e 97 98 if mount | grep -q "${SOF2}.*fuse"; then 99 umount "$SOF2" 100 rmdir "$SOF2" 101 fi 102} 103 104 105diff_some_files() 106{ 107 local p f 108 ( set +e 109 110 for p in "${PLATFS[@]}"; do 111 112 # Compare some ELF section headers. Look at the smallest .c.o 113 # first 114 for f in CMakeFiles/sof.dir/src/arch/xtensa/init.c.o sof; do 115 116 diff --report-identical-files \ 117 {b0,b1}/build_"$p"_?cc/"$f" || 118 diff -u --ignore-matching-lines='file format ' \ 119 <(objdump -h b0/build_"$p"_?cc/"$f") \ 120 <(objdump -h b1/build_"$p"_?cc/"$f") 121 122 done 123 124 for f in generated/include/sof_versions.h sof.ri \ 125 src/arch/xtensa/reproducible.ri; do 126 diff -u --report-identical-files \ 127 {b0,b1}/build_"$p"_?cc/"$f" 128 # report unsupported reproducible.ri 129 test -s b0/build_"$p"_?cc/"$f" || 130 printf '\t%s is EMPTY\n' b0/build_"$p"_?cc/"$f" 131 done 132 133 done 134 true 135 ) | sed -e 's/differ/DIFFER/g' 136} 137 138main() 139{ 140 init 141 142 test -e "$SOF2"/CMakeLists.txt || { 143 mkdir -p "$SOF2" 144 # This will fail in Docker; Docker should provide this bind 145 # mount for us. 146 disorderfs "${SOF_TOP}" "$SOF2" 147 } 148 149 # Chances of name collisions with the user should be pretty small 150 rm -rf reprobld/b0/ reprobld/b1/ 151 mkdir -p reprobld/b0/ reprobld/b1/ 152 153 local oldTZ="$TZ" # typically undefined, coming from some /etc file 154 # instead. 155 156 export EXTRA_CFLAGS='-g0' 157 158 # Going once 159 160 export TZ='Pacific/Midway' # -11:00 161 "${SOF_TOP}"/scripts/xtensa-build-all.sh "${PLATFS[@]}" 162 mv build_*_?cc reprobld/b0/ 163 164 165 # Going twice 166 167 # Use this to "break" rimage that makes the date (in local time! 168 # BIOS fans?) part of the CSS signature. See caveats above. 169 # +14:00 - -11:00 = +25:00 = always on a different date 170 export TZ='Pacific/Kiritimati' # +14:00 171 172 "$SOF2"/scripts/xtensa-build-all.sh "${PLATFS[@]}" 173 mv build_*_?cc reprobld/b1/ 174 175 176 # Restore TZ just in case we want to use dates later. 177 TZ="$oldTZ" 178 179 180 cd reprobld 181 diff -qr b0 b1/ | 182 grep -E -v "${GREP_EXCLUDE_ARGS[@]}" || { 183 printf \ 184 "\n\n ---- PASS: no unexpected difference found between %s/b0/ and b1/ --- \n\n" "$(pwd)" 185 exit 0 186 } 187 188 printf "\n\n ---- FAIL: differences found between %s/b0/ and b1/ --- \n\n" "$(pwd)" 189 diff_some_files 190 printf "\n\n ---- FAIL: differences found between %s/b0/ and b1/ --- \n\n" "$(pwd)" 191} 192 193main "$@" 194