| # Copyright 2020 Google, Inc. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are |
| # met: redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer; |
| # redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution; |
| # neither the name of the copyright holders nor the names of its |
| # contributors may be used to endorse or promote products derived from |
| # this software without specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| import copy |
| import os |
| |
| main = Environment() |
| |
| gem5_root = Dir('..').Dir('..') |
| |
| # Includes which are shared with gem5 itself. |
| common_include = gem5_root.Dir('include') |
| |
| ext_dir = gem5_root.Dir('ext') |
| googletest_dir = ext_dir.Dir('googletest') |
| |
| src_dir = Dir('src') |
| build_dir = Dir('build') |
| |
| def abspath(d): |
| return os.path.abspath(str(d)) |
| |
| # Universal settings. |
| main.Append(CXXFLAGS=[ '-O2' ]) |
| main.Append(CCFLAGS=[ '-O2' ]) |
| main.Append(CPPPATH=[ common_include ]) |
| |
| # Propogate the environment's PATH setting. |
| main['ENV']['PATH'] = os.environ['PATH'] |
| |
| # Detect some dependencies of some forms of the m5 utility/library. |
| main['HAVE_JAVA'] = all(key in main for key in ('JAVAC', 'JAR')) |
| main['HAVE_PKG_CONFIG'] = main.Detect('pkg-config') is not None |
| main['HAVE_LUA51'] = (main['HAVE_PKG_CONFIG'] and |
| os.system('pkg-config --exists lua51') == 0) |
| |
| # Put the sconsign file in the build dir so everything can be deleted at once. |
| main.SConsignFile(os.path.join(abspath(build_dir), 'sconsign')) |
| # Use soft links instead of hard links when setting up a build directory. |
| main.SetOption('duplicate', 'soft-copy') |
| |
| def GTest(env, name, *srcs, **kwargs): |
| if 'GTEST_ENV' not in env: |
| gtest_env = env.Clone(OBJSUFFIX='.to', SHOBJSUFFIX='.sto') |
| gtest_env.Append(CPPFLAGS=[ '${GTEST_CPPFLAGS}' ]) |
| gtest_env.Append(LIBS=[ '${GTEST_LIBS}' ]) |
| env['GTEST_ENV'] = gtest_env |
| |
| if not srcs: |
| srcs = [ name + '.cc', name + '.test.cc' ] |
| env['GTEST_ENV'].Program('test/%s' % name, srcs, **kwargs) |
| |
| main.AddMethod(GTest) |
| |
| native = main.Clone() |
| native_dir = build_dir.Dir('native') |
| |
| # Bring in the googletest sources. |
| native.SConscript(googletest_dir.File('SConscript'), |
| variant_dir=native_dir.Dir('googletest'), exports={ 'main': native }) |
| |
| native.SConscript(src_dir.File('SConscript.native'), |
| variant_dir=native_dir, exports={ 'env': native }) |
| |
| main['CC'] = '${CROSS_COMPILE}gcc' |
| main['CXX'] = '${CROSS_COMPILE}g++' |
| main['AS'] = '${CROSS_COMPILE}as' |
| main['LD'] = '${CROSS_COMPILE}ld' |
| main['AR'] = '${CROSS_COMPILE}ar' |
| |
| class CallType(object): |
| def __init__(self, name): |
| self.name = name |
| self.impl_file = None |
| self.enabled = False |
| self.verifier = None |
| self.default = False |
| |
| def impl(self, impl, verifier=None, default=False): |
| self.impl_file = impl |
| self.enabled = True |
| self.verifier = verifier |
| self.default = default |
| |
| # Being the default can be disabled for testing purposes, so we can tell if |
| # a call type was selected because it was chosen, or because nobody else |
| # was. |
| def setup_env(self, env, allow_default=True): |
| env = env.Clone() |
| is_default = 'true' if self.default and allow_default else 'false' |
| env.Append(CXXFLAGS=[ '-DCALL_TYPE_IS_DEFAULT=%s' % is_default ]) |
| return env |
| |
| call_types = { |
| # Magic instruction. |
| 'inst': CallType('inst'), |
| # Magic address. |
| 'addr': CallType('addr'), |
| # Semihosting extension. |
| 'semi': CallType('semi'), |
| } |
| |
| for root, dirs, files in os.walk(abspath(src_dir)): |
| # Each SConsopts file describes an ABI of the m5 utility. |
| if 'SConsopts' in files: |
| env = main.Clone() |
| |
| env['CALL_TYPE'] = copy.deepcopy(call_types) |
| |
| # The user may override ABI settings by setting environment |
| # variables of the form ${ABI}.${OPTION}. For instance, to set the |
| # CROSS_COMPILE prefix for abi foo to bar-, the user would set an |
| # environment variable foo.CROSS_COMPILE=bar-. |
| # |
| # This also considers scons command line settings which may look like |
| # environment variables, but are set after "scons" on the command line. |
| def get_abi_opt(name, default): |
| var_name = env.subst('${ABI}.%s' % name) |
| env[name] = os.environ.get( |
| var_name, ARGUMENTS.get(var_name, default)) |
| |
| # Process the ABI's settings in the SConsopts file, storing them |
| # in a copy of the primary environment. |
| env.SConscript(Dir(root).File('SConsopts'), |
| exports=[ 'env', 'get_abi_opt' ]) |
| |
| # Once all the options have been configured, set up build targets for |
| # this abi. |
| abi_dir = build_dir.Dir(env.subst('${ABI}')) |
| # Bring in the googletest sources. |
| env.SConscript(googletest_dir.File('SConscript'), |
| variant_dir=abi_dir.Dir('googletest'), |
| exports={ 'main': env }) |
| env.SConscript(src_dir.File('SConscript'), |
| variant_dir=abi_dir, exports='env') |