scons: Turn the Blob method into a builder.

Build the blob .cc and .hh files in the same directory as the file
they're based off of. Move the GDB XML files into the arch directories
they go with.

Change-Id: I12fe48873312c3aba5910989d6e3049ebd5e5bbf
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/48136
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2021-07-15 01:39:56 -07:00
parent 18fb295bcd
commit 9fa9840691
30 changed files with 229 additions and 85 deletions

View File

@@ -287,71 +287,69 @@ def bytesToCppArray(code, symbol, data):
code.dedent()
code('};')
def blobToCpp(data, symbol, cpp_code, hpp_code, namespace):
def build_blob(target, source, env):
'''
Embed an arbitrary blob into the gem5 executable,
and make it accessible to C++ as a byte array.
'''
Convert bytes data into C++ .cpp and .hh uint8_t byte array
code containing that binary data.
:param data: binary data to be converted to C++
:param symbol: name of the symbol
:param cpp_code: append the generated cpp_code to this object
:param hpp_code: append the generated hpp_code to this object
Also include it in the .cpp file.
:param namespace: namespace to put the symbol into.
'''
hpp_code('''\
with open(str(source[0]), 'rb') as f:
data = f.read()
symbol = str(source[1])
cc, hh = target
hh_code = code_formatter()
hh_code('''\
#include <cstddef>
#include <cstdint>
namespace ${namespace}
namespace gem5
{
namespace Blobs
{
extern const std::size_t ${symbol}_len;
extern const std::uint8_t ${symbol}[];
}
} // namespace Blobs
} // namespace gem5
''')
hh_code.write(str(hh))
cpp_code('''\
#include "blobs/${symbol}.hh"
include_path = os.path.relpath(hh.abspath, env['BUILDDIR'])
namespace ${namespace}
cc_code = code_formatter()
cc_code('''\
#include "${include_path}"
namespace gem5
{
namespace Blobs
{
const std::size_t ${symbol}_len = ${{len(data)}};
''')
bytesToCppArray(cpp_code, symbol, data)
cpp_code('} // namespace ${namespace}')
bytesToCppArray(cc_code, symbol, data)
cc_code('''
} // namespace Blobs
} // namespace gem5
''')
cc_code.write(str(cc))
def Blob(blob_path, symbol):
'''
Embed an arbitrary blob into the gem5 executable,
and make it accessible to C++ as a byte array.
'''
blob_path = os.path.abspath(blob_path)
blob_out_dir = os.path.join(env['BUILDDIR'], 'blobs')
path_noext = os.path.join(blob_out_dir, symbol)
cpp_path = path_noext + '.cc'
hpp_path = path_noext + '.hh'
def embedBlob(target, source, env):
with open(str(source[0]), 'rb') as f:
data = f.read()
cpp_code = code_formatter()
hpp_code = code_formatter()
blobToCpp(data, symbol, cpp_code, hpp_code, namespace='Blobs')
cpp_path = str(target[0])
hpp_path = str(target[1])
cpp_dir = os.path.split(cpp_path)[0]
if not os.path.exists(cpp_dir):
os.makedirs(cpp_dir)
cpp_code.write(cpp_path)
hpp_code.write(hpp_path)
env.Command([cpp_path, hpp_path], blob_path,
MakeAction(embedBlob, Transform("EMBED BLOB")))
Source(cpp_path)
blob_action = MakeAction(build_blob, Transform("EMBED BLOB"))
def blob_emitter(target, source, env):
symbol = str(target[0])
cc_file = File(symbol + '.cc')
hh_file = File(symbol + '.hh')
return [cc_file, hh_file], [source, Value(symbol)]
blob_builder = Builder(action=blob_action, emitter=blob_emitter)
env.Append(BUILDERS={'Blob': blob_builder})
def GdbXml(xml_id, symbol):
Blob(os.path.join(gdb_xml_dir, xml_id), symbol)
cc, hh = env.Blob(symbol, xml_id)
Source(cc)
class Source(SourceFile):
pass
@@ -594,7 +592,6 @@ class Gem5(Executable):
# Children should have access
Export('Blob')
Export('GdbXml')
Export('Source')
Export('PySource')