SConscript revision 13656
15703SN/A# Copyright 2018 Google, Inc. 25703SN/A# 35703SN/A# Redistribution and use in source and binary forms, with or without 48825Snilay@cs.wisc.edu# modification, are permitted provided that the following conditions are 57935SN/A# met: redistributions of source code must retain the above copyright 67935SN/A# notice, this list of conditions and the following disclaimer; 77935SN/A# redistributions in binary form must reproduce the above copyright 85703SN/A# notice, this list of conditions and the following disclaimer in the 95703SN/A# documentation and/or other materials provided with the distribution; 105703SN/A# neither the name of the copyright holders nor the names of its 115703SN/A# contributors may be used to endorse or promote products derived from 125703SN/A# this software without specific prior written permission. 135703SN/A# 148835SAli.Saidi@ARM.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 155703SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 168835SAli.Saidi@ARM.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 177670SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 185703SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 198464SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 208721SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 218835SAli.Saidi@ARM.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 225703SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 235703SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 245703SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 255703SN/A# 267935SN/A# Authors: Gabe Black 277935SN/A 287935SN/Afrom __future__ import print_function 297935SN/A 307935SN/AImport('*') 317935SN/A 327935SN/Aif env['USE_SYSTEMC']: 338983Snate@binkert.org 345703SN/A from gem5_scons import Transform 355703SN/A 365703SN/A import os.path 375703SN/A import json 385703SN/A 398721SN/A src = str(Dir('.').srcdir) 408721SN/A 418721SN/A class SystemCTest(object): 425703SN/A def __init__(self, dirname, name): 438983Snate@binkert.org self.name = name 448983Snate@binkert.org self.reldir = os.path.relpath(dirname, src) 455703SN/A self.target = os.path.join(self.reldir, name) 465703SN/A self.sources = [] 475703SN/A self.deps = [] 485703SN/A 495703SN/A self.compile_only = False 505703SN/A 515703SN/A def add_source(self, source): 525703SN/A self.sources.append(os.path.join(self.reldir, source)) 538241SN/A 548241SN/A def add_sources(self, sources): 555703SN/A for source in sources: 565703SN/A self.sources.append(os.path.join(self.reldir, '..', source)) 575703SN/A 585703SN/A def properties(self): 595703SN/A return { 605703SN/A 'name' : self.name, 615876SN/A 'path' : self.reldir, 625703SN/A 'compile_only' : self.compile_only, 635703SN/A 'deps' : self.deps 645703SN/A } 655703SN/A 665703SN/A test_dir = Dir('.') 675703SN/A class SystemCTestBin(Executable): 685703SN/A def __init__(self, test): 695703SN/A super(SystemCTestBin, self).__init__(test.target, *test.sources) 705703SN/A self.reldir = test.reldir 715703SN/A self.test_deps = test.deps 725703SN/A 735703SN/A @classmethod 745703SN/A def declare_all(cls, env): 755703SN/A env = env.Clone() 765703SN/A 775703SN/A # Turn off extra warnings and Werror for the tests. 785703SN/A to_remove = ['-Wall', '-Wundef', '-Wextra', '-Werror'] 795703SN/A env['CCFLAGS'] = \ 805703SN/A filter(lambda f: f not in to_remove, env['CCFLAGS']) 815703SN/A 825703SN/A env.Append(CPPPATH=test_dir.Dir('include')) 835703SN/A 845703SN/A shared_lib_path = env['SHARED_LIB'][0].abspath 855703SN/A sl_dir, sl_base = os.path.split(shared_lib_path) 865703SN/A env.Append(LIBPATH=[sl_dir], LIBS=[sl_base]) 875703SN/A 885703SN/A super(SystemCTestBin, cls).declare_all(env) 895703SN/A 905703SN/A def declare(self, env): 915703SN/A env = env.Clone() 925703SN/A sources = list(self.sources) 935703SN/A for f in self.filters: 945703SN/A sources += Source.all.apply_filter(f) 955703SN/A objs = self.srcs_to_objs(env, sources) 965703SN/A objs = objs + env['MAIN_OBJS'] 975703SN/A relpath = os.path.relpath( 985703SN/A env['SHARED_LIB'][0].dir.abspath, 995703SN/A self.path(env).dir.abspath) 1005703SN/A env.Append(LINKFLAGS=Split('-z origin')) 1015703SN/A env.Append(RPATH=[ 1025703SN/A env.Literal(os.path.join('\\$$ORIGIN', relpath))]) 1035703SN/A test_bin = super(SystemCTestBin, self).declare(env, objs) 1045703SN/A test_dir = self.dir.Dir(self.reldir) 1055703SN/A for dep in self.test_deps: 1065703SN/A env.Depends(test_bin, test_dir.File(dep)) 1078825Snilay@cs.wisc.edu return test_bin 1085703SN/A 1095703SN/A tests = [] 1105703SN/A def new_test(dirname, name): 1115703SN/A test = SystemCTest(dirname, name) 1125703SN/A tests.append(test) 1135703SN/A return test 1145703SN/A 1155703SN/A 1165703SN/A def scan_dir_for_tests(subdir): 1175703SN/A def visitor(arg, dirname, names): 1185703SN/A # If there's a 'DONTRUN' file in this directory, skip it and any 1195703SN/A # child directories. 1205703SN/A if 'DONTRUN' in names: 1215703SN/A del names[:] 1225703SN/A return 1235703SN/A 1245703SN/A endswith = lambda sfx: filter(lambda n: n.endswith(sfx), names) 1255703SN/A 1265703SN/A cpps = endswith('.cpp') 1275703SN/A if not cpps: 1285703SN/A return 1295703SN/A 1305703SN/A def get_entries(fname): 1315703SN/A with open(os.path.join(dirname, fname)) as content: 1325703SN/A lines = content.readlines 1338521SN/A # Get rid of leading and trailing whitespace. 1345703SN/A lines = map(lambda x: x.strip(), content.readlines()) 1355703SN/A # Get rid of blank lines. 1365703SN/A lines = filter(lambda x: x, lines) 1375703SN/A return lines 1385703SN/A 1398825Snilay@cs.wisc.edu # If there's only one source file, then that files name is the test 1405703SN/A # name, and it's the source for that test. 1415703SN/A if len(cpps) == 1: 1425703SN/A cpp = cpps[0] 1435703SN/A 1445703SN/A test = new_test(dirname, os.path.splitext(cpp)[0]) 1458983Snate@binkert.org test.add_source(cpp) 1465703SN/A 1475703SN/A # Otherwise, expect there to be a file that ends in .f. That files 1486123SN/A # name is the test name, and it will list the source files with 1495703SN/A # one preceeding path component. 1508135SN/A else: 1515703SN/A fs = endswith('.f') 1525703SN/A if len(fs) != 1: 1535703SN/A print("In %s, expected 1 *.f file, but found %d.", 1545876SN/A dirname, len(fs)) 1558835SAli.Saidi@ARM.com for f in fs: 1565703SN/A print(os.path.join(dirname, f)) 1575703SN/A return 1585703SN/A f = fs[0] 1595703SN/A 1608835SAli.Saidi@ARM.com test = new_test(dirname, os.path.splitext(f)[0]) 1615703SN/A # Add all the sources to this test. 1625703SN/A test.add_sources(get_entries(f)) 1635703SN/A 1645703SN/A if 'COMPILE' in names: 1655703SN/A test.compile_only = True 1668983Snate@binkert.org 1675703SN/A if 'DEPS' in names: 1685703SN/A test.deps = get_entries('DEPS') 1696024SN/A 1705703SN/A subdir_src = Dir('.').srcdir.Dir(subdir) 1715703SN/A os.path.walk(str(subdir_src), visitor, None) 1725703SN/A 1735703SN/A scan_dir_for_tests('systemc') 1747761SN/A scan_dir_for_tests('tlm') 1757761SN/A 1765703SN/A 1775703SN/A def build_tests_json(target, source, env): 1785703SN/A data = { test.target : test.properties() for test in tests } 1795703SN/A with open(str(target[0]), "w") as tests_json: 1805703SN/A json.dump(data, tests_json) 1815703SN/A 1825703SN/A AlwaysBuild(env.Command(File('tests.json'), None, 1835703SN/A MakeAction(build_tests_json, Transform("TESTJSON")))) 1845703SN/A 1855703SN/A 1865703SN/A for test in tests: 1875703SN/A SystemCTestBin(test) 1885703SN/A