50
50
from tools import wasm2c
51
51
from tools import webassembly
52
52
from tools import config
53
- from tools .settings import settings , MEM_SIZE_SETTINGS
53
+ from tools .settings import settings , MEM_SIZE_SETTINGS , COMPILE_TIME_SETTINGS
54
54
55
55
logger = logging .getLogger ('emcc' )
56
56
@@ -213,6 +213,15 @@ def __init__(self, args):
213
213
self .forced_stdlibs = []
214
214
215
215
216
+ def add_link_flag (state , i , f ):
217
+ if f .startswith ('-l' ):
218
+ state .libs .append ((i , f [2 :]))
219
+ if f .startswith ('-L' ):
220
+ state .lib_dirs .append (f [2 :])
221
+
222
+ state .link_flags .append ((i , f ))
223
+
224
+
216
225
class EmccOptions :
217
226
def __init__ (self ):
218
227
self .output_file = None
@@ -1032,9 +1041,15 @@ def run(args):
1032
1041
## Process argument and setup the compiler
1033
1042
state = EmccState (args )
1034
1043
options , newargs , settings_map = phase_parse_arguments (state )
1044
+
1045
+ # For internal consistency, ensure we don't attempt or read or write any link time
1046
+ # settings until we reach the linking phase.
1047
+ settings .limit_settings (COMPILE_TIME_SETTINGS )
1048
+
1035
1049
newargs , input_files = phase_setup (options , state , newargs , settings_map )
1036
1050
1037
1051
if options .post_link :
1052
+ settings .limit_settings (None )
1038
1053
target , wasm_target = phase_linker_setup (options , state , newargs , settings_map )
1039
1054
process_libraries (state .libs , state .lib_dirs , [])
1040
1055
if len (input_files ) != 1 :
@@ -1043,8 +1058,7 @@ def run(args):
1043
1058
return 0
1044
1059
1045
1060
## Compile source code to object files
1046
- linker_inputs = []
1047
- phase_compile_inputs (options , state , newargs , input_files , linker_inputs )
1061
+ linker_inputs = phase_compile_inputs (options , state , newargs , input_files )
1048
1062
1049
1063
if state .compile_only :
1050
1064
logger .debug ('stopping after compile phase' )
@@ -1055,6 +1069,9 @@ def run(args):
1055
1069
1056
1070
return 0
1057
1071
1072
+ # We have now passed the compile phase, allow reading/writing of all settings.
1073
+ settings .limit_settings (None )
1074
+
1058
1075
if options .output_file and options .output_file .startswith ('-' ):
1059
1076
exit_with_error ('invalid output filename: `%s`' % options .output_file )
1060
1077
@@ -1141,29 +1158,6 @@ def phase_parse_arguments(state):
1141
1158
if options .post_link or options .oformat == OFormat .BARE :
1142
1159
diagnostics .warning ('experimental' , '--oformat=base/--post-link are experimental and subject to change.' )
1143
1160
1144
- if options .emrun :
1145
- options .pre_js += open (shared .path_from_root ('src' , 'emrun_prejs.js' )).read () + '\n '
1146
- options .post_js += open (shared .path_from_root ('src' , 'emrun_postjs.js' )).read () + '\n '
1147
- # emrun mode waits on program exit
1148
- settings .EXIT_RUNTIME = 1
1149
-
1150
- if options .cpu_profiler :
1151
- options .post_js += open (shared .path_from_root ('src' , 'cpuprofiler.js' )).read () + '\n '
1152
-
1153
- if options .memory_profiler :
1154
- settings .MEMORYPROFILER = 1
1155
-
1156
- if options .thread_profiler :
1157
- options .post_js += open (shared .path_from_root ('src' , 'threadprofiler.js' )).read () + '\n '
1158
-
1159
- if options .memory_init_file is None :
1160
- options .memory_init_file = settings .OPT_LEVEL >= 2
1161
-
1162
- # TODO: support source maps with js_transform
1163
- if options .js_transform and settings .GENERATE_SOURCE_MAP :
1164
- logger .warning ('disabling source maps because a js transform is being done' )
1165
- settings .GENERATE_SOURCE_MAP = 0
1166
-
1167
1161
explicit_settings_changes , newargs = parse_s_args (newargs )
1168
1162
settings_changes += explicit_settings_changes
1169
1163
@@ -1206,14 +1200,6 @@ def phase_setup(options, state, newargs, settings_map):
1206
1200
# arguments that expand into multiple processed arguments, as in -Wl,-f1,-f2.
1207
1201
input_files = []
1208
1202
1209
- def add_link_flag (i , f ):
1210
- if f .startswith ('-l' ):
1211
- state .libs .append ((i , f [2 :]))
1212
- if f .startswith ('-L' ):
1213
- state .lib_dirs .append (f [2 :])
1214
-
1215
- state .link_flags .append ((i , f ))
1216
-
1217
1203
# find input files with a simple heuristic. we should really analyze
1218
1204
# based on a full understanding of gcc params, right now we just assume that
1219
1205
# what is left contains no more |-x OPT| things
@@ -1259,21 +1245,21 @@ def add_link_flag(i, f):
1259
1245
else :
1260
1246
input_files .append ((i , arg ))
1261
1247
elif arg .startswith ('-L' ):
1262
- add_link_flag (i , arg )
1248
+ add_link_flag (state , i , arg )
1263
1249
newargs [i ] = ''
1264
1250
elif arg .startswith ('-l' ):
1265
- add_link_flag (i , arg )
1251
+ add_link_flag (state , i , arg )
1266
1252
newargs [i ] = ''
1267
1253
elif arg .startswith ('-Wl,' ):
1268
1254
# Multiple comma separated link flags can be specified. Create fake
1269
1255
# fractional indices for these: -Wl,a,b,c,d at index 4 becomes:
1270
1256
# (4, a), (4.25, b), (4.5, c), (4.75, d)
1271
1257
link_flags_to_add = arg .split (',' )[1 :]
1272
1258
for flag_index , flag in enumerate (link_flags_to_add ):
1273
- add_link_flag (i + float (flag_index ) / len (link_flags_to_add ), flag )
1259
+ add_link_flag (state , i + float (flag_index ) / len (link_flags_to_add ), flag )
1274
1260
newargs [i ] = ''
1275
1261
elif arg == '-Xlinker' :
1276
- add_link_flag (i + 1 , newargs [i + 1 ])
1262
+ add_link_flag (state , i + 1 , newargs [i + 1 ])
1277
1263
newargs [i ] = ''
1278
1264
newargs [i + 1 ] = ''
1279
1265
elif arg == '-s' :
@@ -1307,10 +1293,6 @@ def add_link_flag(i, f):
1307
1293
# for key in settings_map:
1308
1294
# if key not in COMPILE_TIME_SETTINGS:
1309
1295
# diagnostics.warning('unused-command-line-argument', "linker setting ignored during compilation: '%s'" % key)
1310
- else :
1311
- ldflags = emsdk_ldflags (newargs )
1312
- for f in ldflags :
1313
- add_link_flag (sys .maxsize , f )
1314
1296
1315
1297
if state .has_dash_c or state .has_dash_S or state .has_dash_E or '-M' in newargs or '-MM' in newargs :
1316
1298
if state .has_dash_c :
@@ -1362,6 +1344,33 @@ def phase_linker_setup(options, state, newargs, settings_map):
1362
1344
# Add `#!` line to output JS and make it executable.
1363
1345
options .executable = True
1364
1346
1347
+ ldflags = emsdk_ldflags (newargs )
1348
+ for f in ldflags :
1349
+ add_link_flag (state , sys .maxsize , f )
1350
+
1351
+ if options .emrun :
1352
+ options .pre_js += open (shared .path_from_root ('src' , 'emrun_prejs.js' )).read () + '\n '
1353
+ options .post_js += open (shared .path_from_root ('src' , 'emrun_postjs.js' )).read () + '\n '
1354
+ # emrun mode waits on program exit
1355
+ settings .EXIT_RUNTIME = 1
1356
+
1357
+ if options .cpu_profiler :
1358
+ options .post_js += open (shared .path_from_root ('src' , 'cpuprofiler.js' )).read () + '\n '
1359
+
1360
+ if options .memory_profiler :
1361
+ settings .MEMORYPROFILER = 1
1362
+
1363
+ if options .thread_profiler :
1364
+ options .post_js += open (shared .path_from_root ('src' , 'threadprofiler.js' )).read () + '\n '
1365
+
1366
+ if options .memory_init_file is None :
1367
+ options .memory_init_file = settings .OPT_LEVEL >= 2
1368
+
1369
+ # TODO: support source maps with js_transform
1370
+ if options .js_transform and settings .GENERATE_SOURCE_MAP :
1371
+ logger .warning ('disabling source maps because a js transform is being done' )
1372
+ settings .GENERATE_SOURCE_MAP = 0
1373
+
1365
1374
# options.output_file is the user-specified one, target is what we will generate
1366
1375
if options .output_file :
1367
1376
target = options .output_file
@@ -2244,7 +2253,7 @@ def get_full_import_name(name):
2244
2253
2245
2254
2246
2255
@ToolchainProfiler .profile_block ('compile inputs' )
2247
- def phase_compile_inputs (options , state , newargs , input_files , linker_inputs ):
2256
+ def phase_compile_inputs (options , state , newargs , input_files ):
2248
2257
def is_link_flag (flag ):
2249
2258
if flag .startswith ('-nostdlib' ):
2250
2259
return True
@@ -2321,7 +2330,7 @@ def get_clang_command_asm(src_file):
2321
2330
# with -MF! (clang seems to not recognize it)
2322
2331
logger .debug (('just preprocessor ' if state .has_dash_E else 'just dependencies: ' ) + ' ' .join (cmd ))
2323
2332
shared .check_call (cmd )
2324
- return
2333
+ return []
2325
2334
2326
2335
# Precompiled headers support
2327
2336
if state .has_header_inputs :
@@ -2334,8 +2343,9 @@ def get_clang_command_asm(src_file):
2334
2343
cmd += ['-o' , options .output_file ]
2335
2344
logger .debug ("running (for precompiled headers): " + cmd [0 ] + ' ' + ' ' .join (cmd [1 :]))
2336
2345
shared .check_call (cmd )
2337
- return
2346
+ return []
2338
2347
2348
+ linker_inputs = []
2339
2349
seen_names = {}
2340
2350
2341
2351
def uniquename (name ):
@@ -2392,6 +2402,8 @@ def compile_source_file(i, input_file):
2392
2402
logger .debug ('using object file: ' + input_file )
2393
2403
linker_inputs .append ((i , input_file ))
2394
2404
2405
+ return linker_inputs
2406
+
2395
2407
2396
2408
@ToolchainProfiler .profile_block ('calculate system libraries' )
2397
2409
def phase_calculate_system_libraries (state , linker_arguments , linker_inputs , newargs ):
0 commit comments