Skip to content

Instantly share code, notes, and snippets.

@rgov
Created May 17, 2020 18:01
Show Gist options
  • Save rgov/2b338046892c675faf645e42d78d0896 to your computer and use it in GitHub Desktop.
Save rgov/2b338046892c675faf645e42d78d0896 to your computer and use it in GitHub Desktop.
Tool to help with multiple LLVM working trees
#!/usr/bin/env python3
'''
This script helps in maintaining multiple working trees for the LLVM project.
'''
import os
import subprocess
def ensure_main_tree(main):
if not os.path.exists(main):
print('Main working tree does not exist, cloning it...')
os.makedirs(main)
subprocess.check_call([
'git', 'clone',
'https://github.com/llvm/llvm-project',
'.'
], cwd=main)
subprocess.check_call([
'git', 'config',
'extensions.worktreeConfig', 'true'
], cwd=main)
def get_git_path(tree):
return subprocess.check_output([
'git', 'rev-parse', '--git-path', tree
])
def list_cmd(args):
'''Lists all working trees.'''
ensure_main_tree(args.main)
subprocess.check_call(['git', 'worktree', 'list'], cwd=args.main)
def add_cmd(args):
'''Creates a new working directory and checks out desired projects.'''
ensure_main_tree(args.main)
# Add a new working tree, without any files
subprocess.check_call([
'git', 'worktree', 'add',
'--no-checkout',
'-b', args.branch,
os.path.abspath(args.dir),
args.base
], cwd=args.main)
# Initialize sparse checkout, which checks out regular files in the root
# directory, but does not include any subdirectories.
subprocess.check_call(['git', 'sparse-checkout', 'init'], cwd=args.dir)
# Add any subprojects requested
subprocess.check_call([
'git', 'sparse-checkout', 'add',
'llvm', *args.projects
], cwd=args.dir)
if args.cmake:
# Create the build directory
build_dir = os.path.join(args.dir, 'build')
os.mkdir(build_dir)
# Run CMake
subprocess.check_call([
'cmake',
'-G', args.cmake_generator,
'-DCMAKE_BUILD_TYPE=' + args.cmake_build_type,
'-DLLVM_ENABLE_PROJECTS=' + ';'.join(args.projects),
'-DLLVM_TARGETS_TO_BUILD=' + ';'.join(args.targets),
'../llvm'
], cwd=build_dir)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
'--main',
default=os.path.expanduser('~/SourceCache/llvm-project'),
help='path to main working tree'
)
subparsers = parser.add_subparsers(dest='command', required=True)
# List subcommand options
parser_list = subparsers.add_parser('list', description=list_cmd.__doc__)
parser_list.set_defaults(func=list_cmd)
# Add subcommand options
parser_add = subparsers.add_parser('add', description=add_cmd.__doc__)
parser_add.set_defaults(func=add_cmd)
parser_add.add_argument(
'--project', '-p',
metavar='PROJECT', dest='projects', action='append', default=[],
help='include a project in the checkout (e.g., clang)'
)
parser_add.add_argument(
'--target', '-t',
metavar='TARGET', dest='targets', action='append',
help='enable a LLVM target (if none supplied, x86 is default)'
)
parser_add.add_argument(
'--no-cmake',
dest='cmake', action='store_false',
help='do not run CMake in the new working tree'
)
parser_add.add_argument(
'--cmake-generator', default='Ninja',
help='CMake generator (see `man cmake`)'
)
parser_add.add_argument(
'--cmake-build-type', default='RelWithDebInfo',
help='CMake build type (see `man cmake`)'
)
parser_add.add_argument(
'dir',
help='destination directory to create'
)
parser_add.add_argument(
'branch',
help='name of the new branch to create for this work tree'
)
parser_add.add_argument(
'base',
nargs='?', default='master',
help='base commit or branch to check out (default: master)'
)
args = parser.parse_args()
# Fixups
if args.command == 'add':
if not args.targets:
args.targets = ['X86']
args.func(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment