xref: /aosp_15_r20/external/toolchain-utils/llvm_tools/llvm_local_bisection.sh (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
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