@@ -139,6 +139,7 @@ class EmccOptions:
139
139
def __init__ (self ):
140
140
self .target = ''
141
141
self .output_file = None
142
+ self .input_files = []
142
143
self .no_minify = False
143
144
self .post_link = False
144
145
self .save_temps = False
@@ -659,21 +660,23 @@ def run(args):
659
660
# settings until we reach the linking phase.
660
661
settings .limit_settings (COMPILE_TIME_SETTINGS )
661
662
662
- newargs , input_files = phase_setup (options , state , newargs )
663
+ phase_setup (options , state , newargs )
663
664
664
665
if options .reproduce :
665
666
create_reproduce_file (options .reproduce , args )
666
667
667
668
if state .mode == Mode .POST_LINK_ONLY :
668
- if len (input_files ) != 1 :
669
+ if len (options . input_files ) != 1 :
669
670
exit_with_error ('--post-link requires a single input file' )
671
+ separate_linker_flags (options , state , newargs )
670
672
# Delay import of link.py to avoid processing this file when only compiling
671
673
from tools import link
672
- link .run_post_link (input_files [0 ][ 1 ], options , state )
674
+ link .run_post_link (options . input_files [0 ], options , state )
673
675
return 0
674
676
675
- ## Compile source code to object files
676
- linker_inputs = phase_compile_inputs (options , state , newargs , input_files )
677
+ # Compile source code to object files
678
+ # When only compiling this function never returns.
679
+ linker_inputs = phase_compile_inputs (options , state , newargs )
677
680
678
681
if state .mode == Mode .COMPILE_AND_LINK :
679
682
# Delay import of link.py to avoid processing this file when only compiling
@@ -711,11 +714,13 @@ def phase_parse_arguments(state):
711
714
settings .WARN_DEPRECATED = 0
712
715
713
716
for i in range (len (newargs )):
714
- if newargs [i ] in ('-l' , '-L' , '-I' , '-z' , '--js-library' ):
717
+ if newargs [i ] in ('-l' , '-L' , '-I' , '-z' , '--js-library' , '-o' ):
715
718
# Scan for flags that can be written as either one or two arguments
716
719
# and normalize them to the single argument form.
717
720
if newargs [i ] == '--js-library' :
718
721
newargs [i ] += '='
722
+ if len (newargs ) <= i + 1 :
723
+ exit_with_error (f"option '{ newargs [i ]} ' requires an argument" )
719
724
newargs [i ] += newargs [i + 1 ]
720
725
newargs [i + 1 ] = ''
721
726
@@ -748,10 +753,8 @@ def phase_parse_arguments(state):
748
753
return options , newargs
749
754
750
755
751
- @ToolchainProfiler .profile_block ('setup' )
752
- def phase_setup (options , state , newargs ):
753
- """Second phase: configure and setup the compiler based on the specified settings and arguments.
754
- """
756
+ def separate_linker_flags (options , state , newargs ):
757
+ newargs = list (newargs )
755
758
756
759
if settings .RUNTIME_LINKED_LIBS :
757
760
newargs += settings .RUNTIME_LINKED_LIBS
@@ -769,7 +772,6 @@ def phase_setup(options, state, newargs):
769
772
# based on a full understanding of gcc params, right now we just assume that
770
773
# what is left contains no more |-x OPT| things
771
774
skip = False
772
- has_header_inputs = False
773
775
for i in range (len (newargs )):
774
776
if skip :
775
777
skip = False
@@ -792,10 +794,9 @@ def get_next_arg():
792
794
# https://bugs.python.org/issue1311
793
795
if not os .path .exists (arg ) and arg != os .devnull :
794
796
exit_with_error ('%s: No such file or directory ("%s" was expected to be an input file, based on the commandline arguments provided)' , arg , arg )
795
- file_suffix = get_file_suffix (arg )
796
- if file_suffix in HEADER_ENDINGS :
797
- has_header_inputs = True
798
797
input_files .append ((i , arg ))
798
+ elif arg .startswith ('-o' ):
799
+ newargs [i ] = ''
799
800
elif arg .startswith ('-L' ):
800
801
state .add_link_flag (i , arg )
801
802
elif arg .startswith ('-l' ):
@@ -824,9 +825,15 @@ def get_next_arg():
824
825
825
826
newargs = [a for a in newargs if a ]
826
827
827
- # SSEx is implemented on top of SIMD128 instruction set, but do not pass SSE flags to LLVM
828
- # so it won't think about generating native x86 SSE code.
829
- newargs = [x for x in newargs if x not in SIMD_INTEL_FEATURE_TOWER and x not in SIMD_NEON_FLAGS ]
828
+ return newargs , input_files
829
+
830
+
831
+ @ToolchainProfiler .profile_block ('setup' )
832
+ def phase_setup (options , state , newargs ):
833
+ """Second phase: configure and setup the compiler based on the specified settings and arguments.
834
+ """
835
+
836
+ has_header_inputs = any (get_file_suffix (f ) in HEADER_ENDINGS for f in options .input_files )
830
837
831
838
if options .post_link :
832
839
state .mode = Mode .POST_LINK_ONLY
@@ -928,8 +935,6 @@ def get_next_arg():
928
935
if settings .USE_SDL == 2 or settings .USE_SDL_MIXER == 2 or settings .USE_SDL_GFX == 2 :
929
936
default_setting ('GL_ENABLE_GET_PROC_ADDRESS' , 1 )
930
937
931
- return (newargs , input_files )
932
-
933
938
934
939
def filter_out_link_flags (args ):
935
940
rtn = []
@@ -954,7 +959,7 @@ def is_link_flag(flag):
954
959
955
960
956
961
@ToolchainProfiler .profile_block ('compile inputs' )
957
- def phase_compile_inputs (options , state , compile_args , input_files ):
962
+ def phase_compile_inputs (options , state , newargs ):
958
963
if shared .run_via_emxx :
959
964
compiler = [shared .CLANG_CXX ]
960
965
else :
@@ -978,24 +983,21 @@ def get_language_mode(args):
978
983
return removeprefix (item , '-x' )
979
984
return ''
980
985
981
- language_mode = get_language_mode (compile_args )
986
+ language_mode = get_language_mode (newargs )
982
987
use_cxx = 'c++' in language_mode or shared .run_via_emxx
983
988
984
989
def get_clang_command ():
985
- return compiler + get_cflags (state .orig_args , use_cxx ) + compile_args
990
+ return compiler + get_cflags (state .orig_args , use_cxx )
986
991
987
992
def get_clang_command_preprocessed ():
988
- return compiler + get_clang_flags (state .orig_args ) + compile_args
993
+ return compiler + get_clang_flags (state .orig_args )
989
994
990
995
def get_clang_command_asm ():
991
- return compiler + get_target_flags () + compile_args
996
+ return compiler + get_target_flags ()
992
997
993
998
# preprocessor-only (-E/-M) support
994
999
if state .mode == Mode .PREPROCESS_ONLY :
995
- inputs = [i [1 ] for i in input_files ]
996
- cmd = get_clang_command () + inputs
997
- if options .output_file :
998
- cmd += ['-o' , options .output_file ]
1000
+ cmd = get_clang_command () + newargs
999
1001
# Do not compile, but just output the result from preprocessing stage or
1000
1002
# output the dependency rule. Warning: clang and gcc behave differently
1001
1003
# with -MF! (clang seems to not recognize it)
@@ -1005,34 +1007,26 @@ def get_clang_command_asm():
1005
1007
1006
1008
# Precompiled headers support
1007
1009
if state .mode == Mode .PCH :
1008
- inputs = [i [1 ] for i in input_files ]
1009
- for header in inputs :
1010
- if shared .suffix (header ) not in HEADER_ENDINGS :
1011
- exit_with_error (f'cannot mix precompiled headers with non-header inputs: { inputs } : { header } ' )
1012
- cmd = get_clang_command () + inputs
1013
- if options .output_file :
1014
- cmd += ['-o' , options .output_file ]
1010
+ cmd = get_clang_command () + newargs
1015
1011
logger .debug (f"running (for precompiled headers): { cmd [0 ]} { ' ' .join (cmd [1 :])} " )
1016
1012
shared .exec_process (cmd )
1017
1013
assert False , 'exec_process does not return'
1018
1014
1019
1015
if state .mode == Mode .COMPILE_ONLY :
1020
- inputs = [i [1 ] for i in input_files ]
1021
- if all (get_file_suffix (i ) in ASSEMBLY_ENDINGS for i in inputs ):
1022
- cmd = get_clang_command_asm () + inputs
1016
+ if options .output_file and get_file_suffix (options .output_file ) == '.bc' and not settings .LTO and '-emit-llvm' not in state .orig_args :
1017
+ diagnostics .warning ('emcc' , '.bc output file suffix used without -flto or -emit-llvm. Consider using .o extension since emcc will output an object file, not a bitcode file' )
1018
+ if all (get_file_suffix (i ) in ASSEMBLY_ENDINGS for i in options .input_files ):
1019
+ cmd = get_clang_command_asm () + newargs
1023
1020
else :
1024
- cmd = get_clang_command () + inputs
1025
- if options .output_file :
1026
- cmd += ['-o' , options .output_file ]
1027
- if get_file_suffix (options .output_file ) == '.bc' and not settings .LTO and '-emit-llvm' not in state .orig_args :
1028
- diagnostics .warning ('emcc' , '.bc output file suffix used without -flto or -emit-llvm. Consider using .o extension since emcc will output an object file, not a bitcode file' )
1021
+ cmd = get_clang_command () + newargs
1029
1022
shared .exec_process (cmd )
1030
1023
assert False , 'exec_process does not return'
1031
1024
1032
1025
# In COMPILE_AND_LINK we need to compile source files too, but we also need to
1033
1026
# filter out the link flags
1034
1027
assert state .mode == Mode .COMPILE_AND_LINK
1035
1028
assert not options .dash_c
1029
+ compile_args , input_files = separate_linker_flags (options , state , newargs )
1036
1030
compile_args = filter_out_link_flags (compile_args )
1037
1031
linker_inputs = []
1038
1032
seen_names = {}
@@ -1057,7 +1051,7 @@ def compile_source_file(i, input_file):
1057
1051
cmd = get_clang_command ()
1058
1052
if get_file_suffix (input_file ) in ['.pcm' ]:
1059
1053
cmd = [c for c in cmd if not c .startswith ('-fprebuilt-module-path=' )]
1060
- cmd += ['-c' , input_file , '-o' , output_file ]
1054
+ cmd += compile_args + ['-c' , input_file , '-o' , output_file ]
1061
1055
if state .mode == Mode .COMPILE_AND_LINK and options .requested_debug == '-gsplit-dwarf' :
1062
1056
# When running in COMPILE_AND_LINK mode we compile to temporary location
1063
1057
# but we want the `.dwo` file to be generated in the current working directory,
@@ -1481,11 +1475,8 @@ def consume_arg_file():
1481
1475
options .shared = True
1482
1476
elif check_flag ('-r' ):
1483
1477
options .relocatable = True
1484
- elif check_arg ('-o' ):
1485
- options .output_file = consume_arg ()
1486
1478
elif arg .startswith ('-o' ):
1487
1479
options .output_file = removeprefix (arg , '-o' )
1488
- newargs [i ] = ''
1489
1480
elif check_arg ('-target' ) or check_arg ('--target' ):
1490
1481
options .target = consume_arg ()
1491
1482
if options .target not in ('wasm32' , 'wasm64' , 'wasm64-unknown-emscripten' , 'wasm32-unknown-emscripten' ):
@@ -1502,6 +1493,12 @@ def consume_arg_file():
1502
1493
options .dash_M = True
1503
1494
elif arg == '-fsyntax-only' :
1504
1495
options .syntax_only = True
1496
+ elif arg in SIMD_INTEL_FEATURE_TOWER or arg in SIMD_NEON_FLAGS :
1497
+ # SSEx is implemented on top of SIMD128 instruction set, but do not pass SSE flags to LLVM
1498
+ # so it won't think about generating native x86 SSE code.
1499
+ newargs [i ] = ''
1500
+ elif arg and (arg == '-' or not arg .startswith ('-' )):
1501
+ options .input_files .append (arg )
1505
1502
1506
1503
if should_exit :
1507
1504
sys .exit (0 )
0 commit comments