1
1
2
- import json
3
2
import os
4
3
import subprocess
5
4
6
5
DRY_RUN = False
6
+ SQUELCH_STDERR = True
7
+ ECHO_CALLS = False
7
8
8
9
9
- def br_call (args ):
10
- if DRY_RUN :
11
- print ('DRY RUN: ' + ' ' .join (args ))
10
+ def br_call (args , dry_run = DRY_RUN , echo = ECHO_CALLS ):
11
+ if dry_run or echo :
12
+ print ('BRCALL: ' + ' ' .join (args ))
13
+ if dry_run :
12
14
return 0
13
- return subprocess .call (args , stdout = open ('/dev/null' ), stderr = open ('/dev/null' ))
15
+ if SQUELCH_STDERR :
16
+ return subprocess .call (args , stdout = open ('/dev/null' ),
17
+ stderr = open ('/dev/null' ))
18
+ else :
19
+ # Useful for debugging.
20
+ return subprocess .call (args , stdout = open ('/dev/null' ))
21
+
22
+
23
+ # We use this since our squelching of stderr can hide missing file errors.
24
+ def sanity_check_file_exists (f ):
25
+ if not os .access (f , os .F_OK ):
26
+ raise RuntimeError ('Error! Could not find file: ' + f )
14
27
15
28
16
29
class SwiftTools (object ):
@@ -50,7 +63,7 @@ def sil_opt(self):
50
63
def sil_func_extractor (self ):
51
64
"""Return the path to sil-func-extractor in the specified swift build
52
65
directory. Throws a runtime error if the tool does not exist."""
53
- return self ._get_tool ('sil-opt ' )
66
+ return self ._get_tool ('sil-func-extractor ' )
54
67
55
68
@property
56
69
def sil_passpipeline_dumper (self ):
@@ -67,54 +80,93 @@ def maybe_abspath(x):
67
80
return os .path .abspath (x )
68
81
69
82
70
- class SILOptInvoker (object ):
83
+ class SILToolInvokerConfig (object ):
71
84
72
- def __init__ (self , args , tools , extra_args ):
73
- self .tools = tools
85
+ def __init__ (self , args ):
74
86
self .module_cache = args .module_cache
75
87
self .sdk = args .sdk
76
88
self .target = args .target
77
89
self .resource_dir = maybe_abspath (args .resource_dir )
78
90
self .work_dir = maybe_abspath (args .work_dir )
79
91
self .module_name = args .module_name
92
+
93
+
94
+ class SILToolInvoker (object ):
95
+
96
+ def __init__ (self , config , extra_args = None ):
97
+ self .config = config
80
98
self .extra_args = extra_args
81
99
100
+ @property
101
+ def base_args (self ):
102
+ x = [self .tool ]
103
+ if self .config .sdk is not None :
104
+ x .append ("-sdk=%s" % self .config .sdk )
105
+ if self .config .target is not None :
106
+ x .append ("-target=%s" % self .config .target )
107
+ if self .config .resource_dir is not None :
108
+ x .append ("-resource-dir=%s" % self .config .resource_dir )
109
+ if self .config .module_cache is not None :
110
+ x .append ("-module-cache-path=%s" % self .config .module_cache )
111
+ if self .config .module_name is not None :
112
+ x .append ("-module-name=%s" % self .config .module_name )
113
+ return x
114
+
115
+ @property
116
+ def tool (self ):
117
+ raise RuntimeError ('Abstract Method' )
118
+
119
+
120
+ class SILConstantInputToolInvoker (SILToolInvoker ):
121
+
122
+ def __init__ (self , config , tools , initial_input_file , extra_args ):
123
+ SILToolInvoker .__init__ (self , config , extra_args )
124
+ self .tools = tools
125
+
82
126
# Start by creating our workdir if necessary
83
- subprocess .check_call (["mkdir" , "-p" , self .work_dir ])
127
+ subprocess .check_call (["mkdir" , "-p" , self .config . work_dir ])
84
128
85
129
# Then copy our input file into the work dir
86
- base_input_file = os .path .basename (args . input_file )
130
+ base_input_file = os .path .basename (initial_input_file )
87
131
(base , ext ) = os .path .splitext (base_input_file )
88
132
self .base_input_file_stem = base
89
133
self .base_input_file_ext = ".sib"
90
134
91
135
# First emit an initial *.sib file. This ensures no matter if we have a
92
136
# *.swiftmodule, *.sil, or *.sib file, we are always using *.sib.
93
- self .input_file = self .get_suffixed_filename ('initial' )
94
- self ._invoke (args .input_file , [], self .input_file )
137
+ self .input_file = initial_input_file
138
+ sanity_check_file_exists (initial_input_file )
139
+
140
+ def _invoke (self , input_file , passes , output_filename ):
141
+ raise RuntimeError ('Abstract method' )
142
+
143
+ @property
144
+ def base_args (self ):
145
+ base_args = SILToolInvoker .base_args .fget (self )
146
+ base_args .append ('-emit-sib' )
147
+ return base_args
95
148
96
149
def get_suffixed_filename (self , suffix ):
97
150
basename = self .base_input_file_stem + '_' + suffix
98
151
basename += self .base_input_file_ext
99
- return os .path .join (self .work_dir , basename )
152
+ return os .path .join (self .config .work_dir , basename )
153
+
154
+
155
+ class SILOptInvoker (SILConstantInputToolInvoker ):
156
+
157
+ def __init__ (self , config , tools , input_file , extra_args ):
158
+ SILConstantInputToolInvoker .__init__ (self , config , tools , input_file ,
159
+ extra_args )
160
+ self .input_file = self .get_suffixed_filename ('initial' )
161
+ self ._invoke (input_file , [], self .input_file )
100
162
101
163
@property
102
- def base_args (self ):
103
- x = [self .tools .sil_opt , "-emit-sib" ]
104
- if self .sdk is not None :
105
- x .append ("-sdk=%s" % self .sdk )
106
- if self .target is not None :
107
- x .append ("-target=%s" % self .target )
108
- if self .resource_dir is not None :
109
- x .append ("-resource-dir=%s" % self .resource_dir )
110
- if self .module_cache is not None :
111
- x .append ("-module-cache-path=%s" % self .module_cache )
112
- if self .module_name is not None :
113
- x .append ("-module-name=%s" % self .module_name )
114
- return x
164
+ def tool (self ):
165
+ return self .tools .sil_opt
115
166
116
167
def _cmdline (self , input_file , passes , output_file = '-' ):
117
168
base_args = self .base_args
169
+ sanity_check_file_exists (input_file )
118
170
base_args .extend ([input_file , '-o' , output_file ])
119
171
base_args .extend (self .extra_args )
120
172
base_args .extend (passes )
@@ -129,3 +181,61 @@ def invoke_with_passlist(self, passes, output_filename):
129
181
130
182
def cmdline_with_passlist (self , passes ):
131
183
return self ._cmdline (self .input_file , passes )
184
+
185
+
186
+ class SILFuncExtractorInvoker (SILConstantInputToolInvoker ):
187
+
188
+ def __init__ (self , config , tools , input_file ):
189
+ SILConstantInputToolInvoker .__init__ (self , config , tools , input_file ,
190
+ [])
191
+
192
+ @property
193
+ def tool (self ):
194
+ return self .tools .sil_func_extractor
195
+
196
+ def _cmdline (self , input_file , funclist_path , output_file = '-' , invert = False ):
197
+ sanity_check_file_exists (input_file )
198
+ sanity_check_file_exists (funclist_path )
199
+ assert (isinstance (funclist_path , str ))
200
+ base_args = self .base_args
201
+ base_args .extend ([input_file , '-o' , output_file ,
202
+ '-func-file=%s' % funclist_path ])
203
+ if invert :
204
+ base_args .append ('-invert' )
205
+ return base_args
206
+
207
+ def _invoke (self , input_file , funclist_path , output_filename , invert = False ):
208
+ assert (isinstance (funclist_path , str ))
209
+ cmdline = self ._cmdline (input_file , funclist_path , output_filename ,
210
+ invert )
211
+ return br_call (cmdline )
212
+
213
+ def invoke_with_functions (self , funclist_path , output_filename , invert = False ):
214
+ assert (isinstance (funclist_path , str ))
215
+ return self ._invoke (self .input_file , funclist_path , output_filename ,
216
+ invert )
217
+
218
+ def cmdline_with_functions (self , funclist_path , invert = False ):
219
+ assert (isinstance (funclist_path , str ))
220
+ return self ._cmdline (self .input_file , funclist_path , invert )
221
+
222
+
223
+ class SILNMInvoker (SILToolInvoker ):
224
+
225
+ def __init__ (self , config , tools ):
226
+ self .tools = tools
227
+ SILToolInvoker .__init__ (self , config )
228
+
229
+ @property
230
+ def tool (self ):
231
+ return self .tools .sil_nm
232
+
233
+ def get_symbols (self , input_file ):
234
+ sanity_check_file_exists (input_file )
235
+ cmdline = self .base_args
236
+ cmdline .append (input_file )
237
+ output = subprocess .check_output (cmdline )
238
+ for l in output .split ("\n " )[:- 1 ]:
239
+ t = tuple (l .split (" " ))
240
+ assert (len (t ) == 2 )
241
+ yield t
0 commit comments