1#!/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 <smmintrin.h>") 86 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 106 107 txt_changed = True 108 if os.path.exists(options.output): 109 with open(options.output, "r", encoding="utf-8") as amalgam_file: 110 txt_changed = amalgam_file.read() != amalgam_text 111 112 if txt_changed: 113 with open(options.output, "w", encoding="utf-8") as amalgam_file: 114 amalgam_file.write(amalgam_text) 115 116 117if __name__ == "__main__": 118 main(sys.argv[1:]) 119