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