blob: 272cecd9407ab065c4aada865584f69e81350365 [file] [log] [blame]
Marat Dukhan51c61342021-12-22 23:08:39 -08001#!/usr/bin/env python
2# Copyright 2019 Google LLC
3#
4# This source code is licensed under the BSD-style license found in the
5# LICENSE file in the root directory of this source tree.
6
7import argparse
8import codecs
9import math
10import os
11import re
12import sys
13import yaml
14
15
16ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
17
18
19parser = argparse.ArgumentParser(
20 description='Amalgamation utility for microkernels')
21parser.add_argument("-s", "--set", metavar="SET", required=True,
22 help="List of microkernel filenames in the BUILD file")
23parser.add_argument("-o", "--output", metavar="FILE", required=True,
24 help='Output (C source) file')
25
26
27def main(args):
28 options = parser.parse_args(args)
29
30 build_path = os.path.join(ROOT_DIR, "..", "BUILD")
31
32 with codecs.open(build_path, "r", encoding="utf-8") as build_file:
33 build_text = build_file.read()
34
35 pattern = r"\b" + options.set + r"\b\s*=\s*\["
36 match = re.search(pattern, build_text)
37 if not match:
38 raise ValueError(
39 "Failed to find file set %s (regex \"%s\") inside the BUILD file" %
40 (options.set, pattern))
41
42 start_pos = match.end()
43 end_pos = build_text.find("]", start_pos)
44
45 fileset = [filename.strip()[1:-1] for filename in
46 build_text[start_pos:end_pos].split(",")]
47
48 amalgam_lines = list()
49 amalgam_includes = set()
50 for filename in sorted(fileset):
51 if not filename:
52 continue
53
54 filepath = os.path.join(ROOT_DIR, "..", filename)
55 with codecs.open(filepath, "r", encoding="utf-8") as file:
56 filelines = file.read().splitlines()
57
58 consumed_license = False
59 consumed_includes = False
60 for line in filelines:
61 if line.startswith("//"):
62 if not consumed_license:
63 # Skip and generate a standard license header for amalgamated file
64 continue
65 elif line.lstrip().startswith("#"):
66 if not consumed_includes:
67 amalgam_includes.add(line)
68 continue
69 consumed_license = True
70 elif not line:
71 if not consumed_includes:
72 # Skip empty lines until end of headers
73 continue
74 else:
75 consumed_license = True
76 consumed_includes = True
77
78 amalgam_lines.append(line)
79
80 amalgam_lines.append("")
81
82 amalgam_includes.discard("#include <emmintrin.h>")
83 amalgam_includes.discard("#include <immintrin.h>")
84 amalgam_includes.discard("#include <nmmintrin.h>")
85 amalgam_includes.discard("#include <tmmintrin.h>")
86 amalgam_includes.discard("#include <xmmintrin.h>")
87
88 amalgam_text = """\
89// Copyright 2021 Google LLC
90//
91// This source code is licensed under the BSD-style license found in the
92// LICENSE file in the root directory of this source tree.
93
94"""
95
96 amalgam_text += "\n".join(sorted(inc for inc in amalgam_includes if
97 not inc.startswith("#include <xnnpack/")))
98 amalgam_text += "\n\n#include <immintrin.h>\n\n"
99 amalgam_text += "\n".join(sorted(inc for inc in amalgam_includes if
100 inc.startswith("#include <xnnpack/")))
101 amalgam_text += "\n\n\n"
102 amalgam_text += "\n".join(amalgam_lines)
103
104 with open(options.output, "w", encoding="utf-8") as amalgam_file:
105 amalgam_file.write(amalgam_text)
106
107
108if __name__ == "__main__":
109 main(sys.argv[1:])