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