blob: 12c08fd18042f574db5304bcf381d12245dd362d [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A script for fetching LLVM monorepo and building clang-tools-extra binaries.
Example: build clangd and clangd-indexer
tools/clang/scripts/build_clang_tools_extra.py --fetch out/Release clangd \
clangd-indexer
"""
import argparse
import errno
import os
import subprocess
import sys
import update
def GetCheckoutDir(out_dir):
"""Returns absolute path to the checked-out llvm repo."""
return os.path.join(out_dir, 'tools', 'clang', 'third_party', 'llvm')
def GetBuildDir(out_dir):
return os.path.join(GetCheckoutDir(out_dir), 'build')
def CreateDirIfNotExists(dir):
if not os.path.exists(dir):
os.makedirs(dir)
def FetchLLVM(checkout_dir, revision):
"""Clone llvm repo into |out_dir| or update if it already exists."""
CreateDirIfNotExists(os.path.dirname(checkout_dir))
try:
# First, try to clone the repo.
args = [
'git',
'clone',
'https://github.com/llvm/llvm-project.git',
checkout_dir,
]
subprocess.check_call(args, shell=sys.platform == 'win32')
except subprocess.CalledProcessError:
# Otherwise, try to update it.
print('-- Attempting to update existing repo')
args = ['git', 'pull', '--rebase', 'origin', 'master']
subprocess.check_call(args, cwd=checkout_dir)
if revision:
args = ['git', 'checkout', revision]
subprocess.check_call(args, cwd=checkout_dir)
def BuildTargets(build_dir, targets):
"""Build targets from llvm repo at |build_dir|."""
CreateDirIfNotExists(build_dir)
# From that dir, run cmake
cmake_args = [
'cmake',
'-GNinja',
'-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra',
'-DCMAKE_BUILD_TYPE=Release',
'-DLLVM_ENABLE_ASSERTIONS=On',
'../llvm',
]
subprocess.check_call(cmake_args, cwd=build_dir)
ninja_commands = ['ninja'] + targets
subprocess.check_call(ninja_commands, cwd=build_dir)
def main():
parser = argparse.ArgumentParser(description='Build clang_tools_extra.')
parser.add_argument('--fetch', action='store_true', help='fetch LLVM source')
parser.add_argument(
'--revision', help='LLVM revision to use', default=update.CLANG_REVISION)
parser.add_argument('OUT_DIR', help='where we put the LLVM source repository')
parser.add_argument('TARGETS', nargs='+', help='targets being built')
args = parser.parse_args()
if args.fetch:
print 'Fetching LLVM source'
FetchLLVM(GetCheckoutDir(args.OUT_DIR), args.revision)
print 'Building targets: %s' % ', '.join(args.TARGETS)
BuildTargets(GetBuildDir(args.OUT_DIR), args.TARGETS)
if __name__ == '__main__':
sys.exit(main())