SConscript revision 13655
1247Sstever@eecs.umich.edu# Copyright 2018 Google, Inc. 24018Sstever@eecs.umich.edu# 3247Sstever@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 4247Sstever@eecs.umich.edu# modification, are permitted provided that the following conditions are 5247Sstever@eecs.umich.edu# met: redistributions of source code must retain the above copyright 6247Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 7247Sstever@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 8247Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 9247Sstever@eecs.umich.edu# documentation and/or other materials provided with the distribution; 10247Sstever@eecs.umich.edu# neither the name of the copyright holders nor the names of its 11247Sstever@eecs.umich.edu# contributors may be used to endorse or promote products derived from 12247Sstever@eecs.umich.edu# this software without specific prior written permission. 13247Sstever@eecs.umich.edu# 14247Sstever@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15247Sstever@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16247Sstever@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17247Sstever@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18247Sstever@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19247Sstever@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20247Sstever@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21247Sstever@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22247Sstever@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23247Sstever@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24247Sstever@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25247Sstever@eecs.umich.edu# 26247Sstever@eecs.umich.edu# Authors: Gabe Black 27247Sstever@eecs.umich.edu 28247Sstever@eecs.umich.edufrom __future__ import print_function 29247Sstever@eecs.umich.edu 301123Sstever@eecs.umich.eduImport('*') 311123Sstever@eecs.umich.edu 321123Sstever@eecs.umich.eduif env['USE_SYSTEMC']: 331746Shsul@eecs.umich.edu 341746Shsul@eecs.umich.edu from gem5_scons import Transform 351123Sstever@eecs.umich.edu 363362Sstever@eecs.umich.edu import os.path 373362Sstever@eecs.umich.edu import json 383362Sstever@eecs.umich.edu 393362Sstever@eecs.umich.edu src = str(Dir('.').srcdir) 403362Sstever@eecs.umich.edu 413362Sstever@eecs.umich.edu class SystemCTest(object): 423362Sstever@eecs.umich.edu def __init__(self, dirname, name): 431123Sstever@eecs.umich.edu self.name = name 443370Sstever@eecs.umich.edu self.reldir = os.path.relpath(dirname, src) 453370Sstever@eecs.umich.edu self.target = os.path.join(self.reldir, name) 463370Sstever@eecs.umich.edu self.sources = [] 473370Sstever@eecs.umich.edu self.deps = [] 483362Sstever@eecs.umich.edu 493362Sstever@eecs.umich.edu self.compile_only = False 503362Sstever@eecs.umich.edu 513362Sstever@eecs.umich.edu def add_source(self, source): 523362Sstever@eecs.umich.edu self.sources.append(os.path.join(self.reldir, source)) 533362Sstever@eecs.umich.edu 543362Sstever@eecs.umich.edu def add_sources(self, sources): 553362Sstever@eecs.umich.edu for source in sources: 563362Sstever@eecs.umich.edu self.sources.append(os.path.join(self.reldir, '..', source)) 573362Sstever@eecs.umich.edu 583362Sstever@eecs.umich.edu def properties(self): 593362Sstever@eecs.umich.edu return { 603362Sstever@eecs.umich.edu 'name' : self.name, 611123Sstever@eecs.umich.edu 'path' : self.reldir, 62247Sstever@eecs.umich.edu 'compile_only' : self.compile_only, 634018Sstever@eecs.umich.edu 'deps' : self.deps 644018Sstever@eecs.umich.edu } 65247Sstever@eecs.umich.edu 663362Sstever@eecs.umich.edu test_dir = Dir('.') 673362Sstever@eecs.umich.edu class SystemCTestBin(Executable): 683362Sstever@eecs.umich.edu def __init__(self, test): 693362Sstever@eecs.umich.edu super(SystemCTestBin, self).__init__(test.target, *test.sources) 703362Sstever@eecs.umich.edu self.reldir = test.reldir 713362Sstever@eecs.umich.edu self.test_deps = test.deps 723362Sstever@eecs.umich.edu 733362Sstever@eecs.umich.edu @classmethod 743362Sstever@eecs.umich.edu def declare_all(cls, env): 753362Sstever@eecs.umich.edu env = env.Clone() 763362Sstever@eecs.umich.edu 773362Sstever@eecs.umich.edu # Turn off extra warnings and Werror for the tests. 78247Sstever@eecs.umich.edu to_remove = ['-Wall', '-Wundef', '-Wextra', '-Werror'] 79247Sstever@eecs.umich.edu env['CCFLAGS'] = \ 80247Sstever@eecs.umich.edu filter(lambda f: f not in to_remove, env['CCFLAGS']) 813362Sstever@eecs.umich.edu 823362Sstever@eecs.umich.edu env.Append(CPPPATH=test_dir.Dir('include')) 83247Sstever@eecs.umich.edu 843362Sstever@eecs.umich.edu shared_lib_path = env['SHARED_LIB'][0].abspath 853362Sstever@eecs.umich.edu sl_dir, sl_base = os.path.split(shared_lib_path) 863362Sstever@eecs.umich.edu env.Append(LIBPATH=[sl_dir], LIBS=[sl_base]) 87247Sstever@eecs.umich.edu 883370Sstever@eecs.umich.edu super(SystemCTestBin, cls).declare_all(env) 893370Sstever@eecs.umich.edu 903370Sstever@eecs.umich.edu def declare(self, env): 913370Sstever@eecs.umich.edu env = env.Clone() 923370Sstever@eecs.umich.edu sources = list(self.sources) 933370Sstever@eecs.umich.edu for f in self.filters: 943370Sstever@eecs.umich.edu sources = Source.all.apply_filter(f) 953370Sstever@eecs.umich.edu objs = self.srcs_to_objs(env, sources) 961442Sstever@eecs.umich.edu objs = objs + env['MAIN_OBJS'] 971442Sstever@eecs.umich.edu relpath = os.path.relpath( 981442Sstever@eecs.umich.edu env['SHARED_LIB'][0].dir.abspath, 991442Sstever@eecs.umich.edu self.path(env).dir.abspath) 1001442Sstever@eecs.umich.edu env.Append(LINKFLAGS=Split('-z origin')) 1011442Sstever@eecs.umich.edu env.Append(RPATH=[ 1021123Sstever@eecs.umich.edu env.Literal(os.path.join('\\$$ORIGIN', relpath))]) 1033362Sstever@eecs.umich.edu test_bin = super(SystemCTestBin, self).declare(env, objs) 1043362Sstever@eecs.umich.edu test_dir = self.dir.Dir(self.reldir) 105247Sstever@eecs.umich.edu for dep in self.test_deps: 1064018Sstever@eecs.umich.edu env.Depends(test_bin, test_dir.File(dep)) 1074018Sstever@eecs.umich.edu return test_bin 1084018Sstever@eecs.umich.edu 109247Sstever@eecs.umich.edu tests = [] 110247Sstever@eecs.umich.edu def new_test(dirname, name): 111247Sstever@eecs.umich.edu test = SystemCTest(dirname, name) 112247Sstever@eecs.umich.edu tests.append(test) 113247Sstever@eecs.umich.edu return test 114247Sstever@eecs.umich.edu 115 116 def scan_dir_for_tests(subdir): 117 def visitor(arg, dirname, names): 118 # If there's a 'DONTRUN' file in this directory, skip it and any 119 # child directories. 120 if 'DONTRUN' in names: 121 del names[:] 122 return 123 124 endswith = lambda sfx: filter(lambda n: n.endswith(sfx), names) 125 126 cpps = endswith('.cpp') 127 if not cpps: 128 return 129 130 def get_entries(fname): 131 with open(os.path.join(dirname, fname)) as content: 132 lines = content.readlines 133 # Get rid of leading and trailing whitespace. 134 lines = map(lambda x: x.strip(), content.readlines()) 135 # Get rid of blank lines. 136 lines = filter(lambda x: x, lines) 137 return lines 138 139 # If there's only one source file, then that files name is the test 140 # name, and it's the source for that test. 141 if len(cpps) == 1: 142 cpp = cpps[0] 143 144 test = new_test(dirname, os.path.splitext(cpp)[0]) 145 test.add_source(cpp) 146 147 # Otherwise, expect there to be a file that ends in .f. That files 148 # name is the test name, and it will list the source files with 149 # one preceeding path component. 150 else: 151 fs = endswith('.f') 152 if len(fs) != 1: 153 print("In %s, expected 1 *.f file, but found %d.", 154 dirname, len(fs)) 155 for f in fs: 156 print(os.path.join(dirname, f)) 157 return 158 f = fs[0] 159 160 test = new_test(dirname, os.path.splitext(f)[0]) 161 # Add all the sources to this test. 162 test.add_sources(get_entries(f)) 163 164 if 'COMPILE' in names: 165 test.compile_only = True 166 167 if 'DEPS' in names: 168 test.deps = get_entries('DEPS') 169 170 subdir_src = Dir('.').srcdir.Dir(subdir) 171 os.path.walk(str(subdir_src), visitor, None) 172 173 scan_dir_for_tests('systemc') 174 scan_dir_for_tests('tlm') 175 176 177 def build_tests_json(target, source, env): 178 data = { test.target : test.properties() for test in tests } 179 with open(str(target[0]), "w") as tests_json: 180 json.dump(data, tests_json) 181 182 AlwaysBuild(env.Command(File('tests.json'), None, 183 MakeAction(build_tests_json, Transform("TESTJSON")))) 184 185 186 for test in tests: 187 SystemCTestBin(test) 188