SConscript revision 13508:8fe5d0294e51
1955SN/A# -*- mode:python -*- 2955SN/A 31762SN/A# Copyright (c) 2004-2005 The Regents of The University of Michigan 4955SN/A# All rights reserved. 5955SN/A# 6955SN/A# Redistribution and use in source and binary forms, with or without 7955SN/A# modification, are permitted provided that the following conditions are 8955SN/A# met: redistributions of source code must retain the above copyright 9955SN/A# notice, this list of conditions and the following disclaimer; 10955SN/A# redistributions in binary form must reproduce the above copyright 11955SN/A# notice, this list of conditions and the following disclaimer in the 12955SN/A# documentation and/or other materials provided with the distribution; 13955SN/A# neither the name of the copyright holders nor the names of its 14955SN/A# contributors may be used to endorse or promote products derived from 15955SN/A# this software without specific prior written permission. 16955SN/A# 17955SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18955SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20955SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21955SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22955SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23955SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25955SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27955SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu# 294762Snate@binkert.org# Authors: Nathan Binkert 30955SN/A 315522Snate@binkert.orgfrom __future__ import print_function 326143Snate@binkert.org 334762Snate@binkert.orgimport array 345522Snate@binkert.orgimport bisect 35955SN/Aimport functools 365522Snate@binkert.orgimport imp 3711974Sgabeblack@google.comimport marshal 38955SN/Aimport os 395522Snate@binkert.orgimport re 404202Sbinkertn@umich.eduimport subprocess 415742Snate@binkert.orgimport sys 42955SN/Aimport zlib 434381Sbinkertn@umich.edu 444381Sbinkertn@umich.edufrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 458334Snate@binkert.org 46955SN/Aimport SCons 47955SN/A 484202Sbinkertn@umich.edufrom gem5_scons import Transform 49955SN/A 504382Sbinkertn@umich.edu# This file defines how to build a particular configuration of gem5 514382Sbinkertn@umich.edu# based on variable settings in the 'env' build environment. 524382Sbinkertn@umich.edu 536654Snate@binkert.orgImport('*') 545517Snate@binkert.org 558614Sgblack@eecs.umich.edu# Children need to see the environment 567674Snate@binkert.orgExport('env') 576143Snate@binkert.org 586143Snate@binkert.orgbuild_env = [(opt, env[opt]) for opt in export_vars] 596143Snate@binkert.org 608233Snate@binkert.orgfrom m5.util import code_formatter, compareVersions 618233Snate@binkert.org 628233Snate@binkert.org######################################################################## 638233Snate@binkert.org# Code for adding source files of various types 648233Snate@binkert.org# 658334Snate@binkert.org# When specifying a source file of some type, a set of tags can be 668334Snate@binkert.org# specified for that file. 6710453SAndrew.Bardsley@arm.com 6810453SAndrew.Bardsley@arm.comclass SourceFilter(object): 698233Snate@binkert.org def __init__(self, predicate): 708233Snate@binkert.org self.predicate = predicate 718233Snate@binkert.org 728233Snate@binkert.org def __or__(self, other): 738233Snate@binkert.org return SourceFilter(lambda tags: self.predicate(tags) or 748233Snate@binkert.org other.predicate(tags)) 7511983Sgabeblack@google.com 7611983Sgabeblack@google.com def __and__(self, other): 7711983Sgabeblack@google.com return SourceFilter(lambda tags: self.predicate(tags) and 7811983Sgabeblack@google.com other.predicate(tags)) 7911983Sgabeblack@google.com 8011983Sgabeblack@google.comdef with_tags_that(predicate): 8111983Sgabeblack@google.com '''Return a list of sources with tags that satisfy a predicate.''' 8211983Sgabeblack@google.com return SourceFilter(predicate) 8311983Sgabeblack@google.com 8411983Sgabeblack@google.comdef with_any_tags(*tags): 8511983Sgabeblack@google.com '''Return a list of sources with any of the supplied tags.''' 866143Snate@binkert.org return SourceFilter(lambda stags: len(set(tags) & stags) > 0) 878233Snate@binkert.org 888233Snate@binkert.orgdef with_all_tags(*tags): 898233Snate@binkert.org '''Return a list of sources with all of the supplied tags.''' 906143Snate@binkert.org return SourceFilter(lambda stags: set(tags) <= stags) 916143Snate@binkert.org 926143Snate@binkert.orgdef with_tag(tag): 9311308Santhony.gutierrez@amd.com '''Return a list of sources with the supplied tag.''' 948233Snate@binkert.org return SourceFilter(lambda stags: tag in stags) 958233Snate@binkert.org 968233Snate@binkert.orgdef without_tags(*tags): 9711983Sgabeblack@google.com '''Return a list of sources without any of the supplied tags.''' 9811983Sgabeblack@google.com return SourceFilter(lambda stags: len(set(tags) & stags) == 0) 994762Snate@binkert.org 1006143Snate@binkert.orgdef without_tag(tag): 1018233Snate@binkert.org '''Return a list of sources with the supplied tag.''' 1028233Snate@binkert.org return SourceFilter(lambda stags: tag not in stags) 1038233Snate@binkert.org 1048233Snate@binkert.orgsource_filter_factories = { 1058233Snate@binkert.org 'with_tags_that': with_tags_that, 1066143Snate@binkert.org 'with_any_tags': with_any_tags, 1078233Snate@binkert.org 'with_all_tags': with_all_tags, 1088233Snate@binkert.org 'with_tag': with_tag, 1098233Snate@binkert.org 'without_tags': without_tags, 1108233Snate@binkert.org 'without_tag': without_tag, 1116143Snate@binkert.org} 1126143Snate@binkert.org 1136143Snate@binkert.orgExport(source_filter_factories) 1146143Snate@binkert.org 1156143Snate@binkert.orgclass SourceList(list): 1166143Snate@binkert.org def apply_filter(self, f): 1176143Snate@binkert.org def match(source): 1186143Snate@binkert.org return f.predicate(source.tags) 1196143Snate@binkert.org return SourceList(filter(match, self)) 1207065Snate@binkert.org 1216143Snate@binkert.org def __getattr__(self, name): 1228233Snate@binkert.org func = source_filter_factories.get(name, None) 1238233Snate@binkert.org if not func: 1248233Snate@binkert.org raise AttributeError 1258233Snate@binkert.org 1268233Snate@binkert.org @functools.wraps(func) 1278233Snate@binkert.org def wrapper(*args, **kwargs): 1288233Snate@binkert.org return self.apply_filter(func(*args, **kwargs)) 1298233Snate@binkert.org return wrapper 1308233Snate@binkert.org 1318233Snate@binkert.orgclass SourceMeta(type): 1328233Snate@binkert.org '''Meta class for source files that keeps track of all files of a 1338233Snate@binkert.org particular type.''' 1348233Snate@binkert.org def __init__(cls, name, bases, dict): 1358233Snate@binkert.org super(SourceMeta, cls).__init__(name, bases, dict) 1368233Snate@binkert.org cls.all = SourceList() 1378233Snate@binkert.org 1388233Snate@binkert.orgclass SourceFile(object): 1398233Snate@binkert.org '''Base object that encapsulates the notion of a source file. 1408233Snate@binkert.org This includes, the source node, target node, various manipulations 1418233Snate@binkert.org of those. A source file also specifies a set of tags which 1428233Snate@binkert.org describing arbitrary properties of the source file.''' 1438233Snate@binkert.org __metaclass__ = SourceMeta 1448233Snate@binkert.org 1458233Snate@binkert.org static_objs = {} 1468233Snate@binkert.org shared_objs = {} 1478233Snate@binkert.org 1488233Snate@binkert.org def __init__(self, source, tags=None, add_tags=None): 1498233Snate@binkert.org if tags is None: 1508233Snate@binkert.org tags='gem5 lib' 1518233Snate@binkert.org if isinstance(tags, basestring): 1528233Snate@binkert.org tags = set([tags]) 1536143Snate@binkert.org if not isinstance(tags, set): 1546143Snate@binkert.org tags = set(tags) 1556143Snate@binkert.org self.tags = tags 1566143Snate@binkert.org 1576143Snate@binkert.org if add_tags: 1586143Snate@binkert.org if isinstance(add_tags, basestring): 1599982Satgutier@umich.edu add_tags = set([add_tags]) 16010196SCurtis.Dunham@arm.com if not isinstance(add_tags, set): 16110196SCurtis.Dunham@arm.com add_tags = set(add_tags) 16210196SCurtis.Dunham@arm.com self.tags |= add_tags 16310196SCurtis.Dunham@arm.com 16410196SCurtis.Dunham@arm.com tnode = source 16510196SCurtis.Dunham@arm.com if not isinstance(source, SCons.Node.FS.File): 16610196SCurtis.Dunham@arm.com tnode = File(source) 16710196SCurtis.Dunham@arm.com 1686143Snate@binkert.org self.tnode = tnode 16911983Sgabeblack@google.com self.snode = tnode.srcnode() 17011983Sgabeblack@google.com 17111983Sgabeblack@google.com for base in type(self).__mro__: 17211983Sgabeblack@google.com if issubclass(base, SourceFile): 17311983Sgabeblack@google.com base.all.append(self) 17411983Sgabeblack@google.com 17511983Sgabeblack@google.com def static(self, env): 17611983Sgabeblack@google.com key = (self.tnode, env['OBJSUFFIX']) 17711983Sgabeblack@google.com if not key in self.static_objs: 1786143Snate@binkert.org self.static_objs[key] = env.StaticObject(self.tnode) 17911988Sandreas.sandberg@arm.com return self.static_objs[key] 1808233Snate@binkert.org 1818233Snate@binkert.org def shared(self, env): 1826143Snate@binkert.org key = (self.tnode, env['OBJSUFFIX']) 1838945Ssteve.reinhardt@amd.com if not key in self.shared_objs: 1846143Snate@binkert.org self.shared_objs[key] = env.SharedObject(self.tnode) 18511983Sgabeblack@google.com return self.shared_objs[key] 18611983Sgabeblack@google.com 1876143Snate@binkert.org @property 1886143Snate@binkert.org def filename(self): 1895522Snate@binkert.org return str(self.tnode) 1906143Snate@binkert.org 1916143Snate@binkert.org @property 1926143Snate@binkert.org def dirname(self): 1939982Satgutier@umich.edu return dirname(self.filename) 1948233Snate@binkert.org 1958233Snate@binkert.org @property 1968233Snate@binkert.org def basename(self): 1976143Snate@binkert.org return basename(self.filename) 1986143Snate@binkert.org 1996143Snate@binkert.org @property 2006143Snate@binkert.org def extname(self): 2015522Snate@binkert.org index = self.basename.rfind('.') 2025522Snate@binkert.org if index <= 0: 2035522Snate@binkert.org # dot files aren't extensions 2045522Snate@binkert.org return self.basename, None 2055604Snate@binkert.org 2065604Snate@binkert.org return self.basename[:index], self.basename[index+1:] 2076143Snate@binkert.org 2086143Snate@binkert.org def __lt__(self, other): return self.filename < other.filename 2094762Snate@binkert.org def __le__(self, other): return self.filename <= other.filename 2104762Snate@binkert.org def __gt__(self, other): return self.filename > other.filename 2116143Snate@binkert.org def __ge__(self, other): return self.filename >= other.filename 2126727Ssteve.reinhardt@amd.com def __eq__(self, other): return self.filename == other.filename 2136727Ssteve.reinhardt@amd.com def __ne__(self, other): return self.filename != other.filename 2146727Ssteve.reinhardt@amd.com 2154762Snate@binkert.orgclass Source(SourceFile): 2166143Snate@binkert.org ungrouped_tag = 'No link group' 2176143Snate@binkert.org source_groups = set() 2186143Snate@binkert.org 2196143Snate@binkert.org _current_group_tag = ungrouped_tag 2206727Ssteve.reinhardt@amd.com 2216143Snate@binkert.org @staticmethod 2227674Snate@binkert.org def link_group_tag(group): 2237674Snate@binkert.org return 'link group: %s' % group 2245604Snate@binkert.org 2256143Snate@binkert.org @classmethod 2266143Snate@binkert.org def set_group(cls, group): 2276143Snate@binkert.org new_tag = Source.link_group_tag(group) 2284762Snate@binkert.org Source._current_group_tag = new_tag 2296143Snate@binkert.org Source.source_groups.add(group) 2304762Snate@binkert.org 2314762Snate@binkert.org def _add_link_group_tag(self): 2324762Snate@binkert.org self.tags.add(Source._current_group_tag) 2336143Snate@binkert.org 2346143Snate@binkert.org '''Add a c/c++ source file to the build''' 2354762Snate@binkert.org def __init__(self, source, tags=None, add_tags=None): 2368233Snate@binkert.org '''specify the source file, and any tags''' 2378233Snate@binkert.org super(Source, self).__init__(source, tags, add_tags) 2388233Snate@binkert.org self._add_link_group_tag() 2398233Snate@binkert.org 2406143Snate@binkert.orgclass PySource(SourceFile): 2416143Snate@binkert.org '''Add a python source file to the named package''' 2424762Snate@binkert.org invalid_sym_char = re.compile('[^A-z0-9_]') 2436143Snate@binkert.org modules = {} 2444762Snate@binkert.org tnodes = {} 2459396Sandreas.hansson@arm.com symnames = {} 2469396Sandreas.hansson@arm.com 2479396Sandreas.hansson@arm.com def __init__(self, package, source, tags=None, add_tags=None): 2489396Sandreas.hansson@arm.com '''specify the python package, the source file, and any tags''' 2499396Sandreas.hansson@arm.com super(PySource, self).__init__(source, tags, add_tags) 2509396Sandreas.hansson@arm.com 2519396Sandreas.hansson@arm.com modname,ext = self.extname 2529396Sandreas.hansson@arm.com assert ext == 'py' 2539396Sandreas.hansson@arm.com 2549396Sandreas.hansson@arm.com if package: 2559396Sandreas.hansson@arm.com path = package.split('.') 2569396Sandreas.hansson@arm.com else: 2579396Sandreas.hansson@arm.com path = [] 2589930Sandreas.hansson@arm.com 2599930Sandreas.hansson@arm.com modpath = path[:] 2609396Sandreas.hansson@arm.com if modname != '__init__': 2618235Snate@binkert.org modpath += [ modname ] 2628235Snate@binkert.org modpath = '.'.join(modpath) 2636143Snate@binkert.org 2648235Snate@binkert.org arcpath = path + [ self.basename ] 2659003SAli.Saidi@ARM.com abspath = self.snode.abspath 2668235Snate@binkert.org if not exists(abspath): 2678235Snate@binkert.org abspath = self.tnode.abspath 2688235Snate@binkert.org 2698235Snate@binkert.org self.package = package 2708235Snate@binkert.org self.modname = modname 2718235Snate@binkert.org self.modpath = modpath 2728235Snate@binkert.org self.arcname = joinpath(*arcpath) 2738235Snate@binkert.org self.abspath = abspath 2748235Snate@binkert.org self.compiled = File(self.filename + 'c') 2758235Snate@binkert.org self.cpp = File(self.filename + '.cc') 2768235Snate@binkert.org self.symname = PySource.invalid_sym_char.sub('_', modpath) 2778235Snate@binkert.org 2788235Snate@binkert.org PySource.modules[modpath] = self 2798235Snate@binkert.org PySource.tnodes[self.tnode] = self 2809003SAli.Saidi@ARM.com PySource.symnames[self.symname] = self 2818235Snate@binkert.org 2825584Snate@binkert.orgclass SimObject(PySource): 2834382Sbinkertn@umich.edu '''Add a SimObject python file as a python source object and add 2844202Sbinkertn@umich.edu it to a list of sim object modules''' 2854382Sbinkertn@umich.edu 2864382Sbinkertn@umich.edu fixed = False 2879396Sandreas.hansson@arm.com modnames = [] 2885584Snate@binkert.org 2894382Sbinkertn@umich.edu def __init__(self, source, tags=None, add_tags=None): 2904382Sbinkertn@umich.edu '''Specify the source file and any tags (automatically in 2914382Sbinkertn@umich.edu the m5.objects package)''' 2928232Snate@binkert.org super(SimObject, self).__init__('m5.objects', source, tags, add_tags) 2935192Ssaidi@eecs.umich.edu if self.fixed: 2948232Snate@binkert.org raise AttributeError, "Too late to call SimObject now." 2958232Snate@binkert.org 2968232Snate@binkert.org bisect.insort_right(SimObject.modnames, self.modname) 2975192Ssaidi@eecs.umich.edu 2988232Snate@binkert.orgclass ProtoBuf(SourceFile): 2995192Ssaidi@eecs.umich.edu '''Add a Protocol Buffer to build''' 3005799Snate@binkert.org 3018232Snate@binkert.org def __init__(self, source, tags=None, add_tags=None): 3025192Ssaidi@eecs.umich.edu '''Specify the source file, and any tags''' 3035192Ssaidi@eecs.umich.edu super(ProtoBuf, self).__init__(source, tags, add_tags) 3045192Ssaidi@eecs.umich.edu 3058232Snate@binkert.org # Get the file name and the extension 3065192Ssaidi@eecs.umich.edu modname,ext = self.extname 3078232Snate@binkert.org assert ext == 'proto' 3085192Ssaidi@eecs.umich.edu 3095192Ssaidi@eecs.umich.edu # Currently, we stick to generating the C++ headers, so we 3105192Ssaidi@eecs.umich.edu # only need to track the source and header. 3115192Ssaidi@eecs.umich.edu self.cc_file = File(modname + '.pb.cc') 3124382Sbinkertn@umich.edu self.hh_file = File(modname + '.pb.h') 3134382Sbinkertn@umich.edu 3144382Sbinkertn@umich.edu 3152667Sstever@eecs.umich.eduexectuable_classes = [] 3162667Sstever@eecs.umich.educlass ExecutableMeta(type): 3172667Sstever@eecs.umich.edu '''Meta class for Executables.''' 3182667Sstever@eecs.umich.edu all = [] 3192667Sstever@eecs.umich.edu 3202667Sstever@eecs.umich.edu def __init__(cls, name, bases, d): 3215742Snate@binkert.org if not d.pop('abstract', False): 3225742Snate@binkert.org ExecutableMeta.all.append(cls) 3235742Snate@binkert.org super(ExecutableMeta, cls).__init__(name, bases, d) 3245793Snate@binkert.org 3258334Snate@binkert.org cls.all = [] 3265793Snate@binkert.org 3275793Snate@binkert.orgclass Executable(object): 3285793Snate@binkert.org '''Base class for creating an executable from sources.''' 3294382Sbinkertn@umich.edu __metaclass__ = ExecutableMeta 3304762Snate@binkert.org 3315344Sstever@gmail.com abstract = True 3324382Sbinkertn@umich.edu 3335341Sstever@gmail.com def __init__(self, target, *srcs_and_filts): 3345742Snate@binkert.org '''Specify the target name and any sources. Sources that are 3355742Snate@binkert.org not SourceFiles are evalued with Source().''' 3365742Snate@binkert.org super(Executable, self).__init__() 3375742Snate@binkert.org self.all.append(self) 3385742Snate@binkert.org self.target = target 3394762Snate@binkert.org 3405742Snate@binkert.org isFilter = lambda arg: isinstance(arg, SourceFilter) 3415742Snate@binkert.org self.filters = filter(isFilter, srcs_and_filts) 34211984Sgabeblack@google.com sources = filter(lambda a: not isFilter(a), srcs_and_filts) 3437722Sgblack@eecs.umich.edu 3445742Snate@binkert.org srcs = SourceList() 3455742Snate@binkert.org for src in sources: 3465742Snate@binkert.org if not isinstance(src, SourceFile): 3479930Sandreas.hansson@arm.com src = Source(src, tags=[]) 3489930Sandreas.hansson@arm.com srcs.append(src) 3499930Sandreas.hansson@arm.com 3509930Sandreas.hansson@arm.com self.sources = srcs 3519930Sandreas.hansson@arm.com self.dir = Dir('.') 3525742Snate@binkert.org 3538242Sbradley.danofsky@amd.com def path(self, env): 3548242Sbradley.danofsky@amd.com return self.dir.File(self.target + '.' + env['EXE_SUFFIX']) 3558242Sbradley.danofsky@amd.com 3568242Sbradley.danofsky@amd.com def srcs_to_objs(self, env, sources): 3575341Sstever@gmail.com return list([ s.static(env) for s in sources ]) 3585742Snate@binkert.org 3597722Sgblack@eecs.umich.edu @classmethod 3604773Snate@binkert.org def declare_all(cls, env): 3616108Snate@binkert.org return list([ instance.declare(env) for instance in cls.all ]) 3621858SN/A 3631085SN/A def declare(self, env, objs=None): 3646658Snate@binkert.org if objs is None: 3656658Snate@binkert.org objs = self.srcs_to_objs(env, self.sources) 3667673Snate@binkert.org 3676658Snate@binkert.org if env['STRIP_EXES']: 3686658Snate@binkert.org stripped = self.path(env) 36911308Santhony.gutierrez@amd.com unstripped = env.File(str(stripped) + '.unstripped') 3706658Snate@binkert.org if sys.platform == 'sunos5': 37111308Santhony.gutierrez@amd.com cmd = 'cp $SOURCE $TARGET; strip $TARGET' 3726658Snate@binkert.org else: 3736658Snate@binkert.org cmd = 'strip $SOURCE -o $TARGET' 3747673Snate@binkert.org env.Program(unstripped, objs) 3757673Snate@binkert.org return env.Command(stripped, unstripped, 3767673Snate@binkert.org MakeAction(cmd, Transform("STRIP"))) 3777673Snate@binkert.org else: 3787673Snate@binkert.org return env.Program(self.path(env), objs) 3797673Snate@binkert.org 3807673Snate@binkert.orgclass UnitTest(Executable): 38110467Sandreas.hansson@arm.com '''Create a UnitTest''' 3826658Snate@binkert.org def __init__(self, target, *srcs_and_filts, **kwargs): 3837673Snate@binkert.org super(UnitTest, self).__init__(target, *srcs_and_filts) 38410467Sandreas.hansson@arm.com 38510467Sandreas.hansson@arm.com self.main = kwargs.get('main', False) 38610467Sandreas.hansson@arm.com 38710467Sandreas.hansson@arm.com def declare(self, env): 38810467Sandreas.hansson@arm.com sources = list(self.sources) 38910467Sandreas.hansson@arm.com for f in self.filters: 39010467Sandreas.hansson@arm.com sources = Source.all.apply_filter(f) 39110467Sandreas.hansson@arm.com objs = self.srcs_to_objs(env, sources) + env['STATIC_OBJS'] 39210467Sandreas.hansson@arm.com if self.main: 39310467Sandreas.hansson@arm.com objs += env['MAIN_OBJS'] 39410467Sandreas.hansson@arm.com return super(UnitTest, self).declare(env, objs) 3957673Snate@binkert.org 3967673Snate@binkert.orgclass GTest(Executable): 3977673Snate@binkert.org '''Create a unit test based on the google test framework.''' 3987673Snate@binkert.org all = [] 3997673Snate@binkert.org def __init__(self, *srcs_and_filts, **kwargs): 4009048SAli.Saidi@ARM.com super(GTest, self).__init__(*srcs_and_filts) 4017673Snate@binkert.org 4027673Snate@binkert.org self.skip_lib = kwargs.pop('skip_lib', False) 4037673Snate@binkert.org 4047673Snate@binkert.org @classmethod 4056658Snate@binkert.org def declare_all(cls, env): 4067756SAli.Saidi@ARM.com env = env.Clone() 4077816Ssteve.reinhardt@amd.com env.Append(LIBS=env['GTEST_LIBS']) 4086658Snate@binkert.org env.Append(CPPFLAGS=env['GTEST_CPPFLAGS']) 40911308Santhony.gutierrez@amd.com env['GTEST_LIB_SOURCES'] = Source.all.with_tag('gtest lib') 41011308Santhony.gutierrez@amd.com env['GTEST_OUT_DIR'] = \ 41111308Santhony.gutierrez@amd.com Dir(env['BUILDDIR']).Dir('unittests.' + env['EXE_SUFFIX']) 41211308Santhony.gutierrez@amd.com return super(GTest, cls).declare_all(env) 41311308Santhony.gutierrez@amd.com 41411308Santhony.gutierrez@amd.com def declare(self, env): 41511308Santhony.gutierrez@amd.com sources = list(self.sources) 41611308Santhony.gutierrez@amd.com if not self.skip_lib: 41711308Santhony.gutierrez@amd.com sources += env['GTEST_LIB_SOURCES'] 41811308Santhony.gutierrez@amd.com for f in self.filters: 41911308Santhony.gutierrez@amd.com sources += Source.all.apply_filter(f) 42011308Santhony.gutierrez@amd.com objs = self.srcs_to_objs(env, sources) 42111308Santhony.gutierrez@amd.com 42211308Santhony.gutierrez@amd.com binary = super(GTest, self).declare(env, objs) 42311308Santhony.gutierrez@amd.com 42411308Santhony.gutierrez@amd.com out_dir = env['GTEST_OUT_DIR'] 42511308Santhony.gutierrez@amd.com xml_file = out_dir.Dir(str(self.dir)).File(self.target + '.xml') 42611308Santhony.gutierrez@amd.com AlwaysBuild(env.Command(xml_file, binary, 42711308Santhony.gutierrez@amd.com "${SOURCES[0]} --gtest_output=xml:${TARGETS[0]}")) 42811308Santhony.gutierrez@amd.com 42911308Santhony.gutierrez@amd.com return binary 43011308Santhony.gutierrez@amd.com 43111308Santhony.gutierrez@amd.comclass Gem5(Executable): 43211308Santhony.gutierrez@amd.com '''Create a gem5 executable.''' 43311308Santhony.gutierrez@amd.com 43411308Santhony.gutierrez@amd.com def __init__(self, target): 43511308Santhony.gutierrez@amd.com super(Gem5, self).__init__(target) 43611308Santhony.gutierrez@amd.com 43711308Santhony.gutierrez@amd.com def declare(self, env): 43811308Santhony.gutierrez@amd.com objs = env['MAIN_OBJS'] + env['STATIC_OBJS'] 43911308Santhony.gutierrez@amd.com return super(Gem5, self).declare(env, objs) 44011308Santhony.gutierrez@amd.com 44111308Santhony.gutierrez@amd.com 44211308Santhony.gutierrez@amd.com# Children should have access 44311308Santhony.gutierrez@amd.comExport('Source') 44411308Santhony.gutierrez@amd.comExport('PySource') 44511308Santhony.gutierrez@amd.comExport('SimObject') 44611308Santhony.gutierrez@amd.comExport('ProtoBuf') 44711308Santhony.gutierrez@amd.comExport('Executable') 44811308Santhony.gutierrez@amd.comExport('UnitTest') 44911308Santhony.gutierrez@amd.comExport('GTest') 45011308Santhony.gutierrez@amd.com 45111308Santhony.gutierrez@amd.com######################################################################## 45211308Santhony.gutierrez@amd.com# 45311308Santhony.gutierrez@amd.com# Debug Flags 4544382Sbinkertn@umich.edu# 4554382Sbinkertn@umich.edudebug_flags = {} 4564762Snate@binkert.orgdef DebugFlag(name, desc=None): 4574762Snate@binkert.org if name in debug_flags: 4584762Snate@binkert.org raise AttributeError, "Flag %s already specified" % name 4596654Snate@binkert.org debug_flags[name] = (name, (), desc) 4606654Snate@binkert.org 4615517Snate@binkert.orgdef CompoundFlag(name, flags, desc=None): 4625517Snate@binkert.org if name in debug_flags: 4635517Snate@binkert.org raise AttributeError, "Flag %s already specified" % name 4645517Snate@binkert.org 4655517Snate@binkert.org compound = tuple(flags) 4665517Snate@binkert.org debug_flags[name] = (name, compound, desc) 4675517Snate@binkert.org 4685517Snate@binkert.orgExport('DebugFlag') 4695517Snate@binkert.orgExport('CompoundFlag') 4705517Snate@binkert.org 4715517Snate@binkert.org######################################################################## 4725517Snate@binkert.org# 4735517Snate@binkert.org# Set some compiler variables 4745517Snate@binkert.org# 4755517Snate@binkert.org 4765517Snate@binkert.org# Include file paths are rooted in this directory. SCons will 4775517Snate@binkert.org# automatically expand '.' to refer to both the source directory and 4786654Snate@binkert.org# the corresponding build directory to pick up generated include 4795517Snate@binkert.org# files. 4805517Snate@binkert.orgenv.Append(CPPPATH=Dir('.')) 4815517Snate@binkert.org 4825517Snate@binkert.orgfor extra_dir in extras_dir_list: 4835517Snate@binkert.org env.Append(CPPPATH=Dir(extra_dir)) 48411802Sandreas.sandberg@arm.com 4855517Snate@binkert.org# Workaround for bug in SCons version > 0.97d20071212 4865517Snate@binkert.org# Scons bug id: 2006 gem5 Bug id: 308 4876143Snate@binkert.orgfor root, dirs, files in os.walk(base_dir, topdown=True): 4886654Snate@binkert.org Dir(root[len(base_dir) + 1:]) 4895517Snate@binkert.org 4905517Snate@binkert.org######################################################################## 4915517Snate@binkert.org# 4925517Snate@binkert.org# Walk the tree and execute all SConscripts in subdirectories 4935517Snate@binkert.org# 4945517Snate@binkert.org 4955517Snate@binkert.orghere = Dir('.').srcnode().abspath 4965517Snate@binkert.orgfor root, dirs, files in os.walk(base_dir, topdown=True): 4975517Snate@binkert.org if root == here: 4985517Snate@binkert.org # we don't want to recurse back into this SConscript 4995517Snate@binkert.org continue 5005517Snate@binkert.org 5015517Snate@binkert.org if 'SConscript' in files: 5025517Snate@binkert.org build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 5036654Snate@binkert.org Source.set_group(build_dir) 5046654Snate@binkert.org SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 5055517Snate@binkert.org 5065517Snate@binkert.orgfor extra_dir in extras_dir_list: 5076143Snate@binkert.org prefix_len = len(dirname(extra_dir)) + 1 5086143Snate@binkert.org 5096143Snate@binkert.org # Also add the corresponding build directory to pick up generated 5106727Ssteve.reinhardt@amd.com # include files. 5115517Snate@binkert.org env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 5126727Ssteve.reinhardt@amd.com 5135517Snate@binkert.org for root, dirs, files in os.walk(extra_dir, topdown=True): 5145517Snate@binkert.org # if build lives in the extras directory, don't walk down it 5155517Snate@binkert.org if 'build' in dirs: 5166654Snate@binkert.org dirs.remove('build') 5176654Snate@binkert.org 5187673Snate@binkert.org if 'SConscript' in files: 5196654Snate@binkert.org build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 5206654Snate@binkert.org SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 5216654Snate@binkert.org 5226654Snate@binkert.orgfor opt in export_vars: 5235517Snate@binkert.org env.ConfigFile(opt) 5245517Snate@binkert.org 5255517Snate@binkert.orgdef makeTheISA(source, target, env): 5266143Snate@binkert.org isas = [ src.get_contents() for src in source ] 5275517Snate@binkert.org target_isa = env['TARGET_ISA'] 5284762Snate@binkert.org def define(isa): 5295517Snate@binkert.org return isa.upper() + '_ISA' 5305517Snate@binkert.org 5316143Snate@binkert.org def namespace(isa): 5326143Snate@binkert.org return isa[0].upper() + isa[1:].lower() + 'ISA' 5335517Snate@binkert.org 5345517Snate@binkert.org 5355517Snate@binkert.org code = code_formatter() 5365517Snate@binkert.org code('''\ 5375517Snate@binkert.org#ifndef __CONFIG_THE_ISA_HH__ 5385517Snate@binkert.org#define __CONFIG_THE_ISA_HH__ 5395517Snate@binkert.org 5405517Snate@binkert.org''') 5415517Snate@binkert.org 5426143Snate@binkert.org # create defines for the preprocessing and compile-time determination 5435517Snate@binkert.org for i,isa in enumerate(isas): 5446654Snate@binkert.org code('#define $0 $1', define(isa), i + 1) 5456654Snate@binkert.org code() 5466654Snate@binkert.org 5476654Snate@binkert.org # create an enum for any run-time determination of the ISA, we 5486654Snate@binkert.org # reuse the same name as the namespaces 5496654Snate@binkert.org code('enum class Arch {') 5504762Snate@binkert.org for i,isa in enumerate(isas): 5514762Snate@binkert.org if i + 1 == len(isas): 5524762Snate@binkert.org code(' $0 = $1', namespace(isa), define(isa)) 5534762Snate@binkert.org else: 5544762Snate@binkert.org code(' $0 = $1,', namespace(isa), define(isa)) 5557675Snate@binkert.org code('};') 55610584Sandreas.hansson@arm.com 5574762Snate@binkert.org code(''' 5584762Snate@binkert.org 5594762Snate@binkert.org#define THE_ISA ${{define(target_isa)}} 5604762Snate@binkert.org#define TheISA ${{namespace(target_isa)}} 5614382Sbinkertn@umich.edu#define THE_ISA_STR "${{target_isa}}" 5624382Sbinkertn@umich.edu 5635517Snate@binkert.org#endif // __CONFIG_THE_ISA_HH__''') 5646654Snate@binkert.org 5655517Snate@binkert.org code.write(str(target[0])) 5668126Sgblack@eecs.umich.edu 5676654Snate@binkert.orgenv.Command('config/the_isa.hh', map(Value, all_isa_list), 5687673Snate@binkert.org MakeAction(makeTheISA, Transform("CFG ISA", 0))) 5696654Snate@binkert.org 57011802Sandreas.sandberg@arm.comdef makeTheGPUISA(source, target, env): 5716654Snate@binkert.org isas = [ src.get_contents() for src in source ] 5726654Snate@binkert.org target_gpu_isa = env['TARGET_GPU_ISA'] 5736654Snate@binkert.org def define(isa): 5746654Snate@binkert.org return isa.upper() + '_ISA' 57511802Sandreas.sandberg@arm.com 5766669Snate@binkert.org def namespace(isa): 57711802Sandreas.sandberg@arm.com return isa[0].upper() + isa[1:].lower() + 'ISA' 5786669Snate@binkert.org 5796669Snate@binkert.org 5806669Snate@binkert.org code = code_formatter() 5816669Snate@binkert.org code('''\ 5826654Snate@binkert.org#ifndef __CONFIG_THE_GPU_ISA_HH__ 5837673Snate@binkert.org#define __CONFIG_THE_GPU_ISA_HH__ 5845517Snate@binkert.org 5858126Sgblack@eecs.umich.edu''') 5865798Snate@binkert.org 5877756SAli.Saidi@ARM.com # create defines for the preprocessing and compile-time determination 5887816Ssteve.reinhardt@amd.com for i,isa in enumerate(isas): 5895798Snate@binkert.org code('#define $0 $1', define(isa), i + 1) 5905798Snate@binkert.org code() 5915517Snate@binkert.org 5925517Snate@binkert.org # create an enum for any run-time determination of the ISA, we 5937673Snate@binkert.org # reuse the same name as the namespaces 5945517Snate@binkert.org code('enum class GPUArch {') 5955517Snate@binkert.org for i,isa in enumerate(isas): 5967673Snate@binkert.org if i + 1 == len(isas): 5977673Snate@binkert.org code(' $0 = $1', namespace(isa), define(isa)) 5985517Snate@binkert.org else: 5995798Snate@binkert.org code(' $0 = $1,', namespace(isa), define(isa)) 6005798Snate@binkert.org code('};') 6018333Snate@binkert.org 6027816Ssteve.reinhardt@amd.com code(''' 6035798Snate@binkert.org 6045798Snate@binkert.org#define THE_GPU_ISA ${{define(target_gpu_isa)}} 6054762Snate@binkert.org#define TheGpuISA ${{namespace(target_gpu_isa)}} 6064762Snate@binkert.org#define THE_GPU_ISA_STR "${{target_gpu_isa}}" 6074762Snate@binkert.org 6084762Snate@binkert.org#endif // __CONFIG_THE_GPU_ISA_HH__''') 6094762Snate@binkert.org 6108596Ssteve.reinhardt@amd.com code.write(str(target[0])) 6115517Snate@binkert.org 6125517Snate@binkert.orgenv.Command('config/the_gpu_isa.hh', map(Value, all_gpu_isa_list), 61311997Sgabeblack@google.com MakeAction(makeTheGPUISA, Transform("CFG ISA", 0))) 6145517Snate@binkert.org 6155517Snate@binkert.org######################################################################## 6167673Snate@binkert.org# 6178596Ssteve.reinhardt@amd.com# Prevent any SimObjects from being added after this point, they 6187673Snate@binkert.org# should all have been added in the SConscripts above 6195517Snate@binkert.org# 62010458Sandreas.hansson@arm.comSimObject.fixed = True 62110458Sandreas.hansson@arm.com 62210458Sandreas.hansson@arm.comclass DictImporter(object): 62310458Sandreas.hansson@arm.com '''This importer takes a dictionary of arbitrary module names that 62410458Sandreas.hansson@arm.com map to arbitrary filenames.''' 62510458Sandreas.hansson@arm.com def __init__(self, modules): 62610458Sandreas.hansson@arm.com self.modules = modules 62710458Sandreas.hansson@arm.com self.installed = set() 62810458Sandreas.hansson@arm.com 62910458Sandreas.hansson@arm.com def __del__(self): 63010458Sandreas.hansson@arm.com self.unload() 63110458Sandreas.hansson@arm.com 6325517Snate@binkert.org def unload(self): 63311996Sgabeblack@google.com import sys 6345517Snate@binkert.org for module in self.installed: 63511997Sgabeblack@google.com del sys.modules[module] 63611996Sgabeblack@google.com self.installed = set() 6375517Snate@binkert.org 6385517Snate@binkert.org def find_module(self, fullname, path): 6397673Snate@binkert.org if fullname == 'm5.defines': 6407673Snate@binkert.org return self 64111996Sgabeblack@google.com 64211988Sandreas.sandberg@arm.com if fullname == 'm5.objects': 6437673Snate@binkert.org return self 6445517Snate@binkert.org 6458596Ssteve.reinhardt@amd.com if fullname.startswith('_m5'): 6465517Snate@binkert.org return None 6475517Snate@binkert.org 64811997Sgabeblack@google.com source = self.modules.get(fullname, None) 6495517Snate@binkert.org if source is not None and fullname.startswith('m5.objects'): 6505517Snate@binkert.org return self 6517673Snate@binkert.org 6527673Snate@binkert.org return None 6537673Snate@binkert.org 6545517Snate@binkert.org def load_module(self, fullname): 65511988Sandreas.sandberg@arm.com mod = imp.new_module(fullname) 65611997Sgabeblack@google.com sys.modules[fullname] = mod 6578596Ssteve.reinhardt@amd.com self.installed.add(fullname) 6588596Ssteve.reinhardt@amd.com 6598596Ssteve.reinhardt@amd.com mod.__loader__ = self 66011988Sandreas.sandberg@arm.com if fullname == 'm5.objects': 6618596Ssteve.reinhardt@amd.com mod.__path__ = fullname.split('.') 6628596Ssteve.reinhardt@amd.com return mod 6638596Ssteve.reinhardt@amd.com 6644762Snate@binkert.org if fullname == 'm5.defines': 6656143Snate@binkert.org mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 6666143Snate@binkert.org return mod 6676143Snate@binkert.org 6684762Snate@binkert.org source = self.modules[fullname] 6694762Snate@binkert.org if source.modname == '__init__': 6704762Snate@binkert.org mod.__path__ = source.modpath 6717756SAli.Saidi@ARM.com mod.__file__ = source.abspath 6728596Ssteve.reinhardt@amd.com 6734762Snate@binkert.org exec file(source.abspath, 'r') in mod.__dict__ 6744762Snate@binkert.org 67510458Sandreas.hansson@arm.com return mod 67610458Sandreas.hansson@arm.com 67710458Sandreas.hansson@arm.comimport m5.SimObject 67810458Sandreas.hansson@arm.comimport m5.params 67910458Sandreas.hansson@arm.comfrom m5.util import code_formatter 68010458Sandreas.hansson@arm.com 68110458Sandreas.hansson@arm.comm5.SimObject.clear() 68210458Sandreas.hansson@arm.comm5.params.clear() 68310458Sandreas.hansson@arm.com 68410458Sandreas.hansson@arm.com# install the python importer so we can grab stuff from the source 68510458Sandreas.hansson@arm.com# tree itself. We can't have SimObjects added after this point or 68610458Sandreas.hansson@arm.com# else we won't know about them for the rest of the stuff. 68710458Sandreas.hansson@arm.comimporter = DictImporter(PySource.modules) 68810458Sandreas.hansson@arm.comsys.meta_path[0:0] = [ importer ] 68910458Sandreas.hansson@arm.com 69010458Sandreas.hansson@arm.com# import all sim objects so we can populate the all_objects list 69110458Sandreas.hansson@arm.com# make sure that we're working with a list, then let's sort it 69210458Sandreas.hansson@arm.comfor modname in SimObject.modnames: 69310458Sandreas.hansson@arm.com exec('from m5.objects import %s' % modname) 69410458Sandreas.hansson@arm.com 69510458Sandreas.hansson@arm.com# we need to unload all of the currently imported modules so that they 69610458Sandreas.hansson@arm.com# will be re-imported the next time the sconscript is run 69710458Sandreas.hansson@arm.comimporter.unload() 69810458Sandreas.hansson@arm.comsys.meta_path.remove(importer) 69910458Sandreas.hansson@arm.com 70010458Sandreas.hansson@arm.comsim_objects = m5.SimObject.allClasses 70110458Sandreas.hansson@arm.comall_enums = m5.params.allEnums 70210458Sandreas.hansson@arm.com 70310458Sandreas.hansson@arm.comfor name,obj in sorted(sim_objects.iteritems()): 70410458Sandreas.hansson@arm.com for param in obj._params.local.values(): 70510458Sandreas.hansson@arm.com # load the ptype attribute now because it depends on the 70610458Sandreas.hansson@arm.com # current version of SimObject.allClasses, but when scons 70710458Sandreas.hansson@arm.com # actually uses the value, all versions of 70810458Sandreas.hansson@arm.com # SimObject.allClasses will have been loaded 70910458Sandreas.hansson@arm.com param.ptype 71010458Sandreas.hansson@arm.com 71110458Sandreas.hansson@arm.com######################################################################## 71210458Sandreas.hansson@arm.com# 71310458Sandreas.hansson@arm.com# calculate extra dependencies 71410458Sandreas.hansson@arm.com# 71510458Sandreas.hansson@arm.commodule_depends = ["m5", "m5.SimObject", "m5.params"] 71610458Sandreas.hansson@arm.comdepends = [ PySource.modules[dep].snode for dep in module_depends ] 71710458Sandreas.hansson@arm.comdepends.sort(key = lambda x: x.name) 71810458Sandreas.hansson@arm.com 71910458Sandreas.hansson@arm.com######################################################################## 72010458Sandreas.hansson@arm.com# 72110458Sandreas.hansson@arm.com# Commands for the basic automatically generated python files 72210458Sandreas.hansson@arm.com# 72310458Sandreas.hansson@arm.com 72410584Sandreas.hansson@arm.com# Generate Python file containing a dict specifying the current 72510458Sandreas.hansson@arm.com# buildEnv flags. 72610458Sandreas.hansson@arm.comdef makeDefinesPyFile(target, source, env): 72710458Sandreas.hansson@arm.com build_env = source[0].get_contents() 72810458Sandreas.hansson@arm.com 72910458Sandreas.hansson@arm.com code = code_formatter() 7304762Snate@binkert.org code(""" 7316143Snate@binkert.orgimport _m5.core 7326143Snate@binkert.orgimport m5.util 7336143Snate@binkert.org 7344762Snate@binkert.orgbuildEnv = m5.util.SmartDict($build_env) 7354762Snate@binkert.org 73611996Sgabeblack@google.comcompileDate = _m5.core.compileDate 7377816Ssteve.reinhardt@amd.com_globals = globals() 7384762Snate@binkert.orgfor key,val in _m5.core.__dict__.iteritems(): 7394762Snate@binkert.org if key.startswith('flag_'): 7404762Snate@binkert.org flag = key[5:] 7414762Snate@binkert.org _globals[flag] = val 7427756SAli.Saidi@ARM.comdel _globals 7438596Ssteve.reinhardt@amd.com""") 7444762Snate@binkert.org code.write(target[0].abspath) 7454762Snate@binkert.org 74611988Sandreas.sandberg@arm.comdefines_info = Value(build_env) 74711988Sandreas.sandberg@arm.com# Generate a file with all of the compile options in it 74811988Sandreas.sandberg@arm.comenv.Command('python/m5/defines.py', defines_info, 74911988Sandreas.sandberg@arm.com MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 75011988Sandreas.sandberg@arm.comPySource('m5', 'python/m5/defines.py') 75111988Sandreas.sandberg@arm.com 75211988Sandreas.sandberg@arm.com# Generate python file containing info about the M5 source code 75311988Sandreas.sandberg@arm.comdef makeInfoPyFile(target, source, env): 75411988Sandreas.sandberg@arm.com code = code_formatter() 75511988Sandreas.sandberg@arm.com for src in source: 75611988Sandreas.sandberg@arm.com data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 7574382Sbinkertn@umich.edu code('$src = ${{repr(data)}}') 7589396Sandreas.hansson@arm.com code.write(str(target[0])) 7599396Sandreas.hansson@arm.com 7609396Sandreas.hansson@arm.com# Generate a file that wraps the basic top level files 7619396Sandreas.hansson@arm.comenv.Command('python/m5/info.py', 7629396Sandreas.hansson@arm.com [ '#/COPYING', '#/LICENSE', '#/README', ], 7639396Sandreas.hansson@arm.com MakeAction(makeInfoPyFile, Transform("INFO"))) 7649396Sandreas.hansson@arm.comPySource('m5', 'python/m5/info.py') 7659396Sandreas.hansson@arm.com 7669396Sandreas.hansson@arm.com######################################################################## 7679396Sandreas.hansson@arm.com# 7689396Sandreas.hansson@arm.com# Create all of the SimObject param headers and enum headers 7699396Sandreas.hansson@arm.com# 7709396Sandreas.hansson@arm.com 7719396Sandreas.hansson@arm.comdef createSimObjectParamStruct(target, source, env): 7729396Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 1 7739396Sandreas.hansson@arm.com 7749396Sandreas.hansson@arm.com name = source[0].get_text_contents() 7759396Sandreas.hansson@arm.com obj = sim_objects[name] 7768232Snate@binkert.org 7778232Snate@binkert.org code = code_formatter() 7788232Snate@binkert.org obj.cxx_param_decl(code) 7798232Snate@binkert.org code.write(target[0].abspath) 7808232Snate@binkert.org 7816229Snate@binkert.orgdef createSimObjectCxxConfig(is_header): 78210455SCurtis.Dunham@arm.com def body(target, source, env): 7836229Snate@binkert.org assert len(target) == 1 and len(source) == 1 78410455SCurtis.Dunham@arm.com 78510455SCurtis.Dunham@arm.com name = str(source[0].get_contents()) 78610455SCurtis.Dunham@arm.com obj = sim_objects[name] 7875517Snate@binkert.org 7885517Snate@binkert.org code = code_formatter() 7897673Snate@binkert.org obj.cxx_config_param_file(code, is_header) 7905517Snate@binkert.org code.write(target[0].abspath) 79110455SCurtis.Dunham@arm.com return body 7925517Snate@binkert.org 7935517Snate@binkert.orgdef createEnumStrings(target, source, env): 7948232Snate@binkert.org assert len(target) == 1 and len(source) == 2 79510455SCurtis.Dunham@arm.com 79610455SCurtis.Dunham@arm.com name = source[0].get_text_contents() 79710455SCurtis.Dunham@arm.com use_python = source[1].read() 7987673Snate@binkert.org obj = all_enums[name] 7997673Snate@binkert.org 80010455SCurtis.Dunham@arm.com code = code_formatter() 80110455SCurtis.Dunham@arm.com obj.cxx_def(code) 80210455SCurtis.Dunham@arm.com if use_python: 8035517Snate@binkert.org obj.pybind_def(code) 80410455SCurtis.Dunham@arm.com code.write(target[0].abspath) 80510455SCurtis.Dunham@arm.com 80610455SCurtis.Dunham@arm.comdef createEnumDecls(target, source, env): 80710455SCurtis.Dunham@arm.com assert len(target) == 1 and len(source) == 1 80810455SCurtis.Dunham@arm.com 80910455SCurtis.Dunham@arm.com name = source[0].get_text_contents() 81010455SCurtis.Dunham@arm.com obj = all_enums[name] 81110455SCurtis.Dunham@arm.com 81210685Sandreas.hansson@arm.com code = code_formatter() 81310455SCurtis.Dunham@arm.com obj.cxx_decl(code) 81410685Sandreas.hansson@arm.com code.write(target[0].abspath) 81510455SCurtis.Dunham@arm.com 8165517Snate@binkert.orgdef createSimObjectPyBindWrapper(target, source, env): 81710455SCurtis.Dunham@arm.com name = source[0].get_text_contents() 8188232Snate@binkert.org obj = sim_objects[name] 8198232Snate@binkert.org 8205517Snate@binkert.org code = code_formatter() 8217673Snate@binkert.org obj.pybind_decl(code) 8225517Snate@binkert.org code.write(target[0].abspath) 8238232Snate@binkert.org 8248232Snate@binkert.org# Generate all of the SimObject param C++ struct header files 8255517Snate@binkert.orgparams_hh_files = [] 8268232Snate@binkert.orgfor name,simobj in sorted(sim_objects.iteritems()): 8278232Snate@binkert.org py_source = PySource.modules[simobj.__module__] 8288232Snate@binkert.org extra_deps = [ py_source.tnode ] 8297673Snate@binkert.org 8305517Snate@binkert.org hh_file = File('params/%s.hh' % name) 8315517Snate@binkert.org params_hh_files.append(hh_file) 8327673Snate@binkert.org env.Command(hh_file, Value(name), 8335517Snate@binkert.org MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 83410455SCurtis.Dunham@arm.com env.Depends(hh_file, depends + extra_deps) 8355517Snate@binkert.org 8365517Snate@binkert.org# C++ parameter description files 8378232Snate@binkert.orgif GetOption('with_cxx_config'): 8388232Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 8395517Snate@binkert.org py_source = PySource.modules[simobj.__module__] 8408232Snate@binkert.org extra_deps = [ py_source.tnode ] 8418232Snate@binkert.org 8425517Snate@binkert.org cxx_config_hh_file = File('cxx_config/%s.hh' % name) 8438232Snate@binkert.org cxx_config_cc_file = File('cxx_config/%s.cc' % name) 8448232Snate@binkert.org env.Command(cxx_config_hh_file, Value(name), 8458232Snate@binkert.org MakeAction(createSimObjectCxxConfig(True), 8465517Snate@binkert.org Transform("CXXCPRHH"))) 8478232Snate@binkert.org env.Command(cxx_config_cc_file, Value(name), 8488232Snate@binkert.org MakeAction(createSimObjectCxxConfig(False), 8498232Snate@binkert.org Transform("CXXCPRCC"))) 8508232Snate@binkert.org env.Depends(cxx_config_hh_file, depends + extra_deps + 8518232Snate@binkert.org [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 8528232Snate@binkert.org env.Depends(cxx_config_cc_file, depends + extra_deps + 8535517Snate@binkert.org [cxx_config_hh_file]) 8548232Snate@binkert.org Source(cxx_config_cc_file) 8558232Snate@binkert.org 8565517Snate@binkert.org cxx_config_init_cc_file = File('cxx_config/init.cc') 8578232Snate@binkert.org 8587673Snate@binkert.org def createCxxConfigInitCC(target, source, env): 8595517Snate@binkert.org assert len(target) == 1 and len(source) == 1 8607673Snate@binkert.org 8615517Snate@binkert.org code = code_formatter() 8628232Snate@binkert.org 8638232Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 8648232Snate@binkert.org if not hasattr(simobj, 'abstract') or not simobj.abstract: 8655192Ssaidi@eecs.umich.edu code('#include "cxx_config/${name}.hh"') 86610454SCurtis.Dunham@arm.com code() 86710454SCurtis.Dunham@arm.com code('void cxxConfigInit()') 8688232Snate@binkert.org code('{') 86910455SCurtis.Dunham@arm.com code.indent() 87010455SCurtis.Dunham@arm.com for name,simobj in sorted(sim_objects.iteritems()): 87110455SCurtis.Dunham@arm.com not_abstract = not hasattr(simobj, 'abstract') or \ 87210455SCurtis.Dunham@arm.com not simobj.abstract 8735192Ssaidi@eecs.umich.edu if not_abstract and 'type' in simobj.__dict__: 87411077SCurtis.Dunham@arm.com code('cxx_config_directory["${name}"] = ' 87511330SCurtis.Dunham@arm.com '${name}CxxConfigParams::makeDirectoryEntry();') 87611077SCurtis.Dunham@arm.com code.dedent() 87711077SCurtis.Dunham@arm.com code('}') 87811077SCurtis.Dunham@arm.com code.write(target[0].abspath) 87911330SCurtis.Dunham@arm.com 88011077SCurtis.Dunham@arm.com py_source = PySource.modules[simobj.__module__] 8817674Snate@binkert.org extra_deps = [ py_source.tnode ] 8825522Snate@binkert.org env.Command(cxx_config_init_cc_file, Value(name), 8835522Snate@binkert.org MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 8847674Snate@binkert.org cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 8857674Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()) 8867674Snate@binkert.org if not hasattr(simobj, 'abstract') or not simobj.abstract] 8877674Snate@binkert.org Depends(cxx_config_init_cc_file, cxx_param_hh_files + 8887674Snate@binkert.org [File('sim/cxx_config.hh')]) 8897674Snate@binkert.org Source(cxx_config_init_cc_file) 8907674Snate@binkert.org 8917674Snate@binkert.org# Generate all enum header files 8925522Snate@binkert.orgfor name,enum in sorted(all_enums.iteritems()): 8935522Snate@binkert.org py_source = PySource.modules[enum.__module__] 8945522Snate@binkert.org extra_deps = [ py_source.tnode ] 8955517Snate@binkert.org 8965522Snate@binkert.org cc_file = File('enums/%s.cc' % name) 8975517Snate@binkert.org env.Command(cc_file, [Value(name), Value(env['USE_PYTHON'])], 8986143Snate@binkert.org MakeAction(createEnumStrings, Transform("ENUM STR"))) 8996727Ssteve.reinhardt@amd.com env.Depends(cc_file, depends + extra_deps) 9005522Snate@binkert.org Source(cc_file) 9015522Snate@binkert.org 9025522Snate@binkert.org hh_file = File('enums/%s.hh' % name) 9037674Snate@binkert.org env.Command(hh_file, Value(name), 9045517Snate@binkert.org MakeAction(createEnumDecls, Transform("ENUMDECL"))) 9057673Snate@binkert.org env.Depends(hh_file, depends + extra_deps) 9067673Snate@binkert.org 9077674Snate@binkert.org# Generate SimObject Python bindings wrapper files 9087673Snate@binkert.orgif env['USE_PYTHON']: 9097674Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 9107674Snate@binkert.org py_source = PySource.modules[simobj.__module__] 9118946Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 9127674Snate@binkert.org cc_file = File('python/_m5/param_%s.cc' % name) 9137674Snate@binkert.org env.Command(cc_file, Value(name), 9147674Snate@binkert.org MakeAction(createSimObjectPyBindWrapper, 9155522Snate@binkert.org Transform("SO PyBind"))) 9165522Snate@binkert.org env.Depends(cc_file, depends + extra_deps) 9177674Snate@binkert.org Source(cc_file) 9187674Snate@binkert.org 91911308Santhony.gutierrez@amd.com# Build all protocol buffers if we have got protoc and protobuf available 9207674Snate@binkert.orgif env['HAVE_PROTOBUF']: 9217673Snate@binkert.org for proto in ProtoBuf.all: 9227674Snate@binkert.org # Use both the source and header as the target, and the .proto 9237674Snate@binkert.org # file as the source. When executing the protoc compiler, also 9247674Snate@binkert.org # specify the proto_path to avoid having the generated files 9257674Snate@binkert.org # include the path. 9267674Snate@binkert.org env.Command([proto.cc_file, proto.hh_file], proto.tnode, 9277674Snate@binkert.org MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 9287674Snate@binkert.org '--proto_path ${SOURCE.dir} $SOURCE', 9297674Snate@binkert.org Transform("PROTOC"))) 9307811Ssteve.reinhardt@amd.com 9317674Snate@binkert.org # Add the C++ source file 9327673Snate@binkert.org Source(proto.cc_file, tags=proto.tags) 9335522Snate@binkert.orgelif ProtoBuf.all: 9346143Snate@binkert.org print('Got protobuf to build, but lacks support!') 93510453SAndrew.Bardsley@arm.com Exit(1) 9367816Ssteve.reinhardt@amd.com 93710453SAndrew.Bardsley@arm.com# 9384382Sbinkertn@umich.edu# Handle debug flags 9394382Sbinkertn@umich.edu# 9404382Sbinkertn@umich.edudef makeDebugFlagCC(target, source, env): 9414382Sbinkertn@umich.edu assert(len(target) == 1 and len(source) == 1) 9424382Sbinkertn@umich.edu 9434382Sbinkertn@umich.edu code = code_formatter() 9444382Sbinkertn@umich.edu 9454382Sbinkertn@umich.edu # delay definition of CompoundFlags until after all the definition 94610196SCurtis.Dunham@arm.com # of all constituent SimpleFlags 9474382Sbinkertn@umich.edu comp_code = code_formatter() 9482655Sstever@eecs.umich.edu 9492655Sstever@eecs.umich.edu # file header 9502655Sstever@eecs.umich.edu code(''' 9512655Sstever@eecs.umich.edu/* 95212063Sgabeblack@google.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 9535601Snate@binkert.org */ 9545601Snate@binkert.org 95512222Sgabeblack@google.com#include "base/debug.hh" 95612222Sgabeblack@google.com 95712222Sgabeblack@google.comnamespace Debug { 9585522Snate@binkert.org 9595863Snate@binkert.org''') 9605601Snate@binkert.org 9615601Snate@binkert.org for name, flag in sorted(source[0].read().iteritems()): 9625601Snate@binkert.org n, compound, desc = flag 9635559Snate@binkert.org assert n == name 96411718Sjoseph.gross@amd.com 96511718Sjoseph.gross@amd.com if not compound: 96611718Sjoseph.gross@amd.com code('SimpleFlag $name("$name", "$desc");') 96711718Sjoseph.gross@amd.com else: 96811718Sjoseph.gross@amd.com comp_code('CompoundFlag $name("$name", "$desc",') 96911718Sjoseph.gross@amd.com comp_code.indent() 97011718Sjoseph.gross@amd.com last = len(compound) - 1 97111718Sjoseph.gross@amd.com for i,flag in enumerate(compound): 97211718Sjoseph.gross@amd.com if i != last: 97311718Sjoseph.gross@amd.com comp_code('&$flag,') 97411718Sjoseph.gross@amd.com else: 97510457Sandreas.hansson@arm.com comp_code('&$flag);') 97610457Sandreas.hansson@arm.com comp_code.dedent() 97710457Sandreas.hansson@arm.com 97811718Sjoseph.gross@amd.com code.append(comp_code) 97910457Sandreas.hansson@arm.com code() 98010457Sandreas.hansson@arm.com code('} // namespace Debug') 98110457Sandreas.hansson@arm.com 98210457Sandreas.hansson@arm.com code.write(str(target[0])) 98311342Sandreas.hansson@arm.com 9848737Skoansin.tan@gmail.comdef makeDebugFlagHH(target, source, env): 98511342Sandreas.hansson@arm.com assert(len(target) == 1 and len(source) == 1) 98611342Sandreas.hansson@arm.com 98710457Sandreas.hansson@arm.com val = eval(source[0].get_contents()) 98811718Sjoseph.gross@amd.com name, compound, desc = val 98911718Sjoseph.gross@amd.com 99011718Sjoseph.gross@amd.com code = code_formatter() 99111718Sjoseph.gross@amd.com 99211718Sjoseph.gross@amd.com # file header boilerplate 99311718Sjoseph.gross@amd.com code('''\ 99411718Sjoseph.gross@amd.com/* 99510457Sandreas.hansson@arm.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 99611718Sjoseph.gross@amd.com */ 99711500Sandreas.hansson@arm.com 99811500Sandreas.hansson@arm.com#ifndef __DEBUG_${name}_HH__ 99911342Sandreas.hansson@arm.com#define __DEBUG_${name}_HH__ 100011342Sandreas.hansson@arm.com 10018945Ssteve.reinhardt@amd.comnamespace Debug { 100210686SAndreas.Sandberg@ARM.com''') 100310686SAndreas.Sandberg@ARM.com 100410686SAndreas.Sandberg@ARM.com if compound: 100510686SAndreas.Sandberg@ARM.com code('class CompoundFlag;') 100610686SAndreas.Sandberg@ARM.com code('class SimpleFlag;') 100710686SAndreas.Sandberg@ARM.com 10088945Ssteve.reinhardt@amd.com if compound: 10096143Snate@binkert.org code('extern CompoundFlag $name;') 10106143Snate@binkert.org for flag in compound: 10116143Snate@binkert.org code('extern SimpleFlag $flag;') 10126143Snate@binkert.org else: 10136143Snate@binkert.org code('extern SimpleFlag $name;') 101411988Sandreas.sandberg@arm.com 10158945Ssteve.reinhardt@amd.com code(''' 10166143Snate@binkert.org} 10176143Snate@binkert.org 10186143Snate@binkert.org#endif // __DEBUG_${name}_HH__ 10196143Snate@binkert.org''') 10206143Snate@binkert.org 10216143Snate@binkert.org code.write(str(target[0])) 10226143Snate@binkert.org 10236143Snate@binkert.orgfor name,flag in sorted(debug_flags.iteritems()): 10246143Snate@binkert.org n, compound, desc = flag 10256143Snate@binkert.org assert n == name 10266143Snate@binkert.org 10276143Snate@binkert.org hh_file = 'debug/%s.hh' % name 10286143Snate@binkert.org env.Command(hh_file, Value(flag), 102910453SAndrew.Bardsley@arm.com MakeAction(makeDebugFlagHH, Transform("TRACING", 0))) 103010453SAndrew.Bardsley@arm.com 103111988Sandreas.sandberg@arm.comenv.Command('debug/flags.cc', Value(debug_flags), 103211988Sandreas.sandberg@arm.com MakeAction(makeDebugFlagCC, Transform("TRACING", 0))) 103310453SAndrew.Bardsley@arm.comSource('debug/flags.cc') 103410453SAndrew.Bardsley@arm.com 103510453SAndrew.Bardsley@arm.com# version tags 103611983Sgabeblack@google.comtags = \ 103711983Sgabeblack@google.comenv.Command('sim/tags.cc', None, 103811983Sgabeblack@google.com MakeAction('util/cpt_upgrader.py --get-cc-file > $TARGET', 103911983Sgabeblack@google.com Transform("VER TAGS"))) 104011983Sgabeblack@google.comenv.AlwaysBuild(tags) 104111983Sgabeblack@google.com 104211983Sgabeblack@google.com# Embed python files. All .py files that have been indicated by a 104311983Sgabeblack@google.com# PySource() call in a SConscript need to be embedded into the M5 104411983Sgabeblack@google.com# library. To do that, we compile the file to byte code, marshal the 104511983Sgabeblack@google.com# byte code, compress it, and then generate a c++ file that 104611983Sgabeblack@google.com# inserts the result into an array. 104711983Sgabeblack@google.comdef embedPyFile(target, source, env): 104811983Sgabeblack@google.com def c_str(string): 104911983Sgabeblack@google.com if string is None: 105011983Sgabeblack@google.com return "0" 105111983Sgabeblack@google.com return '"%s"' % string 105211983Sgabeblack@google.com 105311983Sgabeblack@google.com '''Action function to compile a .py into a code object, marshal 105412063Sgabeblack@google.com it, compress it, and stick it into an asm file so the code appears 105512063Sgabeblack@google.com as just bytes with a label in the data section''' 105612063Sgabeblack@google.com 105712063Sgabeblack@google.com src = file(str(source[0]), 'r').read() 105812063Sgabeblack@google.com 105912063Sgabeblack@google.com pysource = PySource.tnodes[source[0]] 106012063Sgabeblack@google.com compiled = compile(src, pysource.abspath, 'exec') 106112063Sgabeblack@google.com marshalled = marshal.dumps(compiled) 106211983Sgabeblack@google.com compressed = zlib.compress(marshalled) 106311983Sgabeblack@google.com data = compressed 106411983Sgabeblack@google.com sym = pysource.symname 106511983Sgabeblack@google.com 106611983Sgabeblack@google.com code = code_formatter() 106711983Sgabeblack@google.com code('''\ 106811983Sgabeblack@google.com#include "sim/init.hh" 106911983Sgabeblack@google.com 107011983Sgabeblack@google.comnamespace { 107111983Sgabeblack@google.com 107211983Sgabeblack@google.comconst uint8_t data_${sym}[] = { 107311983Sgabeblack@google.com''') 107411983Sgabeblack@google.com code.indent() 10756143Snate@binkert.org step = 16 10766143Snate@binkert.org for i in xrange(0, len(data), step): 10776143Snate@binkert.org x = array.array('B', data[i:i+step]) 107810453SAndrew.Bardsley@arm.com code(''.join('%d,' % d for d in x)) 10796143Snate@binkert.org code.dedent() 10806240Snate@binkert.org 10815554Snate@binkert.org code('''}; 10825522Snate@binkert.org 10835522Snate@binkert.orgEmbeddedPython embedded_${sym}( 10845797Snate@binkert.org ${{c_str(pysource.arcname)}}, 10855797Snate@binkert.org ${{c_str(pysource.abspath)}}, 10865522Snate@binkert.org ${{c_str(pysource.modpath)}}, 10875601Snate@binkert.org data_${sym}, 10888233Snate@binkert.org ${{len(data)}}, 10898233Snate@binkert.org ${{len(marshalled)}}); 10908235Snate@binkert.org 10918235Snate@binkert.org} // anonymous namespace 10928235Snate@binkert.org''') 10938235Snate@binkert.org code.write(str(target[0])) 10949003SAli.Saidi@ARM.com 10959003SAli.Saidi@ARM.comfor source in PySource.all: 109612222Sgabeblack@google.com env.Command(source.cpp, source.tnode, 109710196SCurtis.Dunham@arm.com MakeAction(embedPyFile, Transform("EMBED PY"))) 10988235Snate@binkert.org Source(source.cpp, tags=source.tags, add_tags='python') 10996143Snate@binkert.org 11002655Sstever@eecs.umich.edu######################################################################## 11016143Snate@binkert.org# 11026143Snate@binkert.org# Define binaries. Each different build type (debug, opt, etc.) gets 110311985Sgabeblack@google.com# a slightly different build environment. 11046143Snate@binkert.org# 11056143Snate@binkert.org 11064007Ssaidi@eecs.umich.edu# List of constructed environments to pass back to SConstruct 11074596Sbinkertn@umich.edudate_source = Source('base/date.cc', tags=[]) 11084007Ssaidi@eecs.umich.edu 11094596Sbinkertn@umich.edugem5_binary = Gem5('gem5') 11107756SAli.Saidi@ARM.com 11117816Ssteve.reinhardt@amd.com# Function to create a new build environment as clone of current 11128334Snate@binkert.org# environment 'env' with modified object suffix and optional stripped 11138334Snate@binkert.org# binary. Additional keyword arguments are appended to corresponding 11148334Snate@binkert.org# build environment vars. 11158334Snate@binkert.orgdef makeEnv(env, label, objsfx, strip=False, disable_partial=False, **kwargs): 11165601Snate@binkert.org # SCons doesn't know to append a library suffix when there is a '.' in the 111711993Sgabeblack@google.com # name. Use '_' instead. 111811993Sgabeblack@google.com libname = 'gem5_' + label 111911993Sgabeblack@google.com secondary_exename = 'm5.' + label 112012223Sgabeblack@google.com 112111993Sgabeblack@google.com new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 11222655Sstever@eecs.umich.edu new_env.Label = label 11239225Sandreas.hansson@arm.com new_env.Append(**kwargs) 11249225Sandreas.hansson@arm.com 11259226Sandreas.hansson@arm.com lib_sources = Source.all.with_tag('gem5 lib') 11269226Sandreas.hansson@arm.com 11279225Sandreas.hansson@arm.com # Without Python, leave out all Python content from the library 11289226Sandreas.hansson@arm.com # builds. The option doesn't affect gem5 built as a program 11299226Sandreas.hansson@arm.com if GetOption('without_python'): 11309226Sandreas.hansson@arm.com lib_sources = lib_sources.without_tag('python') 11319226Sandreas.hansson@arm.com 11329226Sandreas.hansson@arm.com static_objs = [] 11339226Sandreas.hansson@arm.com shared_objs = [] 11349225Sandreas.hansson@arm.com 11359227Sandreas.hansson@arm.com for s in lib_sources.with_tag(Source.ungrouped_tag): 11369227Sandreas.hansson@arm.com static_objs.append(s.static(new_env)) 11379227Sandreas.hansson@arm.com shared_objs.append(s.shared(new_env)) 11389227Sandreas.hansson@arm.com 11398946Sandreas.hansson@arm.com for group in Source.source_groups: 11403918Ssaidi@eecs.umich.edu srcs = lib_sources.with_tag(Source.link_group_tag(group)) 11419225Sandreas.hansson@arm.com if not srcs: 11423918Ssaidi@eecs.umich.edu continue 11439225Sandreas.hansson@arm.com 11449225Sandreas.hansson@arm.com group_static = [ s.static(new_env) for s in srcs ] 11459227Sandreas.hansson@arm.com group_shared = [ s.shared(new_env) for s in srcs ] 11469227Sandreas.hansson@arm.com 11479227Sandreas.hansson@arm.com # If partial linking is disabled, add these sources to the build 11489226Sandreas.hansson@arm.com # directly, and short circuit this loop. 11499225Sandreas.hansson@arm.com if disable_partial: 11509227Sandreas.hansson@arm.com static_objs.extend(group_static) 11519227Sandreas.hansson@arm.com shared_objs.extend(group_shared) 11529227Sandreas.hansson@arm.com continue 11539227Sandreas.hansson@arm.com 11548946Sandreas.hansson@arm.com # Set up the static partially linked objects. 11559225Sandreas.hansson@arm.com file_name = new_env.subst("${OBJPREFIX}lib${OBJSUFFIX}.partial") 11569226Sandreas.hansson@arm.com target = File(joinpath(group, file_name)) 11579226Sandreas.hansson@arm.com partial = env.PartialStatic(target=target, source=group_static) 11589226Sandreas.hansson@arm.com static_objs.extend(partial) 11593515Ssaidi@eecs.umich.edu 11603918Ssaidi@eecs.umich.edu # Set up the shared partially linked objects. 11614762Snate@binkert.org file_name = new_env.subst("${SHOBJPREFIX}lib${SHOBJSUFFIX}.partial") 11623515Ssaidi@eecs.umich.edu target = File(joinpath(group, file_name)) 11638881Smarc.orr@gmail.com partial = env.PartialShared(target=target, source=group_shared) 11648881Smarc.orr@gmail.com shared_objs.extend(partial) 11658881Smarc.orr@gmail.com 11668881Smarc.orr@gmail.com static_date = date_source.static(new_env) 11678881Smarc.orr@gmail.com new_env.Depends(static_date, static_objs) 11689226Sandreas.hansson@arm.com static_objs.extend(static_date) 11699226Sandreas.hansson@arm.com 11709226Sandreas.hansson@arm.com shared_date = date_source.shared(new_env) 11718881Smarc.orr@gmail.com new_env.Depends(shared_date, shared_objs) 11728881Smarc.orr@gmail.com shared_objs.extend(shared_date) 11738881Smarc.orr@gmail.com 11748881Smarc.orr@gmail.com main_objs = [ s.static(new_env) for s in Source.all.with_tag('main') ] 11758881Smarc.orr@gmail.com 11768881Smarc.orr@gmail.com # First make a library of everything but main() so other programs can 11778881Smarc.orr@gmail.com # link against m5. 11788881Smarc.orr@gmail.com static_lib = new_env.StaticLibrary(libname, static_objs) 11798881Smarc.orr@gmail.com shared_lib = new_env.SharedLibrary(libname, shared_objs) 11808881Smarc.orr@gmail.com 11818881Smarc.orr@gmail.com # Keep track of the object files generated so far so Executables can 11828881Smarc.orr@gmail.com # include them. 11838881Smarc.orr@gmail.com new_env['STATIC_OBJS'] = static_objs 11848881Smarc.orr@gmail.com new_env['SHARED_OBJS'] = shared_objs 11858881Smarc.orr@gmail.com new_env['MAIN_OBJS'] = main_objs 11868881Smarc.orr@gmail.com 118712222Sgabeblack@google.com new_env['STATIC_LIB'] = static_lib 118812222Sgabeblack@google.com new_env['SHARED_LIB'] = shared_lib 118912222Sgabeblack@google.com 119012222Sgabeblack@google.com # Record some settings for building Executables. 119112222Sgabeblack@google.com new_env['EXE_SUFFIX'] = label 119212222Sgabeblack@google.com new_env['STRIP_EXES'] = strip 1193955SN/A 119412222Sgabeblack@google.com for cls in ExecutableMeta.all: 119512222Sgabeblack@google.com cls.declare_all(new_env) 119612222Sgabeblack@google.com 119712222Sgabeblack@google.com new_env.M5Binary = File(gem5_binary.path(new_env)) 119812222Sgabeblack@google.com 119912222Sgabeblack@google.com new_env.Command(secondary_exename, new_env.M5Binary, 1200955SN/A MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 120112222Sgabeblack@google.com 120212222Sgabeblack@google.com # Set up regression tests. 120312222Sgabeblack@google.com SConscript(os.path.join(env.root.abspath, 'tests', 'SConscript'), 120412222Sgabeblack@google.com variant_dir=Dir('tests').Dir(new_env.Label), 120512222Sgabeblack@google.com exports={ 'env' : new_env }, duplicate=False) 120612222Sgabeblack@google.com 120712222Sgabeblack@google.com# Start out with the compiler flags common to all compilers, 120812222Sgabeblack@google.com# i.e. they all use -g for opt and -g -pg for prof 120912222Sgabeblack@google.comccflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 121012222Sgabeblack@google.com 'perf' : ['-g']} 12111869SN/A 121212222Sgabeblack@google.com# Start out with the linker flags common to all linkers, i.e. -pg for 121312222Sgabeblack@google.com# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 121412222Sgabeblack@google.com# no-as-needed and as-needed as the binutils linker is too clever and 121512222Sgabeblack@google.com# simply doesn't link to the library otherwise. 121612222Sgabeblack@google.comldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 121712222Sgabeblack@google.com 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 12189226Sandreas.hansson@arm.com 121912222Sgabeblack@google.com# For Link Time Optimization, the optimisation flags used to compile 122012222Sgabeblack@google.com# individual files are decoupled from those used at link time 122112222Sgabeblack@google.com# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 122212222Sgabeblack@google.com# to also update the linker flags based on the target. 122312222Sgabeblack@google.comif env['GCC']: 122412222Sgabeblack@google.com if sys.platform == 'sunos5': 1225 ccflags['debug'] += ['-gstabs+'] 1226 else: 1227 ccflags['debug'] += ['-ggdb3'] 1228 ldflags['debug'] += ['-O0'] 1229 # opt, fast, prof and perf all share the same cc flags, also add 1230 # the optimization to the ldflags as LTO defers the optimization 1231 # to link time 1232 for target in ['opt', 'fast', 'prof', 'perf']: 1233 ccflags[target] += ['-O3'] 1234 ldflags[target] += ['-O3'] 1235 1236 ccflags['fast'] += env['LTO_CCFLAGS'] 1237 ldflags['fast'] += env['LTO_LDFLAGS'] 1238elif env['CLANG']: 1239 ccflags['debug'] += ['-g', '-O0'] 1240 # opt, fast, prof and perf all share the same cc flags 1241 for target in ['opt', 'fast', 'prof', 'perf']: 1242 ccflags[target] += ['-O3'] 1243else: 1244 print('Unknown compiler, please fix compiler options') 1245 Exit(1) 1246 1247 1248# To speed things up, we only instantiate the build environments we 1249# need. We try to identify the needed environment for each target; if 1250# we can't, we fall back on instantiating all the environments just to 1251# be safe. 1252target_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 1253obj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 1254 'gpo' : 'perf'} 1255 1256def identifyTarget(t): 1257 ext = t.split('.')[-1] 1258 if ext in target_types: 1259 return ext 1260 if obj2target.has_key(ext): 1261 return obj2target[ext] 1262 match = re.search(r'/tests/([^/]+)/', t) 1263 if match and match.group(1) in target_types: 1264 return match.group(1) 1265 return 'all' 1266 1267needed_envs = [identifyTarget(target) for target in BUILD_TARGETS] 1268if 'all' in needed_envs: 1269 needed_envs += target_types 1270 1271disable_partial = False 1272if env['PLATFORM'] == 'darwin': 1273 # Up until Apple LLVM version 10.0.0 (clang-1000.11.45.5), partial 1274 # linked objects do not expose symbols that are marked with the 1275 # hidden visibility and consequently building gem5 on Mac OS 1276 # fails. As a workaround, we disable partial linking, however, we 1277 # may want to revisit in the future. 1278 disable_partial = True 1279 1280# Debug binary 1281if 'debug' in needed_envs: 1282 makeEnv(env, 'debug', '.do', 1283 CCFLAGS = Split(ccflags['debug']), 1284 CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 1285 LINKFLAGS = Split(ldflags['debug']), 1286 disable_partial=disable_partial) 1287 1288# Optimized binary 1289if 'opt' in needed_envs: 1290 makeEnv(env, 'opt', '.o', 1291 CCFLAGS = Split(ccflags['opt']), 1292 CPPDEFINES = ['TRACING_ON=1'], 1293 LINKFLAGS = Split(ldflags['opt']), 1294 disable_partial=disable_partial) 1295 1296# "Fast" binary 1297if 'fast' in needed_envs: 1298 disable_partial = disable_partial and \ 1299 env.get('BROKEN_INCREMENTAL_LTO', False) and \ 1300 GetOption('force_lto') 1301 makeEnv(env, 'fast', '.fo', strip = True, 1302 CCFLAGS = Split(ccflags['fast']), 1303 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1304 LINKFLAGS = Split(ldflags['fast']), 1305 disable_partial=disable_partial) 1306 1307# Profiled binary using gprof 1308if 'prof' in needed_envs: 1309 makeEnv(env, 'prof', '.po', 1310 CCFLAGS = Split(ccflags['prof']), 1311 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1312 LINKFLAGS = Split(ldflags['prof']), 1313 disable_partial=disable_partial) 1314 1315# Profiled binary using google-pprof 1316if 'perf' in needed_envs: 1317 makeEnv(env, 'perf', '.gpo', 1318 CCFLAGS = Split(ccflags['perf']), 1319 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1320 LINKFLAGS = Split(ldflags['perf']), 1321 disable_partial=disable_partial) 1322