aboutsummaryrefslogtreecommitdiff
path: root/llvm_tools/llvm_local_bisection.sh
blob: e319080c1cbffdf1e7228d9d1d1e759d7f8024bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/bin/bash -u
# -*- coding: utf-8 -*-
# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# llvm_bisection_template.sh
#
# This script is meant to be run inside a `git bisect` process, like so:
#
#   $ cd <your llvm-project dir>
#   $ git bisect start
#   $ git bisect bad <your bad ref>
#   $ git bisect good <your good ref>
#   $ git bisect run ~/chromimuos/src/scripts/llvm_bisection_template.sh
#
# This template exists as a "batteries included" LLVM bisection script,
# which will modify the LLVM_NEXT hash to help the mage track down issues
# locally.
#
# Modify the fixme sections below to customize to your bisection use-case.

# FIXME: Replace this for the location of your llvm clone within the chroot.
# We need this for the git history.
LLVM_CLONE_PATH="${HOME}/chromiumos/src/third_party/llvm-project"

main () {
  # Note this builds with USE="llvm-next debug -thinlto -llvm_pgo_use continue-on-patch-failure"
  build_llvm || exit

  # FIXME: Write your actual bisection command here which uses
  # LLVM_NEXT here.
  #
  # Example bisection command:
  #
  #   build_pkg efitools || exit 1
  #
  # You can use build_pkg if you want to emerge a package and print
  # out diagnostics along the way
  #
  #   Fail Example: build_pkg "${MY_PACKAGE}" || exit 1
  #   Skip Example: build_pkg "${MY_PACKAGE}" || exit 125
  #
}

# ---------------------------------------------------------------------

# Current LLVM_NEXT_HASH we're using. Does not need to be set.
CURRENT='UNKNOWN'

logdo () {
  local cmd="${1}"
  shift
  printf '%1 $ %2' "$(date '+%T')" "${cmd}"
  for i in "$@"; do
    printf "'%1'" "${i}"
  done
  printf "\n"
  "${cmd}" "$@"
}

log () {
  echo "$(date '+%T') | $*"
}

build_llvm () {
  cd "${LLVM_CLONE_PATH}" || exit 2  # Exit with error
  local llvm_ebuild_path
  llvm_ebuild_path="$(readlink -f "$(equery which llvm)")"
  CURRENT="$(git rev-parse --short HEAD)"
  log "Current hash=${CURRENT}"
  NEW_LINE="LLVM_NEXT_HASH=\"${CURRENT}\""
  sed -i "s/^LLVM_NEXT_HASH=\".*\"/${NEW_LINE}/" "${llvm_ebuild_path}"

  local logfile="/tmp/build-llvm.${CURRENT}.out"
  log "Writing logs to ${logfile}"
  log "sudo USE='llvm-next debug -thinlto -llvm_use_pgo continue-on-patch-failure'" \
      " emerge sys-devel/llvm"
  logdo sudo USE='llvm-next debug -thinlto -llvm_use_pgo continue-on-patch-failure' emerge \
    sys-devel/llvm \
    &> "${logfile}"
  local emerge_exit_code="$?"
  if [[ "${emerge_exit_code}" -ne 0 ]]; then
    log "FAILED to build llvm with hash=${CURRENT}"
    log 'Skipping this hash'
    return 125  # 125 is the "skip" exit code.
  fi
  log "Succesfully built LLVM with hash=${CURRENT}"
  return 0  # Explicitly returning 0 for "good" even if a command errors out
}

build_pkg () {
  local pkg="${1}"

  local logfile="/tmp/build-${pkg}.${CURRENT}.out"
  log "Writing logs to ${logfile}"
  log "sudo emerge ${pkg}"
  logdo sudo emerge "${pkg}" \
    &> "${logfile}"
  local emerge_exit_code="$?"
  if [[ "${emerge_exit_code}" -ne 0 ]]; then
    log "FAILED to build ${pkg} with hash=${CURRENT}"
    return 1  # 1 here isn't for bisection, but for chaining with `||`
  fi
  log "Successfully built ${pkg} with hash=${CURRENT}"
  return 0  # Explicitly returning 0 for "good" even if a command errors out
}

main