Sean Callanan | 10babe1 | 2011-10-14 21:43:51 +0000 | [diff] [blame] | 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 |