The command to detect whether the stash is needed is `git status --porcelain` which includes untracked files by default. We want to stash untracked files as well as they may affect compilation (LLVM CMake checks that all source files should be included in CMakeLists). Update the stash command to include untracked files as well. Reviewed By: #bolt, rafauler Differential Revision: https://reviews.llvm.org/D132610
96 lines
3.8 KiB
Python
Executable File
96 lines
3.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import argparse
|
|
import os
|
|
import re
|
|
import shlex
|
|
import subprocess
|
|
import sys
|
|
import textwrap
|
|
|
|
def get_git_ref_or_rev(dir: str) -> str:
|
|
# Run 'git symbolic-ref -q --short HEAD || git rev-parse --short HEAD'
|
|
cmd_ref = 'git symbolic-ref -q --short HEAD'
|
|
ref = subprocess.run(shlex.split(cmd_ref), cwd=dir, text=True,
|
|
stdout=subprocess.PIPE)
|
|
if not ref.returncode:
|
|
return ref.stdout.strip()
|
|
cmd_rev = 'git rev-parse --short HEAD'
|
|
return subprocess.check_output(shlex.split(cmd_rev), cwd=dir,
|
|
text=True).strip()
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=textwrap.dedent('''
|
|
This script builds two versions of BOLT (with the current and
|
|
previous revision) and sets up symlink for llvm-bolt-wrapper.
|
|
Passes the options through to llvm-bolt-wrapper.
|
|
'''))
|
|
parser.add_argument('build_dir', nargs='?', default=os.getcwd(),
|
|
help='Path to BOLT build directory, default is current '
|
|
'directory')
|
|
parser.add_argument('--switch-back', default=False, action='store_true',
|
|
help='Checkout back to the starting revision')
|
|
args, wrapper_args = parser.parse_known_args()
|
|
bolt_path = f'{args.build_dir}/bin/llvm-bolt'
|
|
|
|
source_dir = None
|
|
# find the repo directory
|
|
with open(f'{args.build_dir}/CMakeCache.txt') as f:
|
|
for line in f:
|
|
m = re.match(r'LLVM_SOURCE_DIR:STATIC=(.*)', line)
|
|
if m:
|
|
source_dir = m.groups()[0]
|
|
if not source_dir:
|
|
sys.exit("Source directory is not found")
|
|
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
wrapper_path = f'{script_dir}/llvm-bolt-wrapper.py'
|
|
# build the current commit
|
|
subprocess.run(shlex.split("cmake --build . --target llvm-bolt"),
|
|
cwd=args.build_dir)
|
|
# rename llvm-bolt
|
|
os.replace(bolt_path, f'{bolt_path}.new')
|
|
# memorize the old hash for logging
|
|
old_ref = get_git_ref_or_rev(source_dir)
|
|
|
|
# determine whether a stash is needed
|
|
stash = subprocess.run(shlex.split("git status --porcelain"), cwd=source_dir,
|
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
|
text=True).stdout
|
|
if stash:
|
|
# save local changes before checkout
|
|
subprocess.run(shlex.split("git stash push -u"), cwd=source_dir)
|
|
# check out the previous commit
|
|
subprocess.run(shlex.split("git checkout -f HEAD^"), cwd=source_dir)
|
|
# get the parent commit hash for logging
|
|
new_ref = get_git_ref_or_rev(source_dir)
|
|
# build the previous commit
|
|
subprocess.run(shlex.split("cmake --build . --target llvm-bolt"),
|
|
cwd=args.build_dir)
|
|
# rename llvm-bolt
|
|
os.replace(bolt_path, f'{bolt_path}.old')
|
|
# set up llvm-bolt-wrapper.ini
|
|
ini = subprocess.check_output(
|
|
shlex.split(
|
|
f"{wrapper_path} {bolt_path}.old {bolt_path}.new") + wrapper_args,
|
|
text=True)
|
|
with open(f'{args.build_dir}/bin/llvm-bolt-wrapper.ini', 'w') as f:
|
|
f.write(ini)
|
|
# symlink llvm-bolt-wrapper
|
|
os.symlink(wrapper_path, bolt_path)
|
|
if args.switch_back:
|
|
if stash:
|
|
subprocess.run(shlex.split("git stash pop"), cwd=source_dir)
|
|
subprocess.run(shlex.split(f"git checkout {old_ref}"), cwd=source_dir)
|
|
else:
|
|
print(f"The repository {source_dir} has been switched from {old_ref} "
|
|
f"to {new_ref}. Local changes were stashed. Switch back using\n\t"
|
|
f"git checkout {old_ref}\n")
|
|
print(f"Build directory {args.build_dir} is ready to run BOLT tests, e.g.\n"
|
|
"\tbin/llvm-lit -sv tools/bolt/test\nor\n"
|
|
"\tbin/llvm-lit -sv tools/bolttests")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|