Skip to content

Commit

Permalink
When compiling, use a single clang command for all input sources. NFC
Browse files Browse the repository at this point in the history
For folks that compiler a bunch of source files at once which should
help by reducing the number of clang subprocesses that we spawn.  This
includes the new system library build process that we use internally.
See emscripten-core#20577.

Do the same for PCH compilation and pre-processing (-E).
  • Loading branch information
sbc100 committed Nov 14, 2023
1 parent 875e31c commit 81cd044
Showing 1 changed file with 41 additions and 30 deletions.
71 changes: 41 additions & 30 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,7 @@ def run(args):

## Process argument and setup the compiler
state = EmccState(args)
options, newargs = phase_parse_arguments(state)
options, phase1_args = phase_parse_arguments(state)

if not shared.SKIP_SUBPROCS:
shared.check_sanity()
Expand All @@ -1282,7 +1282,7 @@ def run(args):
# settings until we reach the linking phase.
settings.limit_settings(COMPILE_TIME_SETTINGS)

newargs, input_files = phase_setup(options, state, newargs)
newargs, input_files = phase_setup(options, state, phase1_args)

if '-dumpmachine' in newargs or '-print-target-triple' in newargs or '--print-target-triple' in newargs:
print(shared.get_llvm_target())
Expand Down Expand Up @@ -1627,8 +1627,6 @@ def phase_setup(options, state, newargs):
elif '-M' in newargs or '-MM' in newargs:
options.default_object_extension = '.mout' # not bitcode, not js; but just dependency rule of the input file

if options.output_file and len(input_files) > 1:
exit_with_error('cannot specify -o with -c/-S/-E/-M and multiple source files')
else:
for arg in state.orig_args:
if any(arg.startswith(f) for f in COMPILE_ONLY_FLAGS):
Expand Down Expand Up @@ -3064,40 +3062,52 @@ def get_language_mode(args):
language_mode = get_language_mode(newargs)
use_cxx = 'c++' in language_mode or run_via_emxx

def get_clang_command(src_file):
return compiler + get_cflags(state.orig_args, use_cxx) + compile_args + [src_file]
def get_clang_command():
return compiler + get_cflags(state.orig_args, use_cxx) + compile_args

def get_clang_command_preprocessed(src_file):
return compiler + get_clang_flags(state.orig_args) + compile_args + [src_file]
def get_clang_command_preprocessed():
return compiler + get_clang_flags(state.orig_args) + compile_args

def get_clang_command_asm(src_file):
return compiler + get_target_flags() + compile_args + [src_file]
def get_clang_command_asm():
return compiler + get_target_flags() + compile_args

# preprocessor-only (-E) support
if state.mode == Mode.PREPROCESS_ONLY:
for input_file in [x[1] for x in input_files]:
cmd = get_clang_command(input_file)
if options.output_file:
cmd += ['-o', options.output_file]
# Do not compile, but just output the result from preprocessing stage or
# output the dependency rule. Warning: clang and gcc behave differently
# with -MF! (clang seems to not recognize it)
logger.debug(('just preprocessor ' if state.has_dash_E else 'just dependencies: ') + ' '.join(cmd))
shared.check_call(cmd)
inputs = [i[1] for i in input_files]
cmd = get_clang_command() + inputs
if options.output_file:
cmd += ['-o', options.output_file]
# Do not compile, but just output the result from preprocessing stage or
# output the dependency rule. Warning: clang and gcc behave differently
# with -MF! (clang seems to not recognize it)
logger.debug(('just preprocessor ' if state.has_dash_E else 'just dependencies: ') + ' '.join(cmd))
shared.check_call(cmd)
return []

# Precompiled headers support
if state.mode == Mode.PCH:
headers = [header for _, header in input_files]
for header in headers:
inputs = [i[1] for i in input_files]
for header in inputs:
if not shared.suffix(header) in HEADER_ENDINGS:
exit_with_error(f'cannot mix precompiled headers with non-header inputs: {headers} : {header}')
cmd = get_clang_command(header)
if options.output_file:
cmd += ['-o', options.output_file]
logger.debug(f"running (for precompiled headers): {cmd[0]} {' '.join(cmd[1:])}")
shared.check_call(cmd)
return []
cmd = get_clang_command() + inputs
if options.output_file:
cmd += ['-o', options.output_file]
logger.debug(f"running (for precompiled headers): {cmd[0]} {' '.join(cmd[1:])}")
shared.check_call(cmd)
return []

if state.mode == Mode.COMPILE_ONLY:
inputs = [i[1] for i in input_files]
if all(get_file_suffix(i) in ASSEMBLY_ENDINGS for i in inputs):
cmd = get_clang_command_asm()
else:
cmd = get_clang_command()
if options.output_file:
cmd += ['-o', options.output_file]
cmd += inputs
shared.check_call(cmd)
return []

linker_inputs = []
seen_names = {}
Expand Down Expand Up @@ -3127,13 +3137,14 @@ def compile_source_file(i, input_file):
if state.mode not in (Mode.COMPILE_ONLY, Mode.PREPROCESS_ONLY):
linker_inputs.append((i, output_file))
if get_file_suffix(input_file) in ASSEMBLY_ENDINGS:
cmd = get_clang_command_asm(input_file)
cmd = get_clang_command_asm()
elif get_file_suffix(input_file) in PREPROCESSED_ENDINGS:
cmd = get_clang_command_preprocessed(input_file)
cmd = get_clang_command_preprocessed()
else:
cmd = get_clang_command(input_file)
cmd = get_clang_command()
if get_file_suffix(input_file) in ['.pcm']:
cmd = [c for c in cmd if not c.startswith('-fprebuilt-module-path=')]
cmd += [input_file]
if not state.has_dash_c:
cmd += ['-c']
cmd += ['-o', output_file]
Expand Down

0 comments on commit 81cd044

Please sign in to comment.