| #!/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()) |