blob: 23c31822150030b8486b65ba6aeefafa6b15d333 [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>")
Marat Dukhan8a9eac62022-01-06 09:22:01 -080085 amalgam_includes.discard("#include <smmintrin.h>")
Marat Dukhan51c61342021-12-22 23:08:39 -080086 amalgam_includes.discard("#include <tmmintrin.h>")
87 amalgam_includes.discard("#include <xmmintrin.h>")
88
89 amalgam_text = """\
90// Copyright 2021 Google LLC
91//
92// This source code is licensed under the BSD-style license found in the
93// LICENSE file in the root directory of this source tree.
94
95"""
96
97 amalgam_text += "\n".join(sorted(inc for inc in amalgam_includes if
98 not inc.startswith("#include <xnnpack/")))
99 amalgam_text += "\n\n#include <immintrin.h>\n\n"
100 amalgam_text += "\n".join(sorted(inc for inc in amalgam_includes if
101 inc.startswith("#include <xnnpack/")))
102 amalgam_text += "\n\n\n"
103 amalgam_text += "\n".join(amalgam_lines)
104
105 with open(options.output, "w", encoding="utf-8") as amalgam_file:
106 amalgam_file.write(amalgam_text)
107
108
109if __name__ == "__main__":
110 main(sys.argv[1:])