Home | History | Annotate | Download | only in scripts
      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