misc: Run pre-commit run on all files in repo
The following command was run: ``` pre-commit run --all-files ``` This ensures all the files in the repository are formatted to pass our checks. Change-Id: Ia2fe3529a50ad925d1076a612d60a4280adc40de Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/62572 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
committed by
Bobby Bruce
parent
64add0e04d
commit
2bc5a8b71a
@@ -52,34 +52,38 @@ import SCons.Script
|
||||
|
||||
termcap = get_termcap()
|
||||
|
||||
|
||||
def strip_build_path(path, env):
|
||||
path = str(path)
|
||||
build_base = 'build/'
|
||||
variant_base = env['BUILDROOT'] + os.path.sep
|
||||
build_base = "build/"
|
||||
variant_base = env["BUILDROOT"] + os.path.sep
|
||||
if path.startswith(variant_base):
|
||||
path = path[len(variant_base):]
|
||||
path = path[len(variant_base) :]
|
||||
elif path.startswith(build_base):
|
||||
path = path[len(build_base):]
|
||||
path = path[len(build_base) :]
|
||||
return path
|
||||
|
||||
|
||||
def TempFileSpawn(scons_env):
|
||||
old_pspawn = scons_env['PSPAWN']
|
||||
old_spawn = scons_env['SPAWN']
|
||||
old_pspawn = scons_env["PSPAWN"]
|
||||
old_spawn = scons_env["SPAWN"]
|
||||
|
||||
def wrapper(old, sh, esc, cmd, sh_args, *py_args):
|
||||
with tempfile.NamedTemporaryFile() as temp:
|
||||
temp.write(' '.join(sh_args).encode())
|
||||
temp.write(" ".join(sh_args).encode())
|
||||
temp.flush()
|
||||
sh_args = [sh, esc(temp.name)]
|
||||
return old(sh, esc, sh, sh_args, *py_args)
|
||||
|
||||
def new_pspawn(sh, esc, cmd, args, sh_env, stdout, stderr):
|
||||
return wrapper(old_pspawn, sh, esc, cmd, args, sh_env, stdout, stderr)
|
||||
|
||||
def new_spawn(sh, esc, cmd, args, sh_env):
|
||||
return wrapper(old_spawn, sh, esc, cmd, args, sh_env)
|
||||
|
||||
scons_env['PSPAWN'] = new_pspawn
|
||||
scons_env['SPAWN'] = new_spawn
|
||||
scons_env["PSPAWN"] = new_pspawn
|
||||
scons_env["SPAWN"] = new_spawn
|
||||
|
||||
|
||||
# Generate a string of the form:
|
||||
# common/path/prefix/src1, src2 -> tgt1, tgt2
|
||||
@@ -93,23 +97,32 @@ class Transform(object):
|
||||
tgts_color = termcap.Yellow + termcap.Bold
|
||||
|
||||
def __init__(self, tool, max_sources=99):
|
||||
self.format = self.tool_color + (" [%8s] " % tool) \
|
||||
+ self.pfx_color + "%s" \
|
||||
+ self.srcs_color + "%s" \
|
||||
+ self.arrow_color + " -> " \
|
||||
+ self.tgts_color + "%s" \
|
||||
+ termcap.Normal
|
||||
self.format = (
|
||||
self.tool_color
|
||||
+ (" [%8s] " % tool)
|
||||
+ self.pfx_color
|
||||
+ "%s"
|
||||
+ self.srcs_color
|
||||
+ "%s"
|
||||
+ self.arrow_color
|
||||
+ " -> "
|
||||
+ self.tgts_color
|
||||
+ "%s"
|
||||
+ termcap.Normal
|
||||
)
|
||||
self.max_sources = max_sources
|
||||
|
||||
def __call__(self, target, source, env, for_signature=None):
|
||||
# truncate source list according to max_sources param
|
||||
source = source[0:self.max_sources]
|
||||
source = source[0 : self.max_sources]
|
||||
|
||||
def strip(f):
|
||||
return strip_build_path(str(f), env)
|
||||
|
||||
if len(source) > 0:
|
||||
srcs = list(map(strip, source))
|
||||
else:
|
||||
srcs = ['']
|
||||
srcs = [""]
|
||||
tgts = list(map(strip, target))
|
||||
# surprisingly, os.path.commonprefix is a dumb char-by-char string
|
||||
# operation that has nothing to do with paths.
|
||||
@@ -137,20 +150,23 @@ class Transform(object):
|
||||
if sep_idx != -1:
|
||||
com_pfx = com_pfx[0:sep_idx]
|
||||
else:
|
||||
com_pfx = ''
|
||||
com_pfx = ""
|
||||
elif src0_len > com_pfx_len and srcs[0][com_pfx_len] == ".":
|
||||
# still splitting at file extension: ok
|
||||
pass
|
||||
else:
|
||||
# probably a fluke; ignore it
|
||||
com_pfx = ''
|
||||
com_pfx = ""
|
||||
# recalculate length in case com_pfx was modified
|
||||
com_pfx_len = len(com_pfx)
|
||||
|
||||
def fmt(files):
|
||||
f = list(map(lambda s: s[com_pfx_len:], files))
|
||||
return ', '.join(f)
|
||||
return ", ".join(f)
|
||||
|
||||
return self.format % (com_pfx, fmt(srcs), fmt(tgts))
|
||||
|
||||
|
||||
# The width warning and error messages should be wrapped at.
|
||||
text_width = None
|
||||
|
||||
@@ -162,6 +178,7 @@ if not sys.stdout.isatty():
|
||||
if text_width is None:
|
||||
try:
|
||||
import shutil
|
||||
|
||||
text_width = shutil.get_terminal_size().columns
|
||||
except:
|
||||
pass
|
||||
@@ -170,6 +187,7 @@ if text_width is None:
|
||||
if text_width is None:
|
||||
try:
|
||||
import curses
|
||||
|
||||
try:
|
||||
_, text_width = curses.initscr().getmaxyx()
|
||||
finally:
|
||||
@@ -181,21 +199,22 @@ if text_width is None:
|
||||
if text_width is None:
|
||||
text_width = 80
|
||||
|
||||
|
||||
def print_message(prefix, color, message, **kwargs):
|
||||
prefix_len = len(prefix)
|
||||
if text_width > prefix_len:
|
||||
wrap_width = text_width - prefix_len
|
||||
padding = ' ' * prefix_len
|
||||
padding = " " * prefix_len
|
||||
|
||||
# First split on newlines.
|
||||
lines = message.split('\n')
|
||||
lines = message.split("\n")
|
||||
# Then wrap each line to the required width.
|
||||
wrapped_lines = []
|
||||
for line in lines:
|
||||
wrapped_lines.extend(textwrap.wrap(line, wrap_width))
|
||||
# Finally add the prefix and padding on extra lines, and glue it all
|
||||
# back together.
|
||||
message = prefix + ('\n' + padding).join(wrapped_lines)
|
||||
message = prefix + ("\n" + padding).join(wrapped_lines)
|
||||
else:
|
||||
# We have very small terminal, indent formatting doesn't help.
|
||||
message = prefix + message
|
||||
@@ -205,27 +224,36 @@ def print_message(prefix, color, message, **kwargs):
|
||||
print(message, **kwargs)
|
||||
return message
|
||||
|
||||
|
||||
all_warnings = []
|
||||
|
||||
|
||||
def summarize_warnings():
|
||||
if not all_warnings:
|
||||
return
|
||||
print(termcap.Yellow + termcap.Bold +
|
||||
'*** Summary of Warnings ***' +
|
||||
termcap.Normal)
|
||||
print(
|
||||
termcap.Yellow
|
||||
+ termcap.Bold
|
||||
+ "*** Summary of Warnings ***"
|
||||
+ termcap.Normal
|
||||
)
|
||||
list(map(print, all_warnings))
|
||||
|
||||
|
||||
def warning(*args, **kwargs):
|
||||
message = ' '.join(args)
|
||||
printed = print_message('Warning: ', termcap.Yellow, message, **kwargs)
|
||||
message = " ".join(args)
|
||||
printed = print_message("Warning: ", termcap.Yellow, message, **kwargs)
|
||||
all_warnings.append(printed)
|
||||
|
||||
|
||||
def error(*args, **kwargs):
|
||||
message = ' '.join(args)
|
||||
print_message('Error: ', termcap.Red, message, **kwargs)
|
||||
message = " ".join(args)
|
||||
print_message("Error: ", termcap.Red, message, **kwargs)
|
||||
SCons.Script.Exit(1)
|
||||
|
||||
|
||||
def parse_build_path(target):
|
||||
path_dirs = target.split('/')
|
||||
path_dirs = target.split("/")
|
||||
|
||||
# Pop off the target file.
|
||||
path_dirs.pop()
|
||||
@@ -233,40 +261,55 @@ def parse_build_path(target):
|
||||
# Search backwards for the "build" directory. Whatever was just before it
|
||||
# was the name of the variant.
|
||||
variant_dir = path_dirs.pop()
|
||||
while path_dirs and path_dirs[-1] != 'build':
|
||||
while path_dirs and path_dirs[-1] != "build":
|
||||
variant_dir = path_dirs.pop()
|
||||
if not path_dirs:
|
||||
error("No non-leaf 'build' dir found on target path.", t)
|
||||
|
||||
return os.path.join('/', *path_dirs), variant_dir
|
||||
return os.path.join("/", *path_dirs), variant_dir
|
||||
|
||||
|
||||
# The MakeAction wrapper, and a SCons tool to set up the *COMSTR variables.
|
||||
if SCons.Script.GetOption('verbose'):
|
||||
if SCons.Script.GetOption("verbose"):
|
||||
|
||||
def MakeAction(action, string, *args, **kwargs):
|
||||
return SCons.Script.Action(action, *args, **kwargs)
|
||||
|
||||
def MakeActionTool(env):
|
||||
pass
|
||||
|
||||
else:
|
||||
MakeAction = SCons.Script.Action
|
||||
|
||||
def MakeActionTool(env):
|
||||
env['CCCOMSTR'] = Transform("CC")
|
||||
env['CXXCOMSTR'] = Transform("CXX")
|
||||
env['ASCOMSTR'] = Transform("AS")
|
||||
env['ARCOMSTR'] = Transform("AR", 0)
|
||||
env['LINKCOMSTR'] = Transform("LINK", 0)
|
||||
env['SHLINKCOMSTR'] = Transform("SHLINK", 0)
|
||||
env['RANLIBCOMSTR'] = Transform("RANLIB", 0)
|
||||
env['M4COMSTR'] = Transform("M4")
|
||||
env['SHCCCOMSTR'] = Transform("SHCC")
|
||||
env['SHCXXCOMSTR'] = Transform("SHCXX")
|
||||
env["CCCOMSTR"] = Transform("CC")
|
||||
env["CXXCOMSTR"] = Transform("CXX")
|
||||
env["ASCOMSTR"] = Transform("AS")
|
||||
env["ARCOMSTR"] = Transform("AR", 0)
|
||||
env["LINKCOMSTR"] = Transform("LINK", 0)
|
||||
env["SHLINKCOMSTR"] = Transform("SHLINK", 0)
|
||||
env["RANLIBCOMSTR"] = Transform("RANLIB", 0)
|
||||
env["M4COMSTR"] = Transform("M4")
|
||||
env["SHCCCOMSTR"] = Transform("SHCC")
|
||||
env["SHCXXCOMSTR"] = Transform("SHCXX")
|
||||
|
||||
|
||||
def ToValue(obj):
|
||||
return SCons.Node.Python.Value(pickle.dumps(obj))
|
||||
|
||||
|
||||
def FromValue(node):
|
||||
return pickle.loads(node.read())
|
||||
|
||||
__all__ = ['Configure', 'EnvDefaults', 'Transform', 'warning', 'error',
|
||||
'MakeAction', 'MakeActionTool', 'ToValue', 'FromValue']
|
||||
|
||||
__all__ = [
|
||||
"Configure",
|
||||
"EnvDefaults",
|
||||
"Transform",
|
||||
"warning",
|
||||
"error",
|
||||
"MakeAction",
|
||||
"MakeActionTool",
|
||||
"ToValue",
|
||||
"FromValue",
|
||||
]
|
||||
|
||||
@@ -43,26 +43,23 @@ import sys
|
||||
|
||||
import SCons.Node.FS
|
||||
|
||||
|
||||
def AddLocalRPATH(env):
|
||||
def add_local_rpath(env, *targets):
|
||||
'''Set up an RPATH for a library which lives in the build directory.
|
||||
"""Set up an RPATH for a library which lives in the build directory.
|
||||
|
||||
The construction environment variable BIN_RPATH_PREFIX should be set
|
||||
to the relative path of the build directory starting from the location
|
||||
of the binary.'''
|
||||
of the binary."""
|
||||
for target in targets:
|
||||
target = env.Entry(target)
|
||||
if not isinstance(target, SCons.Node.FS.Dir):
|
||||
target = target.dir
|
||||
relpath = os.path.relpath(target.abspath, env['BUILDDIR'])
|
||||
components = [
|
||||
'\\$$ORIGIN',
|
||||
'${BIN_RPATH_PREFIX}',
|
||||
relpath
|
||||
]
|
||||
relpath = os.path.relpath(target.abspath, env["BUILDDIR"])
|
||||
components = ["\\$$ORIGIN", "${BIN_RPATH_PREFIX}", relpath]
|
||||
env.Append(RPATH=[env.Literal(os.path.join(*components))])
|
||||
|
||||
if sys.platform != "darwin":
|
||||
env.Append(LINKFLAGS=env.Split('-z origin'))
|
||||
env.Append(LINKFLAGS=env.Split("-z origin"))
|
||||
|
||||
env.AddMethod(add_local_rpath, 'AddLocalRPATH')
|
||||
env.AddMethod(add_local_rpath, "AddLocalRPATH")
|
||||
|
||||
@@ -46,19 +46,21 @@ from code_formatter import code_formatter
|
||||
|
||||
import SCons.Node.Python
|
||||
|
||||
|
||||
def build_blob(target, source, env):
|
||||
'''
|
||||
"""
|
||||
Embed an arbitrary blob into the gem5 executable,
|
||||
and make it accessible to C++ as a byte array.
|
||||
'''
|
||||
"""
|
||||
|
||||
with open(str(source[0]), 'rb') as f:
|
||||
with open(str(source[0]), "rb") as f:
|
||||
data = f.read()
|
||||
symbol = str(source[1])
|
||||
cc, hh = target
|
||||
|
||||
hh_code = code_formatter()
|
||||
hh_code('''\
|
||||
hh_code(
|
||||
"""\
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -72,13 +74,15 @@ extern const std::uint8_t ${symbol}[];
|
||||
|
||||
} // namespace Blobs
|
||||
} // namespace gem5
|
||||
''')
|
||||
"""
|
||||
)
|
||||
hh_code.write(str(hh))
|
||||
|
||||
include_path = os.path.relpath(hh.abspath, env['BUILDDIR'])
|
||||
include_path = os.path.relpath(hh.abspath, env["BUILDDIR"])
|
||||
|
||||
cc_code = code_formatter()
|
||||
cc_code('''\
|
||||
cc_code(
|
||||
"""\
|
||||
#include "${include_path}"
|
||||
|
||||
namespace gem5
|
||||
@@ -87,22 +91,28 @@ namespace Blobs
|
||||
{
|
||||
|
||||
const std::size_t ${symbol}_len = ${{len(data)}};
|
||||
''')
|
||||
"""
|
||||
)
|
||||
bytesToCppArray(cc_code, symbol, data)
|
||||
cc_code('''
|
||||
cc_code(
|
||||
"""
|
||||
} // namespace Blobs
|
||||
} // namespace gem5
|
||||
''')
|
||||
"""
|
||||
)
|
||||
cc_code.write(str(cc))
|
||||
|
||||
|
||||
blob_action = MakeAction(build_blob, Transform("EMBED BLOB"))
|
||||
|
||||
|
||||
def blob_emitter(target, source, env):
|
||||
symbol = str(target[0])
|
||||
cc_file = env.File(symbol + '.cc')
|
||||
hh_file = env.File(symbol + '.hh')
|
||||
cc_file = env.File(symbol + ".cc")
|
||||
hh_file = env.File(symbol + ".hh")
|
||||
return [cc_file, hh_file], [source, SCons.Node.Python.Value(symbol)]
|
||||
|
||||
|
||||
def Blob(env):
|
||||
blob_builder = env.Builder(action=blob_action, emitter=blob_emitter)
|
||||
env.Append(BUILDERS={'Blob': blob_builder})
|
||||
env.Append(BUILDERS={"Blob": blob_builder})
|
||||
|
||||
@@ -46,15 +46,16 @@ from gem5_scons import Transform, MakeAction
|
||||
#
|
||||
###################################################
|
||||
|
||||
|
||||
def ConfigFile(env):
|
||||
# This function generates a config header file that #defines the
|
||||
# variable symbol to the current variable setting (0 or 1). The source
|
||||
# operands are the name of the variable and a Value node containing the
|
||||
# value of the variable.
|
||||
def build_config_file(target, source, env):
|
||||
(variable, value) = [s.get_contents().decode('utf-8') for s in source]
|
||||
with open(str(target[0].abspath), 'w') as f:
|
||||
print('#define', variable, value, file=f)
|
||||
(variable, value) = [s.get_contents().decode("utf-8") for s in source]
|
||||
with open(str(target[0].abspath), "w") as f:
|
||||
print("#define", variable, value, file=f)
|
||||
return None
|
||||
|
||||
# Combine the two functions into a scons Action object.
|
||||
@@ -66,8 +67,8 @@ def ConfigFile(env):
|
||||
# extract variable name from Builder arg
|
||||
variable = str(target[0])
|
||||
# True target is config header file
|
||||
target = env.Dir('config').File(variable.lower() + '.hh')
|
||||
val = env['CONF'][variable]
|
||||
target = env.Dir("config").File(variable.lower() + ".hh")
|
||||
val = env["CONF"][variable]
|
||||
if isinstance(val, bool):
|
||||
# Force value to 0/1
|
||||
val = str(int(val))
|
||||
@@ -79,4 +80,4 @@ def ConfigFile(env):
|
||||
|
||||
config_builder = env.Builder(emitter=config_emitter, action=config_action)
|
||||
|
||||
env.Append(BUILDERS = { 'ConfigFile' : config_builder })
|
||||
env.Append(BUILDERS={"ConfigFile": config_builder})
|
||||
|
||||
@@ -51,27 +51,32 @@ from gem5_scons import Transform, MakeAction
|
||||
#
|
||||
###################################################
|
||||
|
||||
|
||||
def SwitchingHeaders(env):
|
||||
def build_switching_header(target, source, env):
|
||||
path = str(target[0])
|
||||
subdir = str(source[0])
|
||||
dp, fp = os.path.split(path)
|
||||
dp = os.path.relpath(os.path.realpath(dp),
|
||||
os.path.realpath(env['BUILDDIR']))
|
||||
with open(path, 'w') as hdr:
|
||||
dp = os.path.relpath(
|
||||
os.path.realpath(dp), os.path.realpath(env["BUILDDIR"])
|
||||
)
|
||||
with open(path, "w") as hdr:
|
||||
print('#include "%s/%s/%s"' % (dp, subdir, fp), file=hdr)
|
||||
|
||||
switching_header_action = MakeAction(build_switching_header,
|
||||
Transform('GENERATE'))
|
||||
switching_header_action = MakeAction(
|
||||
build_switching_header, Transform("GENERATE")
|
||||
)
|
||||
|
||||
switching_header_builder = env.Builder(action=switching_header_action,
|
||||
source_factory=env.Value,
|
||||
single_source=True)
|
||||
switching_header_builder = env.Builder(
|
||||
action=switching_header_action,
|
||||
source_factory=env.Value,
|
||||
single_source=True,
|
||||
)
|
||||
|
||||
env.Append(BUILDERS = { 'SwitchingHeader': switching_header_builder })
|
||||
env.Append(BUILDERS={"SwitchingHeader": switching_header_builder})
|
||||
|
||||
def switching_headers(self, headers, source):
|
||||
for header in headers:
|
||||
self.SwitchingHeader(header, source)
|
||||
|
||||
env.AddMethod(switching_headers, 'SwitchingHeaders')
|
||||
env.AddMethod(switching_headers, "SwitchingHeaders")
|
||||
|
||||
@@ -44,39 +44,41 @@ import os
|
||||
import SCons.Script
|
||||
import SCons.Util
|
||||
|
||||
|
||||
def CheckCxxFlag(context, flag, autoadd=True):
|
||||
context.Message("Checking for compiler %s support... " % flag)
|
||||
last_cxxflags = context.env['CXXFLAGS']
|
||||
last_cxxflags = context.env["CXXFLAGS"]
|
||||
context.env.Append(CXXFLAGS=[flag])
|
||||
pre_werror = context.env['CXXFLAGS']
|
||||
context.env.Append(CXXFLAGS=['-Werror'])
|
||||
ret = context.TryCompile('// CheckCxxFlag DO NOTHING', '.cc')
|
||||
context.env['CXXFLAGS'] = pre_werror
|
||||
pre_werror = context.env["CXXFLAGS"]
|
||||
context.env.Append(CXXFLAGS=["-Werror"])
|
||||
ret = context.TryCompile("// CheckCxxFlag DO NOTHING", ".cc")
|
||||
context.env["CXXFLAGS"] = pre_werror
|
||||
if not (ret and autoadd):
|
||||
context.env['CXXFLAGS'] = last_cxxflags
|
||||
context.env["CXXFLAGS"] = last_cxxflags
|
||||
context.Result(ret)
|
||||
return ret
|
||||
|
||||
|
||||
def CheckLinkFlag(context, flag, autoadd=True, set_for_shared=True):
|
||||
context.Message("Checking for linker %s support... " % flag)
|
||||
last_linkflags = context.env['LINKFLAGS']
|
||||
last_linkflags = context.env["LINKFLAGS"]
|
||||
context.env.Append(LINKFLAGS=[flag])
|
||||
pre_werror = context.env['LINKFLAGS']
|
||||
context.env.Append(LINKFLAGS=['-Werror'])
|
||||
ret = context.TryLink('int main(int, char *[]) { return 0; }', '.cc')
|
||||
context.env['LINKFLAGS'] = pre_werror
|
||||
pre_werror = context.env["LINKFLAGS"]
|
||||
context.env.Append(LINKFLAGS=["-Werror"])
|
||||
ret = context.TryLink("int main(int, char *[]) { return 0; }", ".cc")
|
||||
context.env["LINKFLAGS"] = pre_werror
|
||||
if not (ret and autoadd):
|
||||
context.env['LINKFLAGS'] = last_linkflags
|
||||
if (ret and set_for_shared):
|
||||
assert(autoadd)
|
||||
context.env["LINKFLAGS"] = last_linkflags
|
||||
if ret and set_for_shared:
|
||||
assert autoadd
|
||||
context.env.Append(SHLINKFLAGS=[flag])
|
||||
context.Result(ret)
|
||||
return ret
|
||||
|
||||
|
||||
# Add a custom Check function to test for structure members.
|
||||
def CheckMember(context, include, decl, member, include_quotes="<>"):
|
||||
context.Message("Checking for member %s in %s..." %
|
||||
(member, decl))
|
||||
context.Message("Checking for member %s in %s..." % (member, decl))
|
||||
text = """
|
||||
#include %(header)s
|
||||
int main(){
|
||||
@@ -84,18 +86,21 @@ int main(){
|
||||
(void)test.%(member)s;
|
||||
return 0;
|
||||
};
|
||||
""" % { "header" : include_quotes[0] + include + include_quotes[1],
|
||||
"decl" : decl,
|
||||
"member" : member,
|
||||
}
|
||||
""" % {
|
||||
"header": include_quotes[0] + include + include_quotes[1],
|
||||
"decl": decl,
|
||||
"member": member,
|
||||
}
|
||||
|
||||
ret = context.TryCompile(text, extension=".cc")
|
||||
context.Result(ret)
|
||||
return ret
|
||||
|
||||
|
||||
def CheckPythonLib(context):
|
||||
context.Message('Checking Python version... ')
|
||||
ret = context.TryRun(r"""
|
||||
context.Message("Checking Python version... ")
|
||||
ret = context.TryRun(
|
||||
r"""
|
||||
#include <pybind11/embed.h>
|
||||
|
||||
int
|
||||
@@ -107,21 +112,24 @@ main(int argc, char **argv) {
|
||||
"sys.stdout.write('%i.%i.%i' % (vi.major, vi.minor, vi.micro));\n");
|
||||
return 0;
|
||||
}
|
||||
""", extension=".cc")
|
||||
""",
|
||||
extension=".cc",
|
||||
)
|
||||
context.Result(ret[1] if ret[0] == 1 else 0)
|
||||
if ret[0] == 0:
|
||||
return None
|
||||
else:
|
||||
return tuple(map(int, ret[1].split(".")))
|
||||
|
||||
|
||||
def CheckPkgConfig(context, pkgs, *args):
|
||||
if not SCons.Util.is_List(pkgs):
|
||||
pkgs = [pkgs]
|
||||
assert(pkgs)
|
||||
assert pkgs
|
||||
|
||||
for pkg in pkgs:
|
||||
context.Message('Checking for pkg-config package %s... ' % pkg)
|
||||
ret = context.TryAction('pkg-config %s' % pkg)[0]
|
||||
context.Message("Checking for pkg-config package %s... " % pkg)
|
||||
ret = context.TryAction("pkg-config %s" % pkg)[0]
|
||||
if not ret:
|
||||
context.Result(ret)
|
||||
continue
|
||||
@@ -129,7 +137,7 @@ def CheckPkgConfig(context, pkgs, *args):
|
||||
if len(args) == 0:
|
||||
break
|
||||
|
||||
cmd = ' '.join(['pkg-config'] + list(args) + [pkg])
|
||||
cmd = " ".join(["pkg-config"] + list(args) + [pkg])
|
||||
try:
|
||||
context.env.ParseConfig(cmd)
|
||||
ret = 1
|
||||
@@ -141,20 +149,25 @@ def CheckPkgConfig(context, pkgs, *args):
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def Configure(env, *args, **kwargs):
|
||||
kwargs.setdefault('conf_dir',
|
||||
os.path.join(env['GEM5BUILD'], 'scons_config'))
|
||||
kwargs.setdefault('log_file',
|
||||
os.path.join(env['GEM5BUILD'], 'scons_config.log'))
|
||||
kwargs.setdefault('custom_tests', {})
|
||||
kwargs['custom_tests'].update({
|
||||
'CheckCxxFlag' : CheckCxxFlag,
|
||||
'CheckLinkFlag' : CheckLinkFlag,
|
||||
'CheckMember' : CheckMember,
|
||||
'CheckPkgConfig' : CheckPkgConfig,
|
||||
'CheckPythonLib' : CheckPythonLib,
|
||||
})
|
||||
kwargs.setdefault(
|
||||
"conf_dir", os.path.join(env["GEM5BUILD"], "scons_config")
|
||||
)
|
||||
kwargs.setdefault(
|
||||
"log_file", os.path.join(env["GEM5BUILD"], "scons_config.log")
|
||||
)
|
||||
kwargs.setdefault("custom_tests", {})
|
||||
kwargs["custom_tests"].update(
|
||||
{
|
||||
"CheckCxxFlag": CheckCxxFlag,
|
||||
"CheckLinkFlag": CheckLinkFlag,
|
||||
"CheckMember": CheckMember,
|
||||
"CheckPkgConfig": CheckPkgConfig,
|
||||
"CheckPythonLib": CheckPythonLib,
|
||||
}
|
||||
)
|
||||
conf = SCons.Script.Configure(env, *args, **kwargs)
|
||||
|
||||
# Recent versions of scons substitute a "Null" object for Configure()
|
||||
@@ -163,14 +176,17 @@ def Configure(env, *args, **kwargs):
|
||||
# breaking all our configuration checks. We replace it with our own
|
||||
# more optimistic null object that returns True instead.
|
||||
if not conf:
|
||||
|
||||
def NullCheck(*args, **kwargs):
|
||||
return True
|
||||
|
||||
class NullConf:
|
||||
def __init__(self, env):
|
||||
self.env = env
|
||||
|
||||
def Finish(self):
|
||||
return self.env
|
||||
|
||||
def __getattr__(self, mname):
|
||||
return NullCheck
|
||||
|
||||
|
||||
@@ -42,56 +42,76 @@ import os
|
||||
|
||||
from gem5_python_paths import extra_python_paths
|
||||
|
||||
|
||||
def EnvDefaults(env):
|
||||
# export TERM so that clang reports errors in color
|
||||
use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH',
|
||||
'LIBRARY_PATH', 'PATH', 'PKG_CONFIG_PATH', 'PROTOC',
|
||||
'PYTHONPATH', 'RANLIB', 'TERM', 'PYTHON_CONFIG',
|
||||
'CCFLAGS_EXTRA', 'GEM5PY_CCFLAGS_EXTRA',
|
||||
'GEM5PY_LINKFLAGS_EXTRA', 'LINKFLAGS_EXTRA', 'LANG'])
|
||||
use_vars = set(
|
||||
[
|
||||
"AS",
|
||||
"AR",
|
||||
"CC",
|
||||
"CXX",
|
||||
"HOME",
|
||||
"LD_LIBRARY_PATH",
|
||||
"LIBRARY_PATH",
|
||||
"PATH",
|
||||
"PKG_CONFIG_PATH",
|
||||
"PROTOC",
|
||||
"PYTHONPATH",
|
||||
"RANLIB",
|
||||
"TERM",
|
||||
"PYTHON_CONFIG",
|
||||
"CCFLAGS_EXTRA",
|
||||
"GEM5PY_CCFLAGS_EXTRA",
|
||||
"GEM5PY_LINKFLAGS_EXTRA",
|
||||
"LINKFLAGS_EXTRA",
|
||||
"LANG",
|
||||
]
|
||||
)
|
||||
|
||||
use_prefixes = [
|
||||
"ASAN_", # address sanitizer symbolizer path and settings
|
||||
"CCACHE_", # ccache (caching compiler wrapper) configuration
|
||||
"CCC_", # clang static analyzer configuration
|
||||
"DISTCC_", # distcc (distributed compiler wrapper) config
|
||||
"INCLUDE_SERVER_", # distcc pump server settings
|
||||
"M5", # M5 configuration (e.g., path to kernels)
|
||||
"NIX_", # wrapped binaries if using nix package manager
|
||||
]
|
||||
"ASAN_", # address sanitizer symbolizer path and settings
|
||||
"CCACHE_", # ccache (caching compiler wrapper) configuration
|
||||
"CCC_", # clang static analyzer configuration
|
||||
"DISTCC_", # distcc (distributed compiler wrapper) config
|
||||
"INCLUDE_SERVER_", # distcc pump server settings
|
||||
"M5", # M5 configuration (e.g., path to kernels)
|
||||
"NIX_", # wrapped binaries if using nix package manager
|
||||
]
|
||||
|
||||
for key,val in sorted(os.environ.items()):
|
||||
if key in use_vars or \
|
||||
any([key.startswith(prefix) for prefix in use_prefixes]):
|
||||
env['ENV'][key] = val
|
||||
for key, val in sorted(os.environ.items()):
|
||||
if key in use_vars or any(
|
||||
[key.startswith(prefix) for prefix in use_prefixes]
|
||||
):
|
||||
env["ENV"][key] = val
|
||||
|
||||
# These variables from the environment override/become SCons variables,
|
||||
# with a default if they weren't in the host environment.
|
||||
var_overrides = {
|
||||
'CC': env['CC'],
|
||||
'CXX': env['CXX'],
|
||||
'PROTOC': 'protoc',
|
||||
'PYTHON_CONFIG': [ 'python3-config', 'python-config' ],
|
||||
'CCFLAGS_EXTRA': '',
|
||||
'GEM5PY_CCFLAGS_EXTRA': '',
|
||||
'GEM5PY_LINKFLAGS_EXTRA': '',
|
||||
'LINKFLAGS_EXTRA': '',
|
||||
"CC": env["CC"],
|
||||
"CXX": env["CXX"],
|
||||
"PROTOC": "protoc",
|
||||
"PYTHON_CONFIG": ["python3-config", "python-config"],
|
||||
"CCFLAGS_EXTRA": "",
|
||||
"GEM5PY_CCFLAGS_EXTRA": "",
|
||||
"GEM5PY_LINKFLAGS_EXTRA": "",
|
||||
"LINKFLAGS_EXTRA": "",
|
||||
}
|
||||
for key,default in var_overrides.items():
|
||||
env[key] = env['ENV'].get(key, default)
|
||||
for key, default in var_overrides.items():
|
||||
env[key] = env["ENV"].get(key, default)
|
||||
|
||||
# Tell scons to avoid implicit command dependencies to avoid issues
|
||||
# with the param wrappes being compiled twice (see
|
||||
# https://github.com/SCons/scons/issues/2811
|
||||
env['IMPLICIT_COMMAND_DEPENDENCIES'] = 0
|
||||
env.Decider('MD5-timestamp')
|
||||
env["IMPLICIT_COMMAND_DEPENDENCIES"] = 0
|
||||
env.Decider("MD5-timestamp")
|
||||
|
||||
# add useful python code PYTHONPATH so it can be used by subprocesses
|
||||
# as well
|
||||
env.AppendENVPath('PYTHONPATH', extra_python_paths)
|
||||
env.AppendENVPath("PYTHONPATH", extra_python_paths)
|
||||
|
||||
# Default duplicate option is to use hard links, but this messes up
|
||||
# when you use emacs to edit a file in the target dir, as emacs moves
|
||||
# file to file~ then copies to file, breaking the link. Symbolic
|
||||
# (soft) links work better.
|
||||
env.SetOption('duplicate', 'soft-copy')
|
||||
env.SetOption("duplicate", "soft-copy")
|
||||
|
||||
@@ -47,8 +47,9 @@ import SCons.Script
|
||||
# When specifying a source file of some type, a set of tags can be
|
||||
# specified for that file.
|
||||
|
||||
|
||||
def tag_implies(env, tag, tag_list):
|
||||
'''
|
||||
"""
|
||||
Associates a tag X to a list of tags which are implied by X.
|
||||
|
||||
For example, assume:
|
||||
@@ -72,10 +73,10 @@ def tag_implies(env, tag, tag_list):
|
||||
|
||||
So that any use of a tag will automatically include its transitive tags
|
||||
after being resolved.
|
||||
'''
|
||||
"""
|
||||
|
||||
env.SetDefault(_tag_implies={})
|
||||
implications = env['_tag_implies']
|
||||
implications = env["_tag_implies"]
|
||||
|
||||
if isinstance(tag_list, str):
|
||||
tag_list = frozenset([tag_list])
|
||||
@@ -95,21 +96,23 @@ def tag_implies(env, tag, tag_list):
|
||||
|
||||
# Check if another tag depends on this tag. If so, add this tag's
|
||||
# implications to that tag.
|
||||
for t,implied in implications.items():
|
||||
for t, implied in implications.items():
|
||||
if tag in implied:
|
||||
implications[t] |= implications[tag]
|
||||
|
||||
|
||||
def TagImpliesTool(env):
|
||||
env.AddMethod(tag_implies, 'TagImplies')
|
||||
env.AddMethod(tag_implies, "TagImplies")
|
||||
|
||||
|
||||
def resolve_tags(env, tags):
|
||||
'''
|
||||
"""
|
||||
Returns the complete set of tags implied (dependencies) by the
|
||||
supplied tags.
|
||||
'''
|
||||
"""
|
||||
|
||||
implications = env.SetDefault(_tag_implies={})
|
||||
implications = env['_tag_implies']
|
||||
implications = env["_tag_implies"]
|
||||
|
||||
if isinstance(tags, str):
|
||||
tags = frozenset([tags])
|
||||
@@ -122,53 +125,71 @@ def resolve_tags(env, tags):
|
||||
tags |= implications[tag]
|
||||
return tags
|
||||
|
||||
|
||||
class SourceFilter(object):
|
||||
factories = {}
|
||||
|
||||
def __init__(self, predicate):
|
||||
self.predicate = predicate
|
||||
|
||||
def __or__(self, other):
|
||||
return SourceFilter(lambda env, tags: self.predicate(env, tags) or
|
||||
other.predicate(env, tags))
|
||||
return SourceFilter(
|
||||
lambda env, tags: self.predicate(env, tags)
|
||||
or other.predicate(env, tags)
|
||||
)
|
||||
|
||||
def __and__(self, other):
|
||||
return SourceFilter(lambda env, tags: self.predicate(env, tags) and
|
||||
other.predicate(env, tags))
|
||||
return SourceFilter(
|
||||
lambda env, tags: self.predicate(env, tags)
|
||||
and other.predicate(env, tags)
|
||||
)
|
||||
|
||||
|
||||
def with_any_tags(*tags):
|
||||
'''Return a list of sources with any of the supplied tags.'''
|
||||
return SourceFilter(lambda env, stags: \
|
||||
len(resolve_tags(env, tags) & stags) > 0)
|
||||
"""Return a list of sources with any of the supplied tags."""
|
||||
return SourceFilter(
|
||||
lambda env, stags: len(resolve_tags(env, tags) & stags) > 0
|
||||
)
|
||||
|
||||
|
||||
def with_all_tags(*tags):
|
||||
'''Return a list of sources with all of the supplied tags.'''
|
||||
"""Return a list of sources with all of the supplied tags."""
|
||||
return SourceFilter(lambda env, stags: resolve_tags(env, tags) <= stags)
|
||||
|
||||
|
||||
def with_tag(tag):
|
||||
'''Return a list of sources with the supplied tag.'''
|
||||
"""Return a list of sources with the supplied tag."""
|
||||
return with_any_tags(*[tag])
|
||||
|
||||
|
||||
def without_tags(*tags):
|
||||
'''Return a list of sources without any of the supplied tags.'''
|
||||
return SourceFilter(lambda env, stags: \
|
||||
len(resolve_tags(env, tags) & stags) == 0)
|
||||
"""Return a list of sources without any of the supplied tags."""
|
||||
return SourceFilter(
|
||||
lambda env, stags: len(resolve_tags(env, tags) & stags) == 0
|
||||
)
|
||||
|
||||
|
||||
def without_tag(tag):
|
||||
'''Return a list of sources without the supplied tag.'''
|
||||
"""Return a list of sources without the supplied tag."""
|
||||
return without_tags(*[tag])
|
||||
|
||||
SourceFilter.factories.update({
|
||||
'with_any_tags': with_any_tags,
|
||||
'with_all_tags': with_all_tags,
|
||||
'with_tag': with_tag,
|
||||
'without_tags': without_tags,
|
||||
'without_tag': without_tag,
|
||||
})
|
||||
|
||||
SourceFilter.factories.update(
|
||||
{
|
||||
"with_any_tags": with_any_tags,
|
||||
"with_all_tags": with_all_tags,
|
||||
"with_tag": with_tag,
|
||||
"without_tags": without_tags,
|
||||
"without_tag": without_tag,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class SourceList(list):
|
||||
def apply_filter(self, env, f):
|
||||
def match(source):
|
||||
return f.predicate(env, resolve_tags(env, source.tags))
|
||||
|
||||
return SourceList(filter(match, self))
|
||||
|
||||
def __getattr__(self, name):
|
||||
@@ -179,33 +200,38 @@ class SourceList(list):
|
||||
@functools.wraps(func)
|
||||
def wrapper(env, *args, **kwargs):
|
||||
return self.apply_filter(env, func(*args, **kwargs))
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class SourceMeta(type):
|
||||
'''Meta class for source files that keeps track of all files of a
|
||||
particular type.'''
|
||||
"""Meta class for source files that keeps track of all files of a
|
||||
particular type."""
|
||||
|
||||
def __init__(cls, name, bases, dict):
|
||||
super(SourceMeta, cls).__init__(name, bases, dict)
|
||||
cls.all = SourceList()
|
||||
|
||||
|
||||
class SourceItem(object, metaclass=SourceMeta):
|
||||
'''Base object that encapsulates the notion of a source component for
|
||||
"""Base object that encapsulates the notion of a source component for
|
||||
gem5. This specifies a set of tags which help group components into groups
|
||||
based on arbitrary properties.'''
|
||||
based on arbitrary properties."""
|
||||
|
||||
def __init__(self, source, tags=None, add_tags=None, append=None):
|
||||
self.source = source
|
||||
|
||||
if tags is None:
|
||||
tags='gem5 lib'
|
||||
tags = "gem5 lib"
|
||||
if isinstance(tags, str):
|
||||
tags = { tags }
|
||||
tags = {tags}
|
||||
if not isinstance(tags, set):
|
||||
tags = set(tags)
|
||||
self.tags = tags.copy()
|
||||
|
||||
if add_tags:
|
||||
if isinstance(add_tags, str):
|
||||
add_tags = { add_tags }
|
||||
add_tags = {add_tags}
|
||||
if not isinstance(add_tags, set):
|
||||
add_tags = set(add_tags)
|
||||
self.tags |= add_tags
|
||||
@@ -216,10 +242,11 @@ class SourceItem(object, metaclass=SourceMeta):
|
||||
if issubclass(base, SourceItem):
|
||||
base.all.append(self)
|
||||
|
||||
|
||||
class SourceFile(SourceItem):
|
||||
'''Base object that encapsulates the notion of a source file.
|
||||
"""Base object that encapsulates the notion of a source file.
|
||||
This includes, the source node, target node, various manipulations
|
||||
of those.'''
|
||||
of those."""
|
||||
|
||||
def __init__(self, source, tags=None, add_tags=None, append=None):
|
||||
super().__init__(source, tags=tags, add_tags=add_tags, append=append)
|
||||
@@ -243,6 +270,15 @@ class SourceFile(SourceItem):
|
||||
return env.SharedObject(self.tnode)
|
||||
|
||||
|
||||
__all__ = ['TagImpliesTool', 'SourceFilter', 'SourceList', 'SourceFile',
|
||||
'SourceItem', 'with_any_tags', 'with_all_tags', 'with_tag',
|
||||
'without_tags', 'without_tag']
|
||||
__all__ = [
|
||||
"TagImpliesTool",
|
||||
"SourceFilter",
|
||||
"SourceList",
|
||||
"SourceFile",
|
||||
"SourceItem",
|
||||
"with_any_tags",
|
||||
"with_all_tags",
|
||||
"with_tag",
|
||||
"without_tags",
|
||||
"without_tag",
|
||||
]
|
||||
|
||||
@@ -46,12 +46,15 @@ import SCons.Script
|
||||
|
||||
import m5.util.terminal
|
||||
|
||||
|
||||
def ignore_style():
|
||||
"""Determine whether we should ignore style checks"""
|
||||
return SCons.Script.GetOption('ignore_style') or not sys.stdin.isatty()
|
||||
return SCons.Script.GetOption("ignore_style") or not sys.stdin.isatty()
|
||||
|
||||
|
||||
def get_termcap():
|
||||
return m5.util.terminal.get_termcap(SCons.Script.GetOption('use_colors'))
|
||||
return m5.util.terminal.get_termcap(SCons.Script.GetOption("use_colors"))
|
||||
|
||||
|
||||
def readCommand(cmd, **kwargs):
|
||||
"""
|
||||
@@ -68,13 +71,13 @@ def readCommand(cmd, **kwargs):
|
||||
if isinstance(cmd, str):
|
||||
cmd = cmd.split()
|
||||
|
||||
no_exception = 'exception' in kwargs
|
||||
exception = kwargs.pop('exception', None)
|
||||
no_exception = "exception" in kwargs
|
||||
exception = kwargs.pop("exception", None)
|
||||
|
||||
kwargs.setdefault('shell', False)
|
||||
kwargs.setdefault('stdout', PIPE)
|
||||
kwargs.setdefault('stderr', STDOUT)
|
||||
kwargs.setdefault('close_fds', True)
|
||||
kwargs.setdefault("shell", False)
|
||||
kwargs.setdefault("stdout", PIPE)
|
||||
kwargs.setdefault("stderr", STDOUT)
|
||||
kwargs.setdefault("close_fds", True)
|
||||
try:
|
||||
subp = Popen(cmd, **kwargs)
|
||||
except Exception as e:
|
||||
@@ -82,20 +85,23 @@ def readCommand(cmd, **kwargs):
|
||||
return -1, exception
|
||||
raise
|
||||
|
||||
output = subp.communicate()[0].decode('utf-8')
|
||||
output = subp.communicate()[0].decode("utf-8")
|
||||
return output
|
||||
|
||||
|
||||
def compareVersions(v1, v2):
|
||||
"""helper function: compare arrays or strings of version numbers.
|
||||
E.g., compare_version((1,3,25), (1,4,1)')
|
||||
returns -1, 0, 1 if v1 is <, ==, > v2
|
||||
"""
|
||||
|
||||
def make_version_list(v):
|
||||
if isinstance(v, (list,tuple)):
|
||||
if isinstance(v, (list, tuple)):
|
||||
return v
|
||||
elif isinstance(v, str):
|
||||
return list(map(lambda x: int(re.match('\d+', x).group()),
|
||||
v.split('.')))
|
||||
return list(
|
||||
map(lambda x: int(re.match("\d+", x).group()), v.split("."))
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
@@ -104,8 +110,10 @@ def compareVersions(v1, v2):
|
||||
|
||||
# Compare corresponding elements of lists
|
||||
# The shorter list is filled with 0 till the lists have the same length
|
||||
for n1,n2 in itertools.zip_longest(v1, v2, fillvalue=0):
|
||||
if n1 < n2: return -1
|
||||
if n1 > n2: return 1
|
||||
for n1, n2 in itertools.zip_longest(v1, v2, fillvalue=0):
|
||||
if n1 < n2:
|
||||
return -1
|
||||
if n1 > n2:
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user