1 #!/usr/bin/env python 2 3 import argparse 4 import os 5 import os.path 6 import shutil 7 import subprocess 8 import sys 9 10 class BuildError(Exception): 11 def __init__(self, 12 string=None, 13 path=None, 14 inferior_error=None): 15 self.m_string = string 16 self.m_path = path 17 self.m_inferior_error = inferior_error 18 def __str__(self): 19 if self.m_path and self.m_string: 20 return "Build error: %s (referring to %s)" % (self.m_string, self.m_path) 21 if self.m_path: 22 return "Build error (referring to %s)" % (self.m_path) 23 if self.m_string: 24 return "Build error: %s" % (self.m_string) 25 return "Build error" 26 27 class LLDBBuildBot: 28 def __init__(self, 29 build_directory_path, 30 log_path, 31 lldb_repository_url="http://llvm.org/svn/llvm-project/lldb/trunk", 32 llvm_repository_url="http://llvm.org/svn/llvm-project/llvm/trunk", 33 clang_repository_url="http://llvm.org/svn/llvm-project/cfe/trunk", 34 revision=None): 35 self.m_build_directory_path = os.path.abspath(build_directory_path) 36 self.m_log_path = os.path.abspath(log_path) 37 self.m_lldb_repository_url = lldb_repository_url 38 self.m_llvm_repository_url = llvm_repository_url 39 self.m_clang_repository_url = clang_repository_url 40 self.m_revision = revision 41 self.m_log_stream = None 42 def Setup(self): 43 if os.path.exists(self.m_build_directory_path): 44 raise BuildError(string="Build directory exists", path=self.m_build_directory_path) 45 if os.path.exists(self.m_log_path): 46 raise BuildError(string="Log file exists", path=self.m_log_path) 47 self.m_log_stream = open(self.m_log_path, 'w') 48 os.mkdir(self.m_build_directory_path) 49 def Checkout(self): 50 os.chdir(self.m_build_directory_path) 51 52 cmdline_prefix = [] 53 54 if self.m_revision != None: 55 cmdline_prefix = ["svn", "-r %s" % (self.m_revision), "co"] 56 else: 57 cmdline_prefix = ["svn", "co"] 58 59 returncode = subprocess.call(cmdline_prefix + [self.m_lldb_repository_url, "lldb"], 60 stdout=self.m_log_stream, 61 stderr=self.m_log_stream) 62 if returncode != 0: 63 raise BuildError(string="Couldn't checkout LLDB") 64 65 os.chdir("lldb") 66 67 returncode = subprocess.call(cmdline_prefix + [self.m_llvm_repository_url, "llvm.checkout"], 68 stdout=self.m_log_stream, 69 stderr=self.m_log_stream) 70 71 if returncode != 0: 72 raise BuildError(string="Couldn't checkout LLVM") 73 74 os.symlink("llvm.checkout", "llvm") 75 76 os.chdir("llvm/tools") 77 78 returncode = subprocess.call(cmdline_prefix + [self.m_clang_repository_url, "clang"], 79 stdout=self.m_log_stream, 80 stderr=self.m_log_stream) 81 82 if returncode != 0: 83 raise BuildError(string="Couldn't checkout Clang") 84 def Build(self): 85 os.chdir(self.m_build_directory_path) 86 os.chdir("lldb/llvm") 87 88 returncode = subprocess.call(["./configure", "--disable-optimized", "--enable-assertions", "--enable-targets=x86,x86_64,arm"], 89 stdout=self.m_log_stream, 90 stderr=self.m_log_stream) 91 92 if returncode != 0: 93 raise BuildError(string="Couldn't configure LLVM/Clang") 94 95 returncode = subprocess.call(["make"], 96 stdout=self.m_log_stream, 97 stderr=self.m_log_stream) 98 99 if returncode != 0: 100 raise BuildError(string="Couldn't build LLVM/Clang") 101 102 os.chdir(self.m_build_directory_path) 103 os.chdir("lldb") 104 105 returncode = subprocess.call(["xcodebuild", 106 "-project", "lldb.xcodeproj", 107 "-target", "lldb-tool", 108 "-configuration", "Debug", 109 "-arch", "x86_64", 110 "LLVM_CONFIGURATION=Debug+Asserts", 111 "OBJROOT=build"], 112 stdout=self.m_log_stream, 113 stderr=self.m_log_stream) 114 115 if returncode != 0: 116 raise BuildError(string="Couldn't build LLDB") 117 def Test(self): 118 os.chdir(self.m_build_directory_path) 119 os.chdir("lldb/test") 120 121 returncode = subprocess.call(["./dotest.py", "-t"], 122 stdout=self.m_log_stream, 123 stderr=self.m_log_stream) 124 def Takedown(self): 125 os.chdir("/tmp") 126 self.m_log_stream.close() 127 shutil.rmtree(self.m_build_directory_path) 128 def Run(self): 129 self.Setup() 130 self.Checkout() 131 self.Build() 132 #self.Test() 133 self.Takedown() 134 135 def GetArgParser(): 136 parser = argparse.ArgumentParser(description="Try to build LLDB/LLVM/Clang and run the full test suite.") 137 parser.add_argument("--build-path", "-b", required=True, help="A (nonexistent) path to put temporary build products into", metavar="path") 138 parser.add_argument("--log-file", "-l", required=True, help="The name of a (nonexistent) log file", metavar="file") 139 parser.add_argument("--revision", "-r", required=False, help="The LLVM revision to use", metavar="N") 140 return parser 141 142 parser = GetArgParser() 143 arg_dict = vars(parser.parse_args()) 144 145 build_bot = LLDBBuildBot(build_directory_path=arg_dict["build_path"], 146 log_path=arg_dict["log_file"], 147 revision=arg_dict["revision"]) 148 149 try: 150 build_bot.Run() 151 except BuildError as err: 152 print err 153