blob: be891da2d08673e1ad9348e1c61bc9966a17a3d3 [file] [log] [blame]
"""
If the build* function is passed the compiler argument, for example, 'llvm-gcc',
it is passed as a make variable to the make command. Otherwise, we check the
LLDB_CC environment variable; if it is defined, it is passed as a make variable
to the make command.
If neither the compiler keyword argument nor the LLDB_CC environment variable is
specified, no CC make variable is passed to the make command. The Makefile gets
to define the default CC being used.
Same idea holds for LLDB_ARCH environment variable, which maps to the ARCH make
variable.
"""
# System imports
import os
import platform
import subprocess
import sys
# Our imports
import lldbsuite.test.lldbtest as lldbtest
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test_event import build_exception
def getArchitecture():
"""Returns the architecture in effect the test suite is running with."""
return os.environ["ARCH"] if "ARCH" in os.environ else ""
def getCompiler():
"""Returns the compiler in effect the test suite is running with."""
compiler = os.environ.get("CC", "clang")
compiler = lldbutil.which(compiler)
return os.path.realpath(compiler)
def getArchFlag():
"""Returns the flag required to specify the arch"""
compiler = getCompiler()
if compiler is None:
return ""
elif "gcc" in compiler:
archflag = "-m"
elif "clang" in compiler:
archflag = "-arch"
else:
archflag = None
return ("ARCHFLAG=" + archflag) if archflag else ""
def getMake(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"]
lldb_build = os.environ["LLDB_BUILD"]
if not (lldb_test and lldb_build 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(lldb_build, test_subdir, test_name)
src_dir = os.path.join(lldb_test, 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,
"-f", makefile]
def getArchSpec(architecture):
"""
Helper function to return the key-value string to specify the architecture
used for the make system.
"""
arch = architecture if architecture else None
if not arch and "ARCH" in os.environ:
arch = os.environ["ARCH"]
return ("ARCH=" + arch) if arch else ""
def getCCSpec(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 "CC" in os.environ:
cc = os.environ["CC"]
if cc:
return "CC=\"%s\"" % cc
else:
return ""
def getCmdLine(d):
"""
Helper function to return a properly formatted command line argument(s)
string used for the make system.
"""
# If d is None or an empty mapping, just return an empty string.
if not d:
return ""
pattern = '%s="%s"' if "win32" in sys.platform else "%s='%s'"
def setOrAppendVariable(k, v):
append_vars = ["CFLAGS_EXTRAS", "LD_EXTRAS"]
if k in append_vars and k in os.environ:
v = os.environ[k] + " " + v
return pattern % (k, v)
cmdline = " ".join([setOrAppendVariable(k, v) for k, v in list(d.items())])
return cmdline
def runBuildCommands(commands, sender):
try:
lldbtest.system(commands, sender=sender)
except subprocess.CalledProcessError as called_process_error:
# Convert to a build-specific error.
# We don't do that in lldbtest.system() since that
# is more general purpose.
raise build_exception.BuildError(called_process_error)
def buildDefault(
sender=None,
architecture=None,
compiler=None,
dictionary=None,
testdir=None,
testname=None):
"""Build the binaries the default way."""
commands = []
commands.append(getMake(testdir, testname) + ["all", getArchSpec(architecture),
getCCSpec(compiler), getCmdLine(dictionary)])
runBuildCommands(commands, sender=sender)
# True signifies that we can handle building default.
return True
def buildDwarf(
sender=None,
architecture=None,
compiler=None,
dictionary=None,
testdir=None,
testname=None):
"""Build the binaries with dwarf debug info."""
commands = []
commands.append(getMake(testdir, testname) +
["MAKE_DSYM=NO", getArchSpec(architecture),
getCCSpec(compiler), getCmdLine(dictionary)])
runBuildCommands(commands, sender=sender)
# True signifies that we can handle building dwarf.
return True
def buildDwo(
sender=None,
architecture=None,
compiler=None,
dictionary=None,
testdir=None,
testname=None):
"""Build the binaries with dwarf debug info."""
commands = []
commands.append(getMake(testdir, testname) +
["MAKE_DSYM=NO", "MAKE_DWO=YES",
getArchSpec(architecture),
getCCSpec(compiler),
getCmdLine(dictionary)])
runBuildCommands(commands, sender=sender)
# True signifies that we can handle building dwo.
return True
def buildGModules(
sender=None,
architecture=None,
compiler=None,
dictionary=None,
testdir=None,
testname=None):
"""Build the binaries with dwarf debug info."""
commands = []
commands.append(getMake(testdir, testname) +
["MAKE_DSYM=NO",
"MAKE_GMODULES=YES",
getArchSpec(architecture),
getCCSpec(compiler),
getCmdLine(dictionary)])
lldbtest.system(commands, sender=sender)
# True signifies that we can handle building with gmodules.
return True
def cleanup(sender=None, dictionary=None):
"""Perform a platform-specific cleanup after the test."""
return True