Skip to content
This repository has been archived by the owner on Aug 22, 2019. It is now read-only.

Commit

Permalink
Add libs file for recording library dependencies of unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
anatol1234 committed Dec 20, 2017
1 parent 6e11cbc commit fe08914
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 56 deletions.
37 changes: 22 additions & 15 deletions mx.sulong/mx_sulong.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,15 @@

def _unittest_config_participant(config):
(vmArgs, mainClass, mainClassArgs) = config
libs = [mx_subst.path_substitutions.substitute('<path:SULONG_TEST_NATIVE>/<lib:sulongtest>')]
rustStd = findRustLibrary('std', on_failure=lambda msg: None)
if rustStd is not None:
libs.append(rustStd)
vmArgs = getCommonOptions(True, libs) + vmArgs
libs = ['<path:SULONG_TEST_NATIVE>/<lib:sulongtest>']
(testSuitePath,), _ = extract_arg_values(vmArgs, '-Dsulongtest.testSuitePath')

# gather library dependencies
for libs_file in glob.glob(os.path.join(testSuitePath, '*', 'libs')):
with open(libs_file, 'r') as l:
libs += l.readline().split()

vmArgs = getCommonOptions(True, [mx_subst.path_substitutions.substitute(lib) for lib in libs]) + vmArgs
return (vmArgs, mainClass, mainClassArgs)

add_config_participant(_unittest_config_participant)
Expand Down Expand Up @@ -366,6 +370,15 @@ def extract_compiler_args(args, useDoubleDash=False):
remainder += [arg]
return compilerArgs, remainder

def extract_arg_values(vmArgs, argKey):
values, remainder = [], []
for arg in vmArgs:
if arg.startswith(argKey + '='):
values += arg[(len(argKey)+1):].split(':')
else:
remainder += [arg]
return values, remainder

def runLLVM(args=None, out=None):
"""uses Sulong to execute a LLVM IR file"""
vmArgs, sulongArgs = truffle_extract_VM_args(args)
Expand All @@ -388,15 +401,9 @@ def getCommonOptions(withAssertion, lib_args=None):
return options

def substituteLibAliases(vmArgs):
librariesOption = '-Dpolyglot.llvm.libraries='
substitutedVmArgs = []
lib_args = None
for vmArg in vmArgs:
if vmArg.startswith(librariesOption):
lib_args = vmArg[len(librariesOption):].split(':')
else:
substitutedVmArgs.append(vmArg)
if lib_args is None:
librariesOption = '-Dpolyglot.llvm.libraries'
lib_args, substitutedVmArgs = extract_arg_values(vmArgs, librariesOption)
if len(lib_args) == 0:
return vmArgs

lib_aliases = {
Expand All @@ -414,7 +421,7 @@ def substituteLibAliases(vmArgs):
lib_arg = lib_arg.replace('*', match.group(1))
lib_arg = mx_subst.path_substitutions.substitute(lib_arg)
resolved_lib_args.append(lib_arg)
substitutedVmArgs.append(librariesOption + ':'.join(resolved_lib_args))
substitutedVmArgs.append(librariesOption + '=' + ':'.join(resolved_lib_args))

return substitutedVmArgs

Expand Down
101 changes: 61 additions & 40 deletions mx.sulong/mx_testsuites.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,54 +256,71 @@ def renameBenchmarkFiles(directory):

mx_subst.path_substitutions.register_no_arg('sulong_include', lambda: os.path.join(mx.suite('sulong').dir, 'include'))

def cached(meth):
cached_attr = '_cached_' + meth.__name__
def _cached_meth(self):
if not hasattr(self, cached_attr):
setattr(self, cached_attr, meth(self))
return getattr(self, cached_attr)
return _cached_meth

class Dependency(object):
def __init__(self, isFulfilled):
self._isFulfilled = isFulfilled

@cached
def isFulfilled(self):
return self._isFulfilled()

Dependency.RUST = Dependency(lambda: mx_sulong.checkRust()) # pylint: disable=W0108
Dependency.DRAGONEGG = Dependency(lambda: mx_sulong.dragonEggPath() is not None and os.path.exists(mx_sulong.dragonEggPath()) and mx_sulong.getGCC(optional=True) is not None)

class SulongTestSuite(mx.NativeProject):
def __init__(self, suite, name, deps, workingSets, subDir, results=None, output=None, buildRef=True, **args):
def __init__(self, suite, name, deps, workingSets, subDir, results=None, output=None, buildRef=True, libraries=(), **args):
d = os.path.join(suite.dir, subDir) # use common Makefile for all test suites
mx.NativeProject.__init__(self, suite, name, subDir, [], deps, workingSets, results, output, d, **args)
self.vpath = True
self.buildRef = buildRef
self.libraries = libraries

@staticmethod
def haveDragonegg():
if not hasattr(SulongTestSuite, '_haveDragonegg'):
SulongTestSuite._haveDragonegg = mx_sulong.dragonEggPath() is not None and os.path.exists(mx_sulong.dragonEggPath()) and mx_sulong.getGCC(optional=True) is not None
return SulongTestSuite._haveDragonegg

@staticmethod
def haveRust():
if not hasattr(SulongTestSuite, '_haveRust'):
SulongTestSuite._haveRust = mx_sulong.checkRust()
return SulongTestSuite._haveRust

@cached
def getTests(self):
if not hasattr(self, '_tests'):
self._tests = []
extensions = ['.c', '.cpp', '.rs']
root = os.path.join(self.dir, self.name)
for path, _, files in os.walk(root):
for f in files:
absPath = os.path.join(path, f)
relPath = os.path.relpath(absPath, root)
test, ext = os.path.splitext(relPath)
if ext in extensions:
if ext == '.rs' and not SulongTestSuite.haveRust():
mx.warn('Rust is not available, not building Rust test files')
extensions.remove('.rs')
continue
self._tests.append(test)
return self._tests

tests = []
extensions = ['.c', '.cpp', '.rs']
root = os.path.join(self.dir, self.name)
for path, _, files in os.walk(root):
for f in files:
absPath = os.path.join(path, f)
relPath = os.path.relpath(absPath, root)
test, ext = os.path.splitext(relPath)
if ext in extensions:
if ext == '.rs' and not Dependency.RUST.isFulfilled():
mx.warn('Rust is not available, not building Rust test files')
extensions.remove('.rs')
continue
tests.append(test)
return tests

@cached
def getVariants(self):
if not hasattr(self, '_variants'):
self._variants = []
for v in self.variants:
if 'gcc' in v and not SulongTestSuite.haveDragonegg():
mx.warn('Could not find dragonegg, not building test variant "%s"' % v)
continue
self._variants.append(v)
return self._variants

variants = []
for v in self.variants:
if 'gcc' in v and not Dependency.DRAGONEGG.isFulfilled():
mx.warn('Could not find dragonegg, not building test variant "%s"' % v)
continue
variants.append(v)
return variants

@cached
def getLibEntries(self):
return [lib['lib'] for lib in self.libraries if all(getattr(Dependency, dep).isFulfilled() for dep in lib['dependencies'])]

@cached
def getLibsLocations(self):
if self.getLibEntries():
root = os.path.join(self.dir, self.name)
return [subdir for subdir in os.listdir(root) if os.path.isdir(os.path.join(root, subdir))]
return []

def getBuildEnv(self, replaceVar=mx_subst.path_substitutions):
env = super(SulongTestSuite, self).getBuildEnv(replaceVar=replaceVar)
Expand All @@ -312,8 +329,10 @@ def getBuildEnv(self, replaceVar=mx_subst.path_substitutions):
env['TESTS'] = ' '.join(self.getTests())
env['VARIANTS'] = ' '.join(self.getVariants())
env['BUILD_REF'] = '1' if self.buildRef else '0'
env['LIBS_LOCATIONS'] = ' '.join(self.getLibsLocations())
env['LIB_ENTRIES'] = ' '.join(self.getLibEntries())
env['SULONG_MAKE_CLANG_IMPLICIT_ARGS'] = mx_sulong.getClangImplicitArgs()
if SulongTestSuite.haveDragonegg():
if Dependency.DRAGONEGG.isFulfilled():
env['DRAGONEGG'] = mx_sulong.dragonEggPath()
env['DRAGONEGG_GCC'] = mx_sulong.getGCC()
env['DRAGONEGG_LLVMAS'] = mx_sulong.findLLVMProgramForDragonegg("llvm-as")
Expand All @@ -327,4 +346,6 @@ def getResults(self, replaceVar=mx_subst.results_substitutions):
self.results.append(os.path.join(t, 'ref.out'))
for v in self.getVariants():
self.results.append(os.path.join(t, v + '.bc'))
for l in self.getLibsLocations():
self.results.append(os.path.join(l, 'libs'))
return super(SulongTestSuite, self).getResults(replaceVar=replaceVar)
3 changes: 3 additions & 0 deletions mx.sulong/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@
"subDir" : "tests",
"class" : "SulongTestSuite",
"variants" : ["O0"],
"libraries" : [
{"lib" : "<rustlib:std>", "dependencies" : ["RUST"]}
],
"buildEnv" : {
"OS" : "<os>",
},
Expand Down
8 changes: 7 additions & 1 deletion tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ endif

BC_TARGETS:=$(foreach var,$(VARIANTS),$(TESTS:%=%/$(var).bc))

LIBS_TARGETS:=$(LIBS_LOCATIONS:%=%/libs)

.PHONY: default
default: $(REF_TARGETS) $(BC_TARGETS)
default: $(REF_TARGETS) $(BC_TARGETS) $(LIBS_TARGETS)

ifeq ($(OS), darwin)
EMBED_BC=-fembed-bitcode
Expand Down Expand Up @@ -95,3 +97,7 @@ $(eval $(call OPT_RULES,O3,-O3))

%_MEM2REG.bc: %.bc
$(QUIETLY) opt -o $@ -mem2reg $<

%/libs:
@mkdir -p $(shell dirname $@)
@echo "$(LIB_ENTRIES)" > $@

0 comments on commit fe08914

Please sign in to comment.