1#!/usr/bin/env python 2# 3# Copyright 2016 Google Inc. 4# 5# Use of this source code is governed by a BSD-style license that can be 6# found in the LICENSE file. 7 8 9"""Create a Clang toolchain for Linux hosts.""" 10 11 12import argparse 13import os 14import subprocess 15import tempfile 16 17 18BRANCH = "release/10.x" 19 20 21def create_asset(target_dir): 22 # CMake will sometimes barf if we pass it a relative path. 23 target_dir = os.path.abspath(target_dir) 24 25 # Build Clang, lld, compiler-rt (sanitizer support) and libc++. 26 os.chdir(tempfile.mkdtemp()) 27 subprocess.check_call(["git", "clone", "--depth", "1", "-b", BRANCH, 28 "https://llvm.googlesource.com/llvm-project"]) 29 os.chdir("llvm-project") 30 os.mkdir("out") 31 os.chdir("out") 32 subprocess.check_call(["cmake", "../llvm", "-G", "Ninja", 33 "-DCMAKE_BUILD_TYPE=MinSizeRel", 34 "-DCMAKE_INSTALL_PREFIX=" + target_dir, 35 "-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra;" + 36 "compiler-rt;libcxx;libcxxabi;lld", 37 "-DLLVM_INSTALL_TOOLCHAIN_ONLY=ON", 38 "-DLLVM_ENABLE_TERMINFO=OFF"]) 39 subprocess.check_call(["ninja", "install"]) 40 41 # Copy a couple extra files we need. 42 subprocess.check_call(["cp", "bin/llvm-symbolizer", target_dir + "/bin"]) 43 subprocess.check_call(["cp", "bin/llvm-profdata", target_dir + "/bin"]) 44 subprocess.check_call(["cp", "bin/llvm-cov", target_dir + "/bin"]) 45 libstdcpp = subprocess.check_output(["c++", 46 "-print-file-name=libstdc++.so.6"]) 47 subprocess.check_call(["cp", libstdcpp.strip(), target_dir + "/lib"]) 48 49 # Finally, build libc++ for TSAN and MSAN bots using the Clang we just built. 50 for (short,full) in [('tsan','Thread'), ('msan','MemoryWithOrigins')]: 51 os.mkdir("../{}_out".format(short)) 52 os.chdir("../{}_out".format(short)) 53 subprocess.check_call( 54 ["cmake", "../llvm", "-G", "Ninja", 55 "-DCMAKE_BUILD_TYPE=MinSizeRel", 56 "-DCMAKE_C_COMPILER=" + target_dir + "/bin/clang", 57 "-DCMAKE_CXX_COMPILER=" + target_dir + "/bin/clang++", 58 "-DLLVM_ENABLE_PROJECTS=libcxx;libcxxabi", 59 "-DLLVM_USE_SANITIZER={}".format(full)]) 60 subprocess.check_call(["ninja", "cxx"]) 61 subprocess.check_call(["cp", "-r", "lib", target_dir + "/" + short]) 62 63 64def main(): 65 parser = argparse.ArgumentParser() 66 parser.add_argument('--target_dir', '-t', required=True) 67 args = parser.parse_args() 68 create_asset(args.target_dir) 69 70 71if __name__ == '__main__': 72 main() 73