# Copyright 2018 Google, Inc. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer; # redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution; # neither the name of the copyright holders nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Gabe Black from __future__ import print_function Import('*') if env['USE_SYSTEMC']: from gem5_scons import Transform import os.path import json src = str(Dir('.').srcdir) class SystemCTest(object): def __init__(self, dirname, name): self.name = name self.reldir = os.path.relpath(dirname, src) self.target = os.path.join(self.reldir, name) self.sources = [] self.compile_only = False def add_source(self, source): self.sources.append(os.path.join(self.reldir, source)) def add_sources(self, sources): for source in sources: self.sources.append(os.path.join(self.reldir, '..', source)) def properties(self): return { 'name' : self.name, 'path' : self.reldir, 'compile_only' : self.compile_only } ext_dir = Dir('..').Dir('ext') class SystemCTestBin(Executable): def __init__(self, test): super(SystemCTestBin, self).__init__(test.target, *test.sources) @classmethod def declare_all(cls, env): env = env.Clone() # Turn off extra warnings and Werror for the tests. to_remove = ['-Wall', '-Wundef', '-Wextra', '-Werror'] env['CCFLAGS'] = \ filter(lambda f: f not in to_remove, env['CCFLAGS']) env.Append(CPPPATH=ext_dir) super(SystemCTestBin, cls).declare_all(env) def declare(self, env): sources = list(self.sources) for f in self.filters: sources = Source.all.apply_filter(f) objs = self.srcs_to_objs(env, sources) objs = objs + env['SHARED_LIB'] + env['MAIN_OBJS'] return super(SystemCTestBin, self).declare(env, objs) tests = [] def new_test(dirname, name): test = SystemCTest(dirname, name) tests.append(test) return test def scan_dir_for_tests(subdir): def visitor(arg, dirname, names): # If there's a 'DONTRUN' file in this directory, skip it and any # child directories. if 'DONTRUN' in names: del names[:] return endswith = lambda sfx: filter(lambda n: n.endswith(sfx), names) cpps = endswith('.cpp') if not cpps: return # If there's only one source file, then that files name is the test # name, and it's the source for that test. if len(cpps) == 1: cpp = cpps[0] test = new_test(dirname, os.path.splitext(cpp)[0]) test.add_source(cpp) # Otherwise, expect there to be a file that ends in .f. That files # name is the test name, and it will list the source files with # one preceeding path component. else: fs = endswith('.f') if len(fs) != 1: print("In %s, expected 1 *.f file, but found %d.", dirname, len(fs)) for f in fs: print(os.path.join(dirname, f)) return f = fs[0] test = new_test(dirname, os.path.splitext(f)[0]) with open(os.path.join(dirname, f)) as content: lines = content.readlines # Get rid of leading and trailing whitespace. lines = map(lambda x: x.strip(), content.readlines()) # Get rid of blank lines. lines = filter(lambda x: x, lines) # Add all the sources to this test. test.add_sources(lines) if 'COMPILE' in names: test.compile_only = True subdir_src = Dir('.').srcdir.Dir(subdir) os.path.walk(str(subdir_src), visitor, None) scan_dir_for_tests('systemc') def build_tests_json(target, source, env): data = { test.target : test.properties() for test in tests } with open(str(target[0]), "w") as tests_json: json.dump(data, tests_json) AlwaysBuild(env.Command(File('tests.json'), None, MakeAction(build_tests_json, Transform("TESTJSON")))) for test in tests: SystemCTestBin(test)