11import os
22import argparse
3+ import sys
4+ import fnmatch
35import glob
46
5-
67def main ():
78 parser = argparse .ArgumentParser (
8- description = "Generate SYCL Headers Resource C++ file"
9- )
10- parser .add_argument ("-o" , "--output" , type = str , required = True , help = "Output file" )
11- parser .add_argument (
12- "-i" ,
13- "--toolchain-dir" ,
14- type = str ,
15- required = True ,
16- help = "Path to toolchain root directory" ,
17- )
18- parser .add_argument (
19- "--prefix" , type = str , required = True , help = "Prefix for file locations"
9+ description = "Generate SYCL Headers Resource C++ file."
2010 )
11+ parser .add_argument ("-o" , "--output" , type = str , required = True , help = "Output C++ file" )
12+ parser .add_argument ("-i" , "--toolchain-dir" , type = str , required = True , help = "Path to toolchain root directory." )
13+ parser .add_argument ("--prefix" , type = str , required = True , help = "Prefix for virtual file locations" )
14+ parser .add_argument ("-m" , "--manifest-input" , type = str , help = "Build from this whitelist manifest (read-only)." )
15+ parser .add_argument ("--manifest-output" , type = str , help = "Glob for files and write them to this capture manifest." )
16+ parser .add_argument ("--blacklist" , type = str , help = "Path to a file containing glob patterns of resources to exclude." )
17+
2118 args = parser .parse_args ()
2219
23- # abspath also strips trailing "/"
20+ if args .manifest_input and args .manifest_output :
21+ print ("Error: --manifest-input and --manifest-output are mutually exclusive." , file = sys .stderr )
22+ sys .exit (1 )
23+
24+ blacklist_patterns = set ()
25+ if args .blacklist :
26+ print (f"Loading blacklist from: { args .blacklist } " )
27+ with open (args .blacklist , "r" ) as f :
28+ for line in f :
29+ pattern = line .strip ()
30+ if pattern and not pattern .startswith ('#' ):
31+ blacklist_patterns .add (pattern )
32+
2433 toolchain_dir = os .path .abspath (args .toolchain_dir )
34+
35+ manifest_to_write = open (args .manifest_output , "w" ) if args .manifest_output else open (os .devnull , "w" )
36+
37+ with manifest_to_write as manifest_out , open (args .output , "w" ) as out :
38+ if args .manifest_output :
39+ preamble = f"""# This manifest was auto-geneerated by the sycl-jit build process
40+ # It contains the list of all candidate resource files found when globbing.
41+ #
42+ # If any of these files should NOT be included in the final library
43+ # (e.g. for IP reasons), add their relative path to the blacklist file at:
44+ # { args .blacklist }
45+ """
46+ manifest_out .write (preamble + '\n ' )
2547
26- with open (args .output , "w" ) as out :
2748 out .write (
2849 """
2950#include <Resource.h>
30-
3151namespace jit_compiler::resource {
3252const resource_file ToolchainFiles[] = {"""
3353 )
3454
35- def process_file (file_path ):
55+ def generate_cpp_for_file (absolute_path ):
56+ relative_path = os .path .relpath (absolute_path , toolchain_dir )
57+ portable_relative_path = relative_path .replace (os .sep , '/' )
58+
59+ for pattern in blacklist_patterns :
60+ # Compare the pattern against the portable relative path
61+ if fnmatch .fnmatch (portable_relative_path , pattern ):
62+ print (f" -> Skipping blacklisted file: { portable_relative_path } " )
63+ return None
64+
3665 out .write (
3766 f"""
38- {{
39- {{"{ args .prefix } { os . path . relpath ( file_path , toolchain_dir ). replace ( os . sep , "/" ) } "}} ,
40- []() {{
41- static const char data[] = {{
42- #embed "{ file_path } " if_empty(0)
43- , 0}};
44- return resource_string_view{{data}};
45- }}()
46- }},"""
67+ {{
68+ {{"{ args .prefix } { portable_relative_path } "}} ,
69+ []() {{
70+ static const char data[] = {{
71+ #embed "{ absolute_path } " if_empty(0)
72+ , 0}};
73+ return resource_string_view{{data}};
74+ }}()
75+ }},"""
4776 )
77+ return portable_relative_path
78+
79+ if args .manifest_input :
80+ print (f"Reading resource list from whitelist manifest: { args .manifest_input } " )
81+ with open (args .manifest_input , "r" ) as manifest_file :
82+ for line in manifest_file :
83+ relative_path = line .strip ()
84+ if relative_path :
85+ absolute_path = os .path .join (toolchain_dir , relative_path )
86+ generate_cpp_for_file (absolute_path )
87+ else :
88+ if args .manifest_output :
89+ print (f"Globbing for resources and writing capture manifest to: { args .manifest_output } " )
90+ else :
91+ print ("Globbing for resources (no capture manifest output)..." )
4892
49- def process_dir (dir ):
50- for root , _ , files in os .walk (dir ):
51- for file in files :
52- file_path = os .path .join (root , file )
53- process_file (file_path )
93+ def process_and_log_file (absolute_path ):
94+ relative_path = generate_cpp_for_file (absolute_path )
95+ if relative_path :
96+ manifest_out .write (relative_path + '\n ' )
5497
55- process_dir (os .path .join (args .toolchain_dir , "include/" ))
56- process_dir (os .path .join (args .toolchain_dir , "lib/clang/" ))
57- process_dir (os .path .join (args .toolchain_dir , "lib/clc/" ))
98+ def process_dir (dir ):
99+ for root , _ , files in os .walk (dir ):
100+ for file in files :
101+ process_and_log_file (os .path .join (root , file ))
58102
59- for file in glob .iglob (
60- "*.bc" , root_dir = os .path .join (args .toolchain_dir , "lib" )
61- ):
62- file_path = os .path .join (args .toolchain_dir , "lib" , file )
63- process_file (file_path )
103+ process_dir (os .path .join (args .toolchain_dir , "include/" ))
104+ process_dir (os .path .join (args .toolchain_dir , "lib/clang/" ))
105+ process_dir (os .path .join (args .toolchain_dir , "lib/clc/" ))
106+
107+ print ("Recursively searching for .bc files in lib/..." )
108+ lib_dir = os .path .join (args .toolchain_dir , "lib" )
109+ search_pattern = os .path .join (lib_dir , "**" , "*.bc" )
110+
111+ for file_path in glob .glob (search_pattern , recursive = True ):
112+ process_and_log_file (file_path )
64113
65114 out .write (
66115 f"""
@@ -72,6 +121,6 @@ def process_dir(dir):
72121"""
73122 )
74123
75-
76124if __name__ == "__main__" :
77125 main ()
126+
0 commit comments