SConscript revision 13512
1955SN/A# Copyright 2018 Google, Inc. 2955SN/A# 31762SN/A# Redistribution and use in source and binary forms, with or without 4955SN/A# modification, are permitted provided that the following conditions are 5955SN/A# met: redistributions of source code must retain the above copyright 6955SN/A# notice, this list of conditions and the following disclaimer; 7955SN/A# redistributions in binary form must reproduce the above copyright 8955SN/A# notice, this list of conditions and the following disclaimer in the 9955SN/A# documentation and/or other materials provided with the distribution; 10955SN/A# neither the name of the copyright holders nor the names of its 11955SN/A# contributors may be used to endorse or promote products derived from 12955SN/A# this software without specific prior written permission. 13955SN/A# 14955SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15955SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17955SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18955SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19955SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20955SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22955SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24955SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25955SN/A# 26955SN/A# Authors: Gabe Black 27955SN/A 282665Ssaidi@eecs.umich.edufrom __future__ import print_function 292665Ssaidi@eecs.umich.edu 30955SN/AImport('*') 31955SN/A 32955SN/Aif env['USE_SYSTEMC']: 331608SN/A 34955SN/A from gem5_scons import Transform 35955SN/A 36955SN/A import os.path 37955SN/A import json 38955SN/A 39955SN/A src = str(Dir('.').srcdir) 40955SN/A 41955SN/A class SystemCTest(object): 42955SN/A def __init__(self, dirname, name): 43955SN/A self.name = name 44955SN/A self.reldir = os.path.relpath(dirname, src) 45955SN/A self.target = os.path.join(self.reldir, name) 46955SN/A self.sources = [] 47955SN/A self.deps = [] 482023SN/A 49955SN/A self.compile_only = False 50955SN/A 51955SN/A def add_source(self, source): 52955SN/A self.sources.append(os.path.join(self.reldir, source)) 53955SN/A 54955SN/A def add_sources(self, sources): 55955SN/A for source in sources: 56955SN/A self.sources.append(os.path.join(self.reldir, '..', source)) 57955SN/A 581031SN/A def properties(self): 59955SN/A return { 601388SN/A 'name' : self.name, 61955SN/A 'path' : self.reldir, 62955SN/A 'compile_only' : self.compile_only, 631296SN/A 'deps' : self.deps 64955SN/A } 652609SN/A 66955SN/A test_dir = Dir('.') 67955SN/A class SystemCTestBin(Executable): 68955SN/A def __init__(self, test): 69955SN/A super(SystemCTestBin, self).__init__(test.target, *test.sources) 70955SN/A self.reldir = test.reldir 71955SN/A self.test_deps = test.deps 72955SN/A 73955SN/A @classmethod 74955SN/A def declare_all(cls, env): 75955SN/A env = env.Clone() 76955SN/A 77955SN/A # Turn off extra warnings and Werror for the tests. 78955SN/A to_remove = ['-Wall', '-Wundef', '-Wextra', '-Werror'] 79955SN/A env['CCFLAGS'] = \ 80955SN/A filter(lambda f: f not in to_remove, env['CCFLAGS']) 81955SN/A 82955SN/A env.Append(CPPPATH=test_dir.Dir('include')) 83955SN/A 842325SN/A shared_lib_path = env['SHARED_LIB'][0].abspath 851717SN/A sl_dir, sl_base = os.path.split(shared_lib_path) 862652Ssaidi@eecs.umich.edu env.Append(LIBPATH=[sl_dir], LIBS=[sl_base]) 87955SN/A 882736Sktlim@umich.edu super(SystemCTestBin, cls).declare_all(env) 892410SN/A 90955SN/A def declare(self, env): 912290SN/A env = env.Clone() 92955SN/A sources = list(self.sources) 931717SN/A for f in self.filters: 942683Sktlim@umich.edu sources = Source.all.apply_filter(f) 952683Sktlim@umich.edu objs = self.srcs_to_objs(env, sources) 962669Sktlim@umich.edu objs = objs + env['MAIN_OBJS'] 972568SN/A relpath = os.path.relpath( 982568SN/A env['SHARED_LIB'][0].dir.abspath, 992462SN/A self.path(env).dir.abspath) 1002568SN/A env.Append(LINKFLAGS=Split('-z origin')) 1012395SN/A env.Append(RPATH=env.Literal(os.path.join('\\$$ORIGIN', relpath))) 1022405SN/A test_bin = super(SystemCTestBin, self).declare(env, objs) 103955SN/A test_dir = self.dir.Dir(self.reldir) 104955SN/A for dep in self.test_deps: 105955SN/A env.Depends(test_bin, test_dir.File(dep)) 106955SN/A return test_bin 1072090SN/A 108955SN/A tests = [] 1092763Sstever@eecs.umich.edu def new_test(dirname, name): 110955SN/A test = SystemCTest(dirname, name) 1111696SN/A tests.append(test) 112955SN/A return test 113955SN/A 114955SN/A 1151127SN/A def scan_dir_for_tests(subdir): 116955SN/A def visitor(arg, dirname, names): 117955SN/A # If there's a 'DONTRUN' file in this directory, skip it and any 1182379SN/A # child directories. 119955SN/A if 'DONTRUN' in names: 120955SN/A del names[:] 121955SN/A return 1222155SN/A 1232155SN/A endswith = lambda sfx: filter(lambda n: n.endswith(sfx), names) 1242155SN/A 1252155SN/A cpps = endswith('.cpp') 1262155SN/A if not cpps: 1272155SN/A return 1282155SN/A 1292155SN/A def get_entries(fname): 1302155SN/A with open(os.path.join(dirname, fname)) as content: 1312155SN/A lines = content.readlines 1322155SN/A # Get rid of leading and trailing whitespace. 1332155SN/A lines = map(lambda x: x.strip(), content.readlines()) 1342155SN/A # Get rid of blank lines. 1352155SN/A lines = filter(lambda x: x, lines) 1362155SN/A return lines 1372155SN/A 1382155SN/A # If there's only one source file, then that files name is the test 1392155SN/A # name, and it's the source for that test. 1402155SN/A if len(cpps) == 1: 1412155SN/A cpp = cpps[0] 1422155SN/A 1432155SN/A test = new_test(dirname, os.path.splitext(cpp)[0]) 1442155SN/A test.add_source(cpp) 1452155SN/A 1462155SN/A # Otherwise, expect there to be a file that ends in .f. That files 1472155SN/A # name is the test name, and it will list the source files with 1482155SN/A # one preceeding path component. 1492155SN/A else: 1502155SN/A fs = endswith('.f') 1512155SN/A if len(fs) != 1: 1522155SN/A print("In %s, expected 1 *.f file, but found %d.", 1532155SN/A dirname, len(fs)) 1542155SN/A for f in fs: 1552155SN/A print(os.path.join(dirname, f)) 1562155SN/A return 1572155SN/A f = fs[0] 1582155SN/A 1592155SN/A test = new_test(dirname, os.path.splitext(f)[0]) 1602155SN/A # Add all the sources to this test. 1612422SN/A test.add_sources(get_entries(f)) 1622422SN/A 1632422SN/A if 'COMPILE' in names: 1642422SN/A test.compile_only = True 1652422SN/A 1662422SN/A if 'DEPS' in names: 1672422SN/A test.deps = get_entries('DEPS') 1682397SN/A 1692397SN/A subdir_src = Dir('.').srcdir.Dir(subdir) 1702422SN/A os.path.walk(str(subdir_src), visitor, None) 1712422SN/A 172955SN/A scan_dir_for_tests('systemc') 173955SN/A scan_dir_for_tests('tlm') 174955SN/A 175955SN/A 176955SN/A def build_tests_json(target, source, env): 177955SN/A data = { test.target : test.properties() for test in tests } 178955SN/A with open(str(target[0]), "w") as tests_json: 179955SN/A json.dump(data, tests_json) 1801078SN/A 181955SN/A AlwaysBuild(env.Command(File('tests.json'), None, 182955SN/A MakeAction(build_tests_json, Transform("TESTJSON")))) 183955SN/A 184955SN/A 1851917SN/A for test in tests: 186955SN/A SystemCTestBin(test) 187955SN/A