77
77
QUIET = (__name__ != '__main__' )
78
78
DEBUG = False
79
79
80
+ CFLAGS = [
81
+ # Avoid parsing problems due to gcc specific syntax.
82
+ '-D_GNU_SOURCE' ,
83
+ ]
84
+
85
+ INTERNAL_CFLAGS = [
86
+ '-I' + utils .path_from_root ('system/lib/libc/musl/src/internal' ),
87
+ '-I' + utils .path_from_root ('system/lib/libc/musl/src/include' ),
88
+ '-I' + utils .path_from_root ('system/lib/pthread/' ),
89
+ ]
90
+
91
+ CXXFLAGS = [
92
+ '-I' + utils .path_from_root ('system/lib/libcxxabi/src' ),
93
+ '-D__EMSCRIPTEN_EXCEPTIONS__' ,
94
+ '-I' + utils .path_from_root ('system/lib/wasmfs/' ),
95
+ '-std=c++17' ,
96
+ ]
97
+
98
+ DEFAULT_JSON_FILES = [
99
+ utils .path_from_root ('src/struct_info.json' ),
100
+ utils .path_from_root ('src/struct_info_internal.json' ),
101
+ utils .path_from_root ('src/struct_info_cxx.json' ),
102
+ utils .path_from_root ('src/struct_info_webgpu.json' ),
103
+ ]
104
+
80
105
81
106
def show (msg ):
82
107
if shared .DEBUG or not QUIET :
@@ -179,7 +204,7 @@ def gen_inspect_code(path, struct, code):
179
204
c_ascent (code )
180
205
181
206
182
- def inspect_headers (headers , cflags ):
207
+ def generate_c_code (headers ):
183
208
code = ['#include <stdio.h>' , '#include <stddef.h>' ]
184
209
for header in headers :
185
210
code .append ('#include "' + header ['name' ] + '"' )
@@ -211,28 +236,10 @@ def inspect_headers(headers, cflags):
211
236
code .append ('return 0;' )
212
237
code .append ('}' )
213
238
214
- # Write the source code to a temporary file.
215
- src_file = tempfile .mkstemp ('.c' , text = True )
216
- show ('Generating C code... ' + src_file [1 ])
217
- os .write (src_file [0 ], '\n ' .join (code ).encode ())
218
-
219
- js_file = tempfile .mkstemp ('.js' )
220
-
221
- # Check sanity early on before populating the cache with libcompiler_rt
222
- # If we don't do this the parallel build of compiler_rt will run while holding the cache
223
- # lock and with EM_EXCLUSIVE_CACHE_ACCESS set causing N processes to race to run sanity checks.
224
- # While this is not in itself serious problem it is wasteful and noise on stdout.
225
- # For the same reason we run this early in embuilder.py and emcc.py.
226
- # TODO(sbc): If we can remove EM_EXCLUSIVE_CACHE_ACCESS then this would not longer be needed.
227
- shared .check_sanity ()
228
-
229
- compiler_rt = system_libs .Library .get_usable_variations ()['libcompiler_rt' ].build ()
239
+ return code
230
240
231
- # Close all unneeded FDs.
232
- os .close (src_file [0 ])
233
- os .close (js_file [0 ])
234
241
235
- info = []
242
+ def generate_cmd ( js_file_path , src_file_path , cflags , compiler_rt ):
236
243
# Compile the program.
237
244
show ('Compiling generated code...' )
238
245
@@ -244,7 +251,7 @@ def inspect_headers(headers, cflags):
244
251
node_flags = building .get_emcc_node_flags (shared .check_node_version ())
245
252
246
253
# -O1+ produces calls to iprintf, which libcompiler_rt doesn't support
247
- cmd = [compiler ] + cflags + ['-o' , js_file [ 1 ], src_file [ 1 ] ,
254
+ cmd = [compiler ] + cflags + ['-o' , js_file_path , src_file_path ,
248
255
'-O0' ,
249
256
'-Werror' ,
250
257
'-Wno-format' ,
@@ -272,27 +279,54 @@ def inspect_headers(headers, cflags):
272
279
cmd += ['-sMEMORY64=2' , '-Wno-experimental' ]
273
280
274
281
show (shared .shlex_join (cmd ))
282
+ return cmd
283
+
284
+
285
+ def inspect_headers (headers , cflags ):
286
+ # Write the source code to a temporary file.
287
+ src_file_fd , src_file_path = tempfile .mkstemp ('.c' , text = True )
288
+ show ('Generating C code... ' + src_file_path )
289
+ code = generate_c_code (headers )
290
+ os .write (src_file_fd , '\n ' .join (code ).encode ())
291
+ os .close (src_file_fd )
292
+
293
+ # Check sanity early on before populating the cache with libcompiler_rt
294
+ # If we don't do this the parallel build of compiler_rt will run while holding the cache
295
+ # lock and with EM_EXCLUSIVE_CACHE_ACCESS set causing N processes to race to run sanity checks.
296
+ # While this is not in itself serious problem it is wasteful and noise on stdout.
297
+ # For the same reason we run this early in embuilder.py and emcc.py.
298
+ # TODO(sbc): If we can remove EM_EXCLUSIVE_CACHE_ACCESS then this would not longer be needed.
299
+ shared .check_sanity ()
300
+
301
+ compiler_rt = system_libs .Library .get_usable_variations ()['libcompiler_rt' ].build ()
302
+
303
+ js_file_fd , js_file_path = tempfile .mkstemp ('.js' )
304
+ # Close the unneeded FD.
305
+ os .close (js_file_fd )
306
+
307
+ cmd = generate_cmd (js_file_path , src_file_path , cflags , compiler_rt )
308
+
275
309
try :
276
310
subprocess .check_call (cmd , env = system_libs .clean_env ())
277
311
except subprocess .CalledProcessError as e :
278
312
sys .stderr .write ('FAIL: Compilation failed!: %s\n ' % e .cmd )
279
313
sys .exit (1 )
280
314
281
315
# Run the compiled program.
282
- show ('Calling generated program... ' + js_file [ 1 ] )
316
+ show ('Calling generated program... ' + js_file_path )
283
317
args = []
284
318
if settings .MEMORY64 :
285
319
args += shared .node_bigint_flags (config .NODE_JS )
286
- info = shared .run_js_tool (js_file [ 1 ] , node_args = args , stdout = shared .PIPE ).splitlines ()
320
+ info = shared .run_js_tool (js_file_path , node_args = args , stdout = shared .PIPE ).splitlines ()
287
321
288
322
if not DEBUG :
289
323
# Remove all temporary files.
290
- os .unlink (src_file [ 1 ] )
324
+ os .unlink (src_file_path )
291
325
292
- if os .path .exists (js_file [ 1 ] ):
293
- os .unlink (js_file [ 1 ] )
294
- wasm_file = shared .replace_suffix (js_file [ 1 ] , '.wasm' )
295
- os .unlink (wasm_file )
326
+ if os .path .exists (js_file_path ):
327
+ os .unlink (js_file_path )
328
+ wasm_file_path = shared .replace_suffix (js_file_path , '.wasm' )
329
+ os .unlink (wasm_file_path )
296
330
297
331
# Parse the output of the program into a dict.
298
332
return parse_c_output (info )
@@ -366,16 +400,10 @@ def output_json(obj, stream):
366
400
def main (args ):
367
401
global QUIET
368
402
369
- default_json_files = [
370
- utils .path_from_root ('src/struct_info.json' ),
371
- utils .path_from_root ('src/struct_info_internal.json' ),
372
- utils .path_from_root ('src/struct_info_cxx.json' ),
373
- utils .path_from_root ('src/struct_info_webgpu.json' ),
374
- ]
375
403
parser = argparse .ArgumentParser (description = 'Generate JSON infos for structs.' )
376
404
parser .add_argument ('json' , nargs = '*' ,
377
405
help = 'JSON file with a list of structs and their fields (defaults to src/struct_info.json)' ,
378
- default = default_json_files )
406
+ default = DEFAULT_JSON_FILES )
379
407
parser .add_argument ('-q' , dest = 'quiet' , action = 'store_true' , default = False ,
380
408
help = 'Don\' t output anything besides error messages.' )
381
409
parser .add_argument ('-o' , dest = 'output' , metavar = 'path' , default = None ,
@@ -392,34 +420,20 @@ def main(args):
392
420
393
421
QUIET = args .quiet
394
422
395
- # Avoid parsing problems due to gcc specifc syntax.
396
- cflags = ['-D_GNU_SOURCE' ]
423
+ extra_cflags = []
397
424
398
425
if args .wasm64 :
399
426
settings .MEMORY64 = 2
400
427
401
428
# Add the user options to the list as well.
402
429
for path in args .includes :
403
- cflags .append ('-I' + path )
430
+ extra_cflags .append ('-I' + path )
404
431
405
432
for arg in args .defines :
406
- cflags .append ('-D' + arg )
433
+ extra_cflags .append ('-D' + arg )
407
434
408
435
for arg in args .undefines :
409
- cflags .append ('-U' + arg )
410
-
411
- internal_cflags = [
412
- '-I' + utils .path_from_root ('system/lib/libc/musl/src/internal' ),
413
- '-I' + utils .path_from_root ('system/lib/libc/musl/src/include' ),
414
- '-I' + utils .path_from_root ('system/lib/pthread/' ),
415
- ]
416
-
417
- cxxflags = [
418
- '-I' + utils .path_from_root ('system/lib/libcxxabi/src' ),
419
- '-D__EMSCRIPTEN_EXCEPTIONS__' ,
420
- '-I' + utils .path_from_root ('system/lib/wasmfs/' ),
421
- '-std=c++17' ,
422
- ]
436
+ extra_cflags .append ('-U' + arg )
423
437
424
438
# Look for structs in all passed headers.
425
439
info = {'defines' : {}, 'structs' : {}}
@@ -429,11 +443,11 @@ def main(args):
429
443
header_files = parse_json (f )
430
444
# Inspect all collected structs.
431
445
if 'internal' in f :
432
- use_cflags = cflags + internal_cflags
446
+ use_cflags = CFLAGS + extra_cflags + INTERNAL_CFLAGS
433
447
elif 'cxx' in f :
434
- use_cflags = cflags + cxxflags
448
+ use_cflags = CFLAGS + extra_cflags + CXXFLAGS
435
449
else :
436
- use_cflags = cflags
450
+ use_cflags = CFLAGS + extra_cflags
437
451
info_fragment = inspect_code (header_files , use_cflags )
438
452
merge_info (info , info_fragment )
439
453
0 commit comments