1*7594170eSAndroid Build Coastguard Worker#!/bin/bash -eu 2*7594170eSAndroid Build Coastguard Worker 3*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2023 The Android Open Source Project 4*7594170eSAndroid Build Coastguard Worker# 5*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*7594170eSAndroid Build Coastguard Worker# 11*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*7594170eSAndroid Build Coastguard Worker# limitations under the License. 16*7594170eSAndroid Build Coastguard Worker 17*7594170eSAndroid Build Coastguard Worker 18*7594170eSAndroid Build Coastguard Worker# Verifies that various intermediate outputs of the build have deterministic 19*7594170eSAndroid Build Coastguard Worker# outputs. Nondeterministic intermediate outputs have incremental performance 20*7594170eSAndroid Build Coastguard Worker# implications, so this is a critical test even if the determinism if the final 21*7594170eSAndroid Build Coastguard Worker# outputs is not in question. 22*7594170eSAndroid Build Coastguard Worker# 23*7594170eSAndroid Build Coastguard Worker# Determinism is verified by running several builds and comparing checksums of 24*7594170eSAndroid Build Coastguard Worker# outputs. This may provides confidence in determinism, but does not guarantee 25*7594170eSAndroid Build Coastguard Worker# it. "Flakiness" in this test should thus be treated as indicative of a 26*7594170eSAndroid Build Coastguard Worker# failure, and investigated promptly. 27*7594170eSAndroid Build Coastguard Workerif [[ -z ${OUT_DIR+x} ]]; then 28*7594170eSAndroid Build Coastguard Worker OUT_DIR="out" 29*7594170eSAndroid Build Coastguard Workerfi 30*7594170eSAndroid Build Coastguard Worker 31*7594170eSAndroid Build Coastguard Workerif [[ -z ${DIST_DIR+x} ]]; then 32*7594170eSAndroid Build Coastguard Worker echo "DIST_DIR not set. Using ${OUT_DIR}/dist. This should only be used for manual developer testing." 33*7594170eSAndroid Build Coastguard Worker DIST_DIR="${OUT_DIR}/dist" 34*7594170eSAndroid Build Coastguard Workerfi 35*7594170eSAndroid Build Coastguard Worker 36*7594170eSAndroid Build Coastguard Workerif [[ -z ${TARGET_PRODUCT+x} ]]; then 37*7594170eSAndroid Build Coastguard Worker echo "TARGET_PRODUCT not set. Using aosp_arm64" 38*7594170eSAndroid Build Coastguard Worker TARGET_PRODUCT=aosp_arm64 39*7594170eSAndroid Build Coastguard Workerfi 40*7594170eSAndroid Build Coastguard Worker 41*7594170eSAndroid Build Coastguard Workerif [[ -z ${TARGET_BUILD_VARIANT+x} ]]; then 42*7594170eSAndroid Build Coastguard Worker echo "TARGET_BUILD_VARIANT not set. Using userdebug" 43*7594170eSAndroid Build Coastguard Worker TARGET_BUILD_VARIANT=userdebug 44*7594170eSAndroid Build Coastguard Workerfi 45*7594170eSAndroid Build Coastguard Worker 46*7594170eSAndroid Build Coastguard WorkerUNAME="$(uname)" 47*7594170eSAndroid Build Coastguard Workercase "$UNAME" in 48*7594170eSAndroid Build Coastguard WorkerLinux) 49*7594170eSAndroid Build Coastguard Worker PREBUILTS="prebuilts/build-tools/path/linux-x86" 50*7594170eSAndroid Build Coastguard Worker ;; 51*7594170eSAndroid Build Coastguard WorkerDarwin) 52*7594170eSAndroid Build Coastguard Worker PREBUILTS="prebuilts/build-tools/path/darwin-x86" 53*7594170eSAndroid Build Coastguard Worker ;; 54*7594170eSAndroid Build Coastguard Worker*) 55*7594170eSAndroid Build Coastguard Worker exit 1 56*7594170eSAndroid Build Coastguard Worker ;; 57*7594170eSAndroid Build Coastguard Workeresac 58*7594170eSAndroid Build Coastguard Worker 59*7594170eSAndroid Build Coastguard Workerfunction clean_build { 60*7594170eSAndroid Build Coastguard Worker build/soong/soong_ui.bash --make-mode clean 61*7594170eSAndroid Build Coastguard Worker 62*7594170eSAndroid Build Coastguard Worker # Generate the ninja file with default setting. We expect Bazel to be enabled by 63*7594170eSAndroid Build Coastguard Worker # default. 64*7594170eSAndroid Build Coastguard Worker build/soong/soong_ui.bash --make-mode \ 65*7594170eSAndroid Build Coastguard Worker --mk-metrics \ 66*7594170eSAndroid Build Coastguard Worker BAZEL_STARTUP_ARGS="--max_idle_secs=5" \ 67*7594170eSAndroid Build Coastguard Worker BAZEL_BUILD_ARGS="--color=no --curses=no --show_progress_rate_limit=5" \ 68*7594170eSAndroid Build Coastguard Worker TARGET_PRODUCT=${TARGET_PRODUCT} \ 69*7594170eSAndroid Build Coastguard Worker TARGET_BUILD_VARIANT=${TARGET_BUILD_VARIANT} \ 70*7594170eSAndroid Build Coastguard Worker nothing \ 71*7594170eSAndroid Build Coastguard Worker dist DIST_DIR=$DIST_DIR 72*7594170eSAndroid Build Coastguard Worker} 73*7594170eSAndroid Build Coastguard Worker 74*7594170eSAndroid Build Coastguard Workerfunction save_hash { 75*7594170eSAndroid Build Coastguard Worker local -r filepath="$1" 76*7594170eSAndroid Build Coastguard Worker find $OUT_DIR/soong/workspace -type f,l -iname "BUILD.bazel" -o -iname "*.bzl" | xargs "${PREBUILTS}"/md5sum > $filepath 77*7594170eSAndroid Build Coastguard Worker find $OUT_DIR/soong/soong_injection -type f,l | xargs "${PREBUILTS}"/md5sum >> $filepath 78*7594170eSAndroid Build Coastguard Worker "${PREBUILTS}"/md5sum $OUT_DIR/soong/Android-${TARGET_PRODUCT}.mk >> $filepath 79*7594170eSAndroid Build Coastguard Worker if [[ -z ${SKIP_NINJA_CHECK+x} ]]; then 80*7594170eSAndroid Build Coastguard Worker "${PREBUILTS}"/md5sum $OUT_DIR/soong/build.${TARGET_PRODUCT}.ninja >> $filepath 81*7594170eSAndroid Build Coastguard Worker fi 82*7594170eSAndroid Build Coastguard Worker} 83*7594170eSAndroid Build Coastguard Worker 84*7594170eSAndroid Build Coastguard WorkerTESTDIR=$(mktemp -t testdir.XXXXXX -d) 85*7594170eSAndroid Build Coastguard WorkerFIRST_FILE=$TESTDIR/first_hashes 86*7594170eSAndroid Build Coastguard WorkerTEST_FILE=$TESTDIR/hashes_to_test 87*7594170eSAndroid Build Coastguard Worker 88*7594170eSAndroid Build Coastguard Workerclean_build 89*7594170eSAndroid Build Coastguard Workersave_hash $FIRST_FILE 90*7594170eSAndroid Build Coastguard Worker 91*7594170eSAndroid Build Coastguard Workerfor i in {1..4} ; do 92*7594170eSAndroid Build Coastguard Worker clean_build 93*7594170eSAndroid Build Coastguard Worker save_hash $TEST_FILE 94*7594170eSAndroid Build Coastguard Worker if cmp -s "$FIRST_FILE" "$TEST_FILE" 95*7594170eSAndroid Build Coastguard Worker then 96*7594170eSAndroid Build Coastguard Worker echo "Comparison $i succeeded." 97*7594170eSAndroid Build Coastguard Worker else 98*7594170eSAndroid Build Coastguard Worker cp $FIRST_FILE $TEST_FILE $DIST_DIR 99*7594170eSAndroid Build Coastguard Worker >&2 echo "Comparison $i failed. This likely indicates nondeterminism in the differing files." 100*7594170eSAndroid Build Coastguard Worker >&2 echo "\n\nFirst file hashes:\n" 101*7594170eSAndroid Build Coastguard Worker >&2 cat $FIRST_FILE 102*7594170eSAndroid Build Coastguard Worker >&2 echo "\n\nRerun $i:\n" 103*7594170eSAndroid Build Coastguard Worker >&2 cat $TEST_FILE 104*7594170eSAndroid Build Coastguard Worker exit 1 105*7594170eSAndroid Build Coastguard Worker fi 106*7594170eSAndroid Build Coastguard Workerdone 107