1*760c253cSXin Li#!/bin/bash -u 2*760c253cSXin Li# -*- coding: utf-8 -*- 3*760c253cSXin Li# Copyright 2022 The ChromiumOS Authors 4*760c253cSXin Li# Use of this source code is governed by a BSD-style license that can be 5*760c253cSXin Li# found in the LICENSE file. 6*760c253cSXin Li 7*760c253cSXin Li# llvm_bisection_template.sh 8*760c253cSXin Li# 9*760c253cSXin Li# This script is meant to be run inside a `git bisect` process, like so: 10*760c253cSXin Li# 11*760c253cSXin Li# $ cd <your llvm-project dir> 12*760c253cSXin Li# $ git bisect start 13*760c253cSXin Li# $ git bisect bad <your bad ref> 14*760c253cSXin Li# $ git bisect good <your good ref> 15*760c253cSXin Li# $ git bisect run ~/chromimuos/src/scripts/llvm_bisection_template.sh 16*760c253cSXin Li# 17*760c253cSXin Li# This template exists as a "batteries included" LLVM bisection script, 18*760c253cSXin Li# which will modify the LLVM_NEXT hash to help the mage track down issues 19*760c253cSXin Li# locally. 20*760c253cSXin Li# 21*760c253cSXin Li# Modify the fixme sections below to customize to your bisection use-case. 22*760c253cSXin Li 23*760c253cSXin Li# FIXME: Replace this for the location of your llvm clone within the chroot. 24*760c253cSXin Li# We need this for the git history. 25*760c253cSXin LiLLVM_CLONE_PATH="${HOME}/chromiumos/src/third_party/llvm-project" 26*760c253cSXin Li 27*760c253cSXin Limain () { 28*760c253cSXin Li # Note this builds with USE="llvm-next debug -thinlto -llvm_pgo_use continue-on-patch-failure" 29*760c253cSXin Li build_llvm || exit 30*760c253cSXin Li 31*760c253cSXin Li # FIXME: Write your actual bisection command here which uses 32*760c253cSXin Li # LLVM_NEXT here. 33*760c253cSXin Li # 34*760c253cSXin Li # Example bisection command: 35*760c253cSXin Li # 36*760c253cSXin Li # build_pkg efitools || exit 1 37*760c253cSXin Li # 38*760c253cSXin Li # You can use build_pkg if you want to emerge a package and print 39*760c253cSXin Li # out diagnostics along the way 40*760c253cSXin Li # 41*760c253cSXin Li # Fail Example: build_pkg "${MY_PACKAGE}" || exit 1 42*760c253cSXin Li # Skip Example: build_pkg "${MY_PACKAGE}" || exit 125 43*760c253cSXin Li # 44*760c253cSXin Li} 45*760c253cSXin Li 46*760c253cSXin Li# --------------------------------------------------------------------- 47*760c253cSXin Li 48*760c253cSXin Li# Current LLVM_NEXT_HASH we're using. Does not need to be set. 49*760c253cSXin LiCURRENT='UNKNOWN' 50*760c253cSXin Li 51*760c253cSXin Lilogdo () { 52*760c253cSXin Li local cmd="${1}" 53*760c253cSXin Li shift 54*760c253cSXin Li printf '%1 $ %2' "$(date '+%T')" "${cmd}" 55*760c253cSXin Li for i in "$@"; do 56*760c253cSXin Li printf "'%1'" "${i}" 57*760c253cSXin Li done 58*760c253cSXin Li printf "\n" 59*760c253cSXin Li "${cmd}" "$@" 60*760c253cSXin Li} 61*760c253cSXin Li 62*760c253cSXin Lilog () { 63*760c253cSXin Li echo "$(date '+%T') | $*" 64*760c253cSXin Li} 65*760c253cSXin Li 66*760c253cSXin Libuild_llvm () { 67*760c253cSXin Li cd "${LLVM_CLONE_PATH}" || exit 2 # Exit with error 68*760c253cSXin Li local llvm_ebuild_path 69*760c253cSXin Li llvm_ebuild_path="$(readlink -f "$(equery which llvm)")" 70*760c253cSXin Li CURRENT="$(git rev-parse --short HEAD)" 71*760c253cSXin Li log "Current hash=${CURRENT}" 72*760c253cSXin Li NEW_LINE="LLVM_NEXT_HASH=\"${CURRENT}\"" 73*760c253cSXin Li sed -i "s/^LLVM_NEXT_HASH=\".*\"/${NEW_LINE}/" "${llvm_ebuild_path}" 74*760c253cSXin Li 75*760c253cSXin Li local logfile="/tmp/build-llvm.${CURRENT}.out" 76*760c253cSXin Li log "Writing logs to ${logfile}" 77*760c253cSXin Li log "sudo USE='llvm-next debug -thinlto -llvm_use_pgo continue-on-patch-failure'" \ 78*760c253cSXin Li " emerge sys-devel/llvm" 79*760c253cSXin Li logdo sudo USE='llvm-next debug -thinlto -llvm_use_pgo continue-on-patch-failure' emerge \ 80*760c253cSXin Li sys-devel/llvm \ 81*760c253cSXin Li &> "${logfile}" 82*760c253cSXin Li local emerge_exit_code="$?" 83*760c253cSXin Li if [[ "${emerge_exit_code}" -ne 0 ]]; then 84*760c253cSXin Li log "FAILED to build llvm with hash=${CURRENT}" 85*760c253cSXin Li log 'Skipping this hash' 86*760c253cSXin Li return 125 # 125 is the "skip" exit code. 87*760c253cSXin Li fi 88*760c253cSXin Li log "Succesfully built LLVM with hash=${CURRENT}" 89*760c253cSXin Li return 0 # Explicitly returning 0 for "good" even if a command errors out 90*760c253cSXin Li} 91*760c253cSXin Li 92*760c253cSXin Libuild_pkg () { 93*760c253cSXin Li local pkg="${1}" 94*760c253cSXin Li 95*760c253cSXin Li local logfile="/tmp/build-${pkg//\//_}.${CURRENT}.out" 96*760c253cSXin Li log "Writing logs to ${logfile}" 97*760c253cSXin Li log "sudo emerge ${pkg}" 98*760c253cSXin Li logdo sudo emerge "${pkg}" \ 99*760c253cSXin Li &> "${logfile}" 100*760c253cSXin Li local emerge_exit_code="$?" 101*760c253cSXin Li if [[ "${emerge_exit_code}" -ne 0 ]]; then 102*760c253cSXin Li log "FAILED to build ${pkg} with hash=${CURRENT}" 103*760c253cSXin Li return 1 # 1 here isn't for bisection, but for chaining with `||` 104*760c253cSXin Li fi 105*760c253cSXin Li log "Successfully built ${pkg} with hash=${CURRENT}" 106*760c253cSXin Li return 0 # Explicitly returning 0 for "good" even if a command errors out 107*760c253cSXin Li} 108*760c253cSXin Li 109*760c253cSXin Limain 110