blob: 823a982e6743806dcafd2cedb2a65271f896d9f7 [file] [log] [blame]
import os
import platform
import subprocess
import sys
import itertools
import lldbsuite.test.lldbtest as lldbtest
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import configuration
from lldbsuite.test_event import build_exception
class Builder:
def getArchitecture(self):
"""Returns the architecture in effect the test suite is running with."""
return configuration.arch if configuration.arch else ""
def getCompiler(self):
"""Returns the compiler in effect the test suite is running with."""
compiler = configuration.compiler if configuration.compiler else "clang"
compiler = lldbutil.which(compiler)
return os.path.abspath(compiler)
def getTriple(self, arch):
"""Returns the triple for the given architecture or None."""
return None
def getExtraMakeArgs(self):
"""
Helper function to return extra argumentsfor the make system. This
method is meant to be overridden by platform specific builders.
"""
return []
def getArchCFlags(self, architecture):
"""Returns the ARCH_CFLAGS for the make system."""
return []
def getMake(self, test_subdir, test_name):
"""Returns the invocation for GNU make.
The first argument is a tuple of the relative path to the testcase
and its filename stem."""
if platform.system() == "FreeBSD" or platform.system() == "NetBSD":
make = "gmake"
else:
make = "make"
# Construct the base make invocation.
lldb_test = os.environ["LLDB_TEST"]
if not (
lldb_test
and configuration.test_build_dir
and test_subdir
and test_name
and (not os.path.isabs(test_subdir))
):
raise Exception("Could not derive test directories")
build_dir = os.path.join(configuration.test_build_dir, test_subdir, test_name)
src_dir = os.path.join(configuration.test_src_root, test_subdir)
# This is a bit of a hack to make inline testcases work.
makefile = os.path.join(src_dir, "Makefile")
if not os.path.isfile(makefile):
makefile = os.path.join(build_dir, "Makefile")
return [
make,
"VPATH=" + src_dir,
"-C",
build_dir,
"-I",
src_dir,
"-I",
os.path.join(lldb_test, "make"),
"-f",
makefile,
]
def getCmdLine(self, d):
"""
Helper function to return a command line argument string used for the
make system.
"""
# If d is None or an empty mapping, just return an empty list.
if not d:
return []
def setOrAppendVariable(k, v):
append_vars = ["CFLAGS", "CFLAGS_EXTRAS", "LD_EXTRAS"]
if k in append_vars and k in os.environ:
v = os.environ[k] + " " + v
return "%s=%s" % (k, v)
cmdline = [setOrAppendVariable(k, v) for k, v in list(d.items())]
return cmdline
def getArchSpec(self, architecture):
"""
Helper function to return the key-value string to specify the architecture
used for the make system.
"""
return ["ARCH=" + architecture] if architecture else []
def getCCSpec(self, compiler):
"""
Helper function to return the key-value string to specify the compiler
used for the make system.
"""
cc = compiler if compiler else None
if not cc and configuration.compiler:
cc = configuration.compiler
if cc:
return ['CC="%s"' % cc]
return []
def getSDKRootSpec(self):
"""
Helper function to return the key-value string to specify the SDK root
used for the make system.
"""
if configuration.sdkroot:
return ["SDKROOT={}".format(configuration.sdkroot)]
return []
def getModuleCacheSpec(self):
"""
Helper function to return the key-value string to specify the clang
module cache used for the make system.
"""
if configuration.clang_module_cache_dir:
return [
"CLANG_MODULE_CACHE_DIR={}".format(configuration.clang_module_cache_dir)
]
return []
def getLibCxxArgs(self):
if configuration.libcxx_include_dir and configuration.libcxx_library_dir:
libcpp_args = [
"LIBCPP_INCLUDE_DIR={}".format(configuration.libcxx_include_dir),
"LIBCPP_LIBRARY_DIR={}".format(configuration.libcxx_library_dir),
]
if configuration.libcxx_include_target_dir:
libcpp_args.append(
"LIBCPP_INCLUDE_TARGET_DIR={}".format(
configuration.libcxx_include_target_dir
)
)
return libcpp_args
return []
def _getDebugInfoArgs(self, debug_info):
if debug_info is None:
return []
if debug_info == "dwarf":
return ["MAKE_DSYM=NO"]
if debug_info == "dwo":
return ["MAKE_DSYM=NO", "MAKE_DWO=YES"]
if debug_info == "gmodules":
return ["MAKE_DSYM=NO", "MAKE_GMODULES=YES"]
return None
def getBuildCommand(
self,
debug_info,
architecture=None,
compiler=None,
dictionary=None,
testdir=None,
testname=None,
make_targets=None,
):
debug_info_args = self._getDebugInfoArgs(debug_info)
if debug_info_args is None:
return None
if make_targets is None:
make_targets = ["all"]
command_parts = [
self.getMake(testdir, testname),
debug_info_args,
make_targets,
self.getArchCFlags(architecture),
self.getArchSpec(architecture),
self.getCCSpec(compiler),
self.getExtraMakeArgs(),
self.getSDKRootSpec(),
self.getModuleCacheSpec(),
self.getLibCxxArgs(),
self.getCmdLine(dictionary),
]
command = list(itertools.chain(*command_parts))
return command
def cleanup(self, dictionary=None):
"""Perform a platform-specific cleanup after the test."""
return True