@@ -139,6 +139,7 @@ class EmccOptions:
139139 def __init__ (self ):
140140 self .target = ''
141141 self .output_file = None
142+ self .input_files = []
142143 self .no_minify = False
143144 self .post_link = False
144145 self .save_temps = False
@@ -659,21 +660,23 @@ def run(args):
659660 # settings until we reach the linking phase.
660661 settings .limit_settings (COMPILE_TIME_SETTINGS )
661662
662- newargs , input_files = phase_setup (options , state , newargs )
663+ phase_setup (options , state , newargs )
663664
664665 if options .reproduce :
665666 create_reproduce_file (options .reproduce , args )
666667
667668 if state .mode == Mode .POST_LINK_ONLY :
668- if len (input_files ) != 1 :
669+ if len (options . input_files ) != 1 :
669670 exit_with_error ('--post-link requires a single input file' )
671+ separate_linker_flags (options , state , newargs )
670672 # Delay import of link.py to avoid processing this file when only compiling
671673 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 )
673675 return 0
674676
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 )
677680
678681 if state .mode == Mode .COMPILE_AND_LINK :
679682 # Delay import of link.py to avoid processing this file when only compiling
@@ -711,11 +714,13 @@ def phase_parse_arguments(state):
711714 settings .WARN_DEPRECATED = 0
712715
713716 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' ):
715718 # Scan for flags that can be written as either one or two arguments
716719 # and normalize them to the single argument form.
717720 if newargs [i ] == '--js-library' :
718721 newargs [i ] += '='
722+ if len (newargs ) <= i + 1 :
723+ exit_with_error (f"option '{ newargs [i ]} ' requires an argument" )
719724 newargs [i ] += newargs [i + 1 ]
720725 newargs [i + 1 ] = ''
721726
@@ -748,10 +753,8 @@ def phase_parse_arguments(state):
748753 return options , newargs
749754
750755
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 )
755758
756759 if settings .RUNTIME_LINKED_LIBS :
757760 newargs += settings .RUNTIME_LINKED_LIBS
@@ -769,7 +772,6 @@ def phase_setup(options, state, newargs):
769772 # based on a full understanding of gcc params, right now we just assume that
770773 # what is left contains no more |-x OPT| things
771774 skip = False
772- has_header_inputs = False
773775 for i in range (len (newargs )):
774776 if skip :
775777 skip = False
@@ -792,10 +794,9 @@ def get_next_arg():
792794 # https://bugs.python.org/issue1311
793795 if not os .path .exists (arg ) and arg != os .devnull :
794796 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
798797 input_files .append ((i , arg ))
798+ elif arg .startswith ('-o' ):
799+ newargs [i ] = ''
799800 elif arg .startswith ('-L' ):
800801 state .add_link_flag (i , arg )
801802 elif arg .startswith ('-l' ):
@@ -824,9 +825,15 @@ def get_next_arg():
824825
825826 newargs = [a for a in newargs if a ]
826827
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 )
830837
831838 if options .post_link :
832839 state .mode = Mode .POST_LINK_ONLY
@@ -928,8 +935,6 @@ def get_next_arg():
928935 if settings .USE_SDL == 2 or settings .USE_SDL_MIXER == 2 or settings .USE_SDL_GFX == 2 :
929936 default_setting ('GL_ENABLE_GET_PROC_ADDRESS' , 1 )
930937
931- return (newargs , input_files )
932-
933938
934939def filter_out_link_flags (args ):
935940 rtn = []
@@ -954,7 +959,7 @@ def is_link_flag(flag):
954959
955960
956961@ToolchainProfiler .profile_block ('compile inputs' )
957- def phase_compile_inputs (options , state , compile_args , input_files ):
962+ def phase_compile_inputs (options , state , newargs ):
958963 if shared .run_via_emxx :
959964 compiler = [shared .CLANG_CXX ]
960965 else :
@@ -978,24 +983,21 @@ def get_language_mode(args):
978983 return removeprefix (item , '-x' )
979984 return ''
980985
981- language_mode = get_language_mode (compile_args )
986+ language_mode = get_language_mode (newargs )
982987 use_cxx = 'c++' in language_mode or shared .run_via_emxx
983988
984989 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 )
986991
987992 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 )
989994
990995 def get_clang_command_asm ():
991- return compiler + get_target_flags () + compile_args
996+ return compiler + get_target_flags ()
992997
993998 # preprocessor-only (-E/-M) support
994999 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
9991001 # Do not compile, but just output the result from preprocessing stage or
10001002 # output the dependency rule. Warning: clang and gcc behave differently
10011003 # with -MF! (clang seems to not recognize it)
@@ -1005,34 +1007,26 @@ def get_clang_command_asm():
10051007
10061008 # Precompiled headers support
10071009 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
10151011 logger .debug (f"running (for precompiled headers): { cmd [0 ]} { ' ' .join (cmd [1 :])} " )
10161012 shared .exec_process (cmd )
10171013 assert False , 'exec_process does not return'
10181014
10191015 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
10231020 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
10291022 shared .exec_process (cmd )
10301023 assert False , 'exec_process does not return'
10311024
10321025 # In COMPILE_AND_LINK we need to compile source files too, but we also need to
10331026 # filter out the link flags
10341027 assert state .mode == Mode .COMPILE_AND_LINK
10351028 assert not options .dash_c
1029+ compile_args , input_files = separate_linker_flags (options , state , newargs )
10361030 compile_args = filter_out_link_flags (compile_args )
10371031 linker_inputs = []
10381032 seen_names = {}
@@ -1057,7 +1051,7 @@ def compile_source_file(i, input_file):
10571051 cmd = get_clang_command ()
10581052 if get_file_suffix (input_file ) in ['.pcm' ]:
10591053 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 ]
10611055 if state .mode == Mode .COMPILE_AND_LINK and options .requested_debug == '-gsplit-dwarf' :
10621056 # When running in COMPILE_AND_LINK mode we compile to temporary location
10631057 # but we want the `.dwo` file to be generated in the current working directory,
@@ -1481,11 +1475,8 @@ def consume_arg_file():
14811475 options .shared = True
14821476 elif check_flag ('-r' ):
14831477 options .relocatable = True
1484- elif check_arg ('-o' ):
1485- options .output_file = consume_arg ()
14861478 elif arg .startswith ('-o' ):
14871479 options .output_file = removeprefix (arg , '-o' )
1488- newargs [i ] = ''
14891480 elif check_arg ('-target' ) or check_arg ('--target' ):
14901481 options .target = consume_arg ()
14911482 if options .target not in ('wasm32' , 'wasm64' , 'wasm64-unknown-emscripten' , 'wasm32-unknown-emscripten' ):
@@ -1502,6 +1493,12 @@ def consume_arg_file():
15021493 options .dash_M = True
15031494 elif arg == '-fsyntax-only' :
15041495 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 )
15051502
15061503 if should_exit :
15071504 sys .exit (0 )
0 commit comments