1be691f3bSpatrickimport os 2be691f3bSpatrickimport platform 3be691f3bSpatrickimport subprocess 4be691f3bSpatrickimport sys 5*f6aab3d8Srobertimport itertools 6be691f3bSpatrick 7be691f3bSpatrickimport lldbsuite.test.lldbtest as lldbtest 8be691f3bSpatrickimport lldbsuite.test.lldbutil as lldbutil 9be691f3bSpatrickfrom lldbsuite.test import configuration 10be691f3bSpatrickfrom lldbsuite.test_event import build_exception 11be691f3bSpatrick 12be691f3bSpatrick 13be691f3bSpatrickclass Builder: 14be691f3bSpatrick def getArchitecture(self): 15be691f3bSpatrick """Returns the architecture in effect the test suite is running with.""" 16be691f3bSpatrick return configuration.arch if configuration.arch else "" 17be691f3bSpatrick 18be691f3bSpatrick def getCompiler(self): 19be691f3bSpatrick """Returns the compiler in effect the test suite is running with.""" 20be691f3bSpatrick compiler = configuration.compiler if configuration.compiler else "clang" 21be691f3bSpatrick compiler = lldbutil.which(compiler) 22be691f3bSpatrick return os.path.abspath(compiler) 23be691f3bSpatrick 24*f6aab3d8Srobert def getTriple(self, arch): 25*f6aab3d8Srobert """Returns the triple for the given architecture or None.""" 26*f6aab3d8Srobert return None 27*f6aab3d8Srobert 28be691f3bSpatrick def getExtraMakeArgs(self): 29be691f3bSpatrick """ 30be691f3bSpatrick Helper function to return extra argumentsfor the make system. This 31be691f3bSpatrick method is meant to be overridden by platform specific builders. 32be691f3bSpatrick """ 33*f6aab3d8Srobert return [] 34be691f3bSpatrick 35be691f3bSpatrick def getArchCFlags(self, architecture): 36be691f3bSpatrick """Returns the ARCH_CFLAGS for the make system.""" 37*f6aab3d8Srobert return [] 38be691f3bSpatrick 39be691f3bSpatrick def getMake(self, test_subdir, test_name): 40be691f3bSpatrick """Returns the invocation for GNU make. 41be691f3bSpatrick The first argument is a tuple of the relative path to the testcase 42be691f3bSpatrick and its filename stem.""" 43be691f3bSpatrick if platform.system() == "FreeBSD" or platform.system() == "NetBSD": 44be691f3bSpatrick make = "gmake" 45be691f3bSpatrick else: 46be691f3bSpatrick make = "make" 47be691f3bSpatrick 48be691f3bSpatrick # Construct the base make invocation. 49be691f3bSpatrick lldb_test = os.environ["LLDB_TEST"] 50be691f3bSpatrick if not (lldb_test and configuration.test_build_dir and test_subdir 51be691f3bSpatrick and test_name and (not os.path.isabs(test_subdir))): 52be691f3bSpatrick raise Exception("Could not derive test directories") 53be691f3bSpatrick build_dir = os.path.join(configuration.test_build_dir, test_subdir, 54be691f3bSpatrick test_name) 55be691f3bSpatrick src_dir = os.path.join(configuration.test_src_root, test_subdir) 56be691f3bSpatrick # This is a bit of a hack to make inline testcases work. 57be691f3bSpatrick makefile = os.path.join(src_dir, "Makefile") 58be691f3bSpatrick if not os.path.isfile(makefile): 59be691f3bSpatrick makefile = os.path.join(build_dir, "Makefile") 60be691f3bSpatrick return [ 61be691f3bSpatrick make, "VPATH=" + src_dir, "-C", build_dir, "-I", src_dir, "-I", 62be691f3bSpatrick os.path.join(lldb_test, "make"), "-f", makefile 63be691f3bSpatrick ] 64be691f3bSpatrick 65be691f3bSpatrick def getCmdLine(self, d): 66be691f3bSpatrick """ 67*f6aab3d8Srobert Helper function to return a command line argument string used for the 68*f6aab3d8Srobert make system. 69be691f3bSpatrick """ 70be691f3bSpatrick 71*f6aab3d8Srobert # If d is None or an empty mapping, just return an empty list. 72be691f3bSpatrick if not d: 73*f6aab3d8Srobert return [] 74be691f3bSpatrick 75be691f3bSpatrick def setOrAppendVariable(k, v): 76be691f3bSpatrick append_vars = ["CFLAGS", "CFLAGS_EXTRAS", "LD_EXTRAS"] 77be691f3bSpatrick if k in append_vars and k in os.environ: 78be691f3bSpatrick v = os.environ[k] + " " + v 79*f6aab3d8Srobert return '%s=%s' % (k, v) 80be691f3bSpatrick 81*f6aab3d8Srobert cmdline = [setOrAppendVariable(k, v) for k, v in list(d.items())] 82be691f3bSpatrick 83be691f3bSpatrick return cmdline 84be691f3bSpatrick 85be691f3bSpatrick def getArchSpec(self, architecture): 86be691f3bSpatrick """ 87be691f3bSpatrick Helper function to return the key-value string to specify the architecture 88be691f3bSpatrick used for the make system. 89be691f3bSpatrick """ 90*f6aab3d8Srobert return ["ARCH=" + architecture] if architecture else [] 91be691f3bSpatrick 92be691f3bSpatrick def getCCSpec(self, compiler): 93be691f3bSpatrick """ 94be691f3bSpatrick Helper function to return the key-value string to specify the compiler 95be691f3bSpatrick used for the make system. 96be691f3bSpatrick """ 97be691f3bSpatrick cc = compiler if compiler else None 98be691f3bSpatrick if not cc and configuration.compiler: 99be691f3bSpatrick cc = configuration.compiler 100be691f3bSpatrick if cc: 101*f6aab3d8Srobert return ["CC=\"%s\"" % cc] 102*f6aab3d8Srobert return [] 103be691f3bSpatrick 104be691f3bSpatrick def getSDKRootSpec(self): 105be691f3bSpatrick """ 106be691f3bSpatrick Helper function to return the key-value string to specify the SDK root 107be691f3bSpatrick used for the make system. 108be691f3bSpatrick """ 109be691f3bSpatrick if configuration.sdkroot: 110*f6aab3d8Srobert return ["SDKROOT={}".format(configuration.sdkroot)] 111*f6aab3d8Srobert return [] 112be691f3bSpatrick 113be691f3bSpatrick def getModuleCacheSpec(self): 114be691f3bSpatrick """ 115be691f3bSpatrick Helper function to return the key-value string to specify the clang 116be691f3bSpatrick module cache used for the make system. 117be691f3bSpatrick """ 118be691f3bSpatrick if configuration.clang_module_cache_dir: 119*f6aab3d8Srobert return ["CLANG_MODULE_CACHE_DIR={}".format( 120*f6aab3d8Srobert configuration.clang_module_cache_dir)] 121*f6aab3d8Srobert return [] 122be691f3bSpatrick 123*f6aab3d8Srobert def getLibCxxArgs(self): 124*f6aab3d8Srobert if configuration.libcxx_include_dir and configuration.libcxx_library_dir: 125*f6aab3d8Srobert libcpp_args = ["LIBCPP_INCLUDE_DIR={}".format(configuration.libcxx_include_dir), 126*f6aab3d8Srobert "LIBCPP_LIBRARY_DIR={}".format(configuration.libcxx_library_dir)] 127*f6aab3d8Srobert if configuration.libcxx_include_target_dir: 128*f6aab3d8Srobert libcpp_args.append("LIBCPP_INCLUDE_TARGET_DIR={}".format( 129*f6aab3d8Srobert configuration.libcxx_include_target_dir)) 130*f6aab3d8Srobert return libcpp_args 131*f6aab3d8Srobert return [] 132be691f3bSpatrick 133*f6aab3d8Srobert def _getDebugInfoArgs(self, debug_info): 134*f6aab3d8Srobert if debug_info is None: 135*f6aab3d8Srobert return [] 136*f6aab3d8Srobert if debug_info == "dwarf": 137*f6aab3d8Srobert return ["MAKE_DSYM=NO"] 138*f6aab3d8Srobert if debug_info == "dwo": 139*f6aab3d8Srobert return ["MAKE_DSYM=NO", "MAKE_DWO=YES"] 140*f6aab3d8Srobert if debug_info == "gmodules": 141*f6aab3d8Srobert return ["MAKE_DSYM=NO", "MAKE_GMODULES=YES"] 142*f6aab3d8Srobert return None 143be691f3bSpatrick 144*f6aab3d8Srobert def getBuildCommand(self, debug_info, architecture=None, compiler=None, 145*f6aab3d8Srobert dictionary=None, testdir=None, testname=None, make_targets=None): 146*f6aab3d8Srobert debug_info_args = self._getDebugInfoArgs(debug_info) 147*f6aab3d8Srobert if debug_info_args is None: 148*f6aab3d8Srobert return None 149*f6aab3d8Srobert if make_targets is None: 150*f6aab3d8Srobert make_targets = ["all"] 151*f6aab3d8Srobert command_parts = [ 152*f6aab3d8Srobert self.getMake(testdir, testname), debug_info_args, make_targets, 153*f6aab3d8Srobert self.getArchCFlags(architecture), self.getArchSpec(architecture), 154*f6aab3d8Srobert self.getCCSpec(compiler), self.getExtraMakeArgs(), 155*f6aab3d8Srobert self.getSDKRootSpec(), self.getModuleCacheSpec(), 156*f6aab3d8Srobert self.getLibCxxArgs(), self.getCmdLine(dictionary)] 157*f6aab3d8Srobert command = list(itertools.chain(*command_parts)) 158be691f3bSpatrick 159*f6aab3d8Srobert return command 160be691f3bSpatrick 161*f6aab3d8Srobert def cleanup(self, dictionary=None): 162be691f3bSpatrick """Perform a platform-specific cleanup after the test.""" 163be691f3bSpatrick return True 164