| #!/usr/bin/env python | 
 |  | 
 | import argparse | 
 | import os | 
 | import os.path | 
 | import shutil | 
 | import subprocess | 
 | import sys | 
 |  | 
 |  | 
 | class BuildError(Exception): | 
 |  | 
 |     def __init__(self, | 
 |                  string=None, | 
 |                  path=None, | 
 |                  inferior_error=None): | 
 |         self.m_string = string | 
 |         self.m_path = path | 
 |         self.m_inferior_error = inferior_error | 
 |  | 
 |     def __str__(self): | 
 |         if self.m_path and self.m_string: | 
 |             return "Build error: %s (referring to %s)" % ( | 
 |                 self.m_string, self.m_path) | 
 |         if self.m_path: | 
 |             return "Build error (referring to %s)" % (self.m_path) | 
 |         if self.m_string: | 
 |             return "Build error: %s" % (self.m_string) | 
 |         return "Build error" | 
 |  | 
 |  | 
 | class LLDBBuildBot: | 
 |  | 
 |     def __init__( | 
 |             self, | 
 |             build_directory_path, | 
 |             log_path, | 
 |             lldb_repository_url="http://llvm.org/svn/llvm-project/lldb/trunk", | 
 |             llvm_repository_url="http://llvm.org/svn/llvm-project/llvm/trunk", | 
 |             clang_repository_url="http://llvm.org/svn/llvm-project/cfe/trunk", | 
 |             revision=None): | 
 |         self.m_build_directory_path = os.path.abspath(build_directory_path) | 
 |         self.m_log_path = os.path.abspath(log_path) | 
 |         self.m_lldb_repository_url = lldb_repository_url | 
 |         self.m_llvm_repository_url = llvm_repository_url | 
 |         self.m_clang_repository_url = clang_repository_url | 
 |         self.m_revision = revision | 
 |         self.m_log_stream = None | 
 |  | 
 |     def Setup(self): | 
 |         if os.path.exists(self.m_build_directory_path): | 
 |             raise BuildError( | 
 |                 string="Build directory exists", | 
 |                 path=self.m_build_directory_path) | 
 |         if os.path.exists(self.m_log_path): | 
 |             raise BuildError(string="Log file exists", path=self.m_log_path) | 
 |         self.m_log_stream = open(self.m_log_path, 'w') | 
 |         os.mkdir(self.m_build_directory_path) | 
 |  | 
 |     def Checkout(self): | 
 |         os.chdir(self.m_build_directory_path) | 
 |  | 
 |         cmdline_prefix = [] | 
 |  | 
 |         if self.m_revision is not None: | 
 |             cmdline_prefix = ["svn", "-r %s" % (self.m_revision), "co"] | 
 |         else: | 
 |             cmdline_prefix = ["svn", "co"] | 
 |  | 
 |         returncode = subprocess.call( | 
 |             cmdline_prefix + [ | 
 |                 self.m_lldb_repository_url, | 
 |                 "lldb"], | 
 |             stdout=self.m_log_stream, | 
 |             stderr=self.m_log_stream) | 
 |         if returncode != 0: | 
 |             raise BuildError(string="Couldn't checkout LLDB") | 
 |  | 
 |         os.chdir("lldb") | 
 |  | 
 |         returncode = subprocess.call( | 
 |             cmdline_prefix + [ | 
 |                 self.m_llvm_repository_url, | 
 |                 "llvm.checkout"], | 
 |             stdout=self.m_log_stream, | 
 |             stderr=self.m_log_stream) | 
 |  | 
 |         if returncode != 0: | 
 |             raise BuildError(string="Couldn't checkout LLVM") | 
 |  | 
 |         os.symlink("llvm.checkout", "llvm") | 
 |  | 
 |         os.chdir("llvm/tools") | 
 |  | 
 |         returncode = subprocess.call( | 
 |             cmdline_prefix + [ | 
 |                 self.m_clang_repository_url, | 
 |                 "clang"], | 
 |             stdout=self.m_log_stream, | 
 |             stderr=self.m_log_stream) | 
 |  | 
 |         if returncode != 0: | 
 |             raise BuildError(string="Couldn't checkout Clang") | 
 |  | 
 |     def Build(self): | 
 |         os.chdir(self.m_build_directory_path) | 
 |         os.chdir("lldb/llvm") | 
 |  | 
 |         returncode = subprocess.call(["./configure", | 
 |                                       "--disable-optimized", | 
 |                                       "--enable-assertions", | 
 |                                       "--enable-targets=x86,x86_64,arm"], | 
 |                                      stdout=self.m_log_stream, | 
 |                                      stderr=self.m_log_stream) | 
 |  | 
 |         if returncode != 0: | 
 |             raise BuildError(string="Couldn't configure LLVM/Clang") | 
 |  | 
 |         returncode = subprocess.call(["make"], | 
 |                                      stdout=self.m_log_stream, | 
 |                                      stderr=self.m_log_stream) | 
 |  | 
 |         if returncode != 0: | 
 |             raise BuildError(string="Couldn't build LLVM/Clang") | 
 |  | 
 |         os.chdir(self.m_build_directory_path) | 
 |         os.chdir("lldb") | 
 |  | 
 |         returncode = subprocess.call(["xcodebuild", | 
 |                                       "-project", "lldb.xcodeproj", | 
 |                                       "-target", "lldb-tool", | 
 |                                       "-configuration", "Debug", | 
 |                                       "-arch", "x86_64", | 
 |                                       "LLVM_CONFIGURATION=Debug+Asserts", | 
 |                                       "OBJROOT=build"], | 
 |                                      stdout=self.m_log_stream, | 
 |                                      stderr=self.m_log_stream) | 
 |  | 
 |         if returncode != 0: | 
 |             raise BuildError(string="Couldn't build LLDB") | 
 |  | 
 |     def Test(self): | 
 |         os.chdir(self.m_build_directory_path) | 
 |         os.chdir("lldb/test") | 
 |  | 
 |         returncode = subprocess.call(["./dotest.py", "-t"], | 
 |                                      stdout=self.m_log_stream, | 
 |                                      stderr=self.m_log_stream) | 
 |  | 
 |     def Takedown(self): | 
 |         os.chdir("/tmp") | 
 |         self.m_log_stream.close() | 
 |         shutil.rmtree(self.m_build_directory_path) | 
 |  | 
 |     def Run(self): | 
 |         self.Setup() | 
 |         self.Checkout() | 
 |         self.Build() | 
 |         # self.Test() | 
 |         self.Takedown() | 
 |  | 
 |  | 
 | def GetArgParser(): | 
 |     parser = argparse.ArgumentParser( | 
 |         description="Try to build LLDB/LLVM/Clang and run the full test suite.") | 
 |     parser.add_argument( | 
 |         "--build-path", | 
 |         "-b", | 
 |         required=True, | 
 |         help="A (nonexistent) path to put temporary build products into", | 
 |         metavar="path") | 
 |     parser.add_argument( | 
 |         "--log-file", | 
 |         "-l", | 
 |         required=True, | 
 |         help="The name of a (nonexistent) log file", | 
 |         metavar="file") | 
 |     parser.add_argument( | 
 |         "--revision", | 
 |         "-r", | 
 |         required=False, | 
 |         help="The LLVM revision to use", | 
 |         metavar="N") | 
 |     return parser | 
 |  | 
 | parser = GetArgParser() | 
 | arg_dict = vars(parser.parse_args()) | 
 |  | 
 | build_bot = LLDBBuildBot(build_directory_path=arg_dict["build_path"], | 
 |                          log_path=arg_dict["log_file"], | 
 |                          revision=arg_dict["revision"]) | 
 |  | 
 | try: | 
 |     build_bot.Run() | 
 | except BuildError as err: | 
 |     print err |