Skip to content

Commit a8e9dd5

Browse files
authored
Add support for -### compiler flag (#20475)
From the gcc man page: ``` -### Like -v except the commands are not executed and arguments are quoted unless they contain only alphanumeric characters or "./-_". This is useful for shell scripts to capture the driver-generated command lines. ``` Fixes: #20468
1 parent 2832299 commit a8e9dd5

File tree

6 files changed

+51
-13
lines changed

6 files changed

+51
-13
lines changed

embuilder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ def main():
198198
settings.LTO = args.lto
199199

200200
if args.verbose:
201-
shared.PRINT_STAGES = True
201+
shared.PRINT_SUBPROCS = True
202202

203203
if args.pic:
204204
settings.RELOCATABLE = 1

emcc.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,8 @@ def run(args):
12571257
state = EmccState(args)
12581258
options, newargs = phase_parse_arguments(state)
12591259

1260-
shared.check_sanity()
1260+
if not shared.SKIP_SUBPROCS:
1261+
shared.check_sanity()
12611262

12621263
if 'EMMAKEN_NO_SDK' in os.environ:
12631264
exit_with_error('EMMAKEN_NO_SDK is no longer supported. The standard -nostdlib and -nostdinc flags should be used instead')
@@ -1331,7 +1332,7 @@ def run(args):
13311332
return 0
13321333

13331334
js_syms = {}
1334-
if not settings.SIDE_MODULE or settings.ASYNCIFY:
1335+
if (not settings.SIDE_MODULE or settings.ASYNCIFY) and not shared.SKIP_SUBPROCS:
13351336
js_info = get_js_sym_info()
13361337
if not settings.SIDE_MODULE:
13371338
js_syms = js_info['deps']
@@ -3128,7 +3129,7 @@ def compile_source_file(i, input_file):
31283129
cmd += ['-Xclang', '-split-dwarf-file', '-Xclang', unsuffixed_basename(input_file) + '.dwo']
31293130
cmd += ['-Xclang', '-split-dwarf-output', '-Xclang', unsuffixed_basename(input_file) + '.dwo']
31303131
shared.check_call(cmd)
3131-
if output_file not in ('-', os.devnull):
3132+
if output_file not in ('-', os.devnull) and not shared.SKIP_SUBPROCS:
31323133
assert os.path.exists(output_file)
31333134

31343135
# First, generate LLVM bitcode. For each input file, we get base.o with bitcode
@@ -3229,6 +3230,9 @@ def phase_emscript(options, in_wasm, wasm_target, memfile, js_syms):
32293230

32303231
settings.SUPPORT_BASE64_EMBEDDING = embed_memfile(options)
32313232

3233+
if shared.SKIP_SUBPROCS:
3234+
return
3235+
32323236
emscripten.run(in_wasm, wasm_target, final_js, memfile, js_syms)
32333237
save_intermediate('original')
32343238

@@ -3315,6 +3319,9 @@ def create_worker_file(input_file, target_dir, output_file):
33153319
def phase_final_emitting(options, state, target, wasm_target, memfile):
33163320
global final_js
33173321

3322+
if shared.SKIP_SUBPROCS:
3323+
return
3324+
33183325
target_dir = os.path.dirname(os.path.abspath(target))
33193326
if settings.PTHREADS:
33203327
create_worker_file('src/worker.js', target_dir, settings.PTHREAD_WORKER_FILE)
@@ -3601,7 +3608,9 @@ def consume_arg_file():
36013608
elif check_flag('--ignore-dynamic-linking'):
36023609
options.ignore_dynamic_linking = True
36033610
elif arg == '-v':
3604-
shared.PRINT_STAGES = True
3611+
shared.PRINT_SUBPROCS = True
3612+
elif arg == '-###':
3613+
shared.SKIP_SUBPROCS = True
36053614
elif check_arg('--shell-file'):
36063615
options.shell_path = consume_arg_file()
36073616
elif check_arg('--source-map-base'):

emsymbolizer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def get_args():
246246
parser.add_argument('address', help='Address to lookup')
247247
args = parser.parse_args()
248248
if args.verbose:
249-
shared.PRINT_STAGES = 1
249+
shared.PRINT_SUBPROCS = 1
250250
shared.DEBUG = True
251251
return args
252252

test/test_other.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
from tools.shared import config
3030
from tools.shared import EMCC, EMXX, EMAR, EMRANLIB, FILE_PACKAGER, WINDOWS, LLVM_NM
31-
from tools.shared import CLANG_CC, CLANG_CXX, LLVM_AR, LLVM_DWARFDUMP, LLVM_DWP, EMCMAKE, EMCONFIGURE
31+
from tools.shared import CLANG_CC, CLANG_CXX, LLVM_AR, LLVM_DWARFDUMP, LLVM_DWP, EMCMAKE, EMCONFIGURE, WASM_LD
3232
from common import RunnerCore, path_from_root, is_slow_test, ensure_dir, disabled, make_executable
3333
from common import env_modify, no_mac, no_windows, only_windows, requires_native_clang, with_env_modify
3434
from common import create_file, parameterized, NON_ZERO, node_pthreads, TEST_ROOT, test_file
@@ -257,6 +257,21 @@ def test_emcc_v(self):
257257
self.assertContained('Target: wasm32-unknown-emscripten', proc.stderr)
258258
self.assertNotContained('this is dangerous', proc.stderr)
259259

260+
def test_log_subcommands(self):
261+
# `-v` when combined with other arguments will trace the subcommands
262+
# that get run
263+
proc = self.run_process([EMCC, '-v', test_file('hello_world.c')], stdout=PIPE, stderr=PIPE)
264+
self.assertContained(CLANG_CC, proc.stderr)
265+
self.assertContained(WASM_LD, proc.stderr)
266+
self.assertExists('a.out.js')
267+
268+
def test_skip_subcommands(self):
269+
# The -### flag is like `-v` but it doesn't actaully execute the sub-commands
270+
proc = self.run_process([EMCC, '-###', test_file('hello_world.c')], stdout=PIPE, stderr=PIPE)
271+
self.assertContained(CLANG_CC, proc.stderr)
272+
self.assertContained(WASM_LD, proc.stderr)
273+
self.assertNotExists('a.out.js')
274+
260275
def test_emcc_check(self):
261276
proc = self.run_process([EMCC, '--check'], stdout=PIPE, stderr=PIPE)
262277
self.assertEqual(proc.stdout, '')

tools/shared.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@
4949

5050

5151
DEBUG_SAVE = DEBUG or int(os.environ.get('EMCC_DEBUG_SAVE', '0'))
52-
PRINT_STAGES = int(os.getenv('EMCC_VERBOSE', '0'))
52+
PRINT_SUBPROCS = int(os.getenv('EMCC_VERBOSE', '0'))
53+
SKIP_SUBPROCS = False
54+
5355
# Minimum node version required to run the emscripten compiler. This is distinct
5456
# from the minimum version required to execute the generated code. This is not an
5557
# exact requirement, but is the oldest version of node that we do any testing with.
@@ -225,6 +227,8 @@ def get_finished_process():
225227
def check_call(cmd, *args, **kw):
226228
"""Like `run_process` above but treat failures as fatal and exit_with_error."""
227229
print_compiler_stage(cmd)
230+
if SKIP_SUBPROCS:
231+
return 0
228232
try:
229233
return run_process(cmd, *args, **kw)
230234
except subprocess.CalledProcessError as e:
@@ -616,10 +620,20 @@ def target_environment_may_be(environment):
616620

617621

618622
def print_compiler_stage(cmd):
619-
"""Emulate the '-v' of clang/gcc by printing the name of the sub-command
620-
before executing it."""
621-
if PRINT_STAGES:
622-
print(' "%s" %s' % (cmd[0], shlex_join(cmd[1:])), file=sys.stderr)
623+
"""Emulate the '-v/-###' flags of clang/gcc by printing the sub-commands
624+
that we run."""
625+
626+
def maybe_quote(arg):
627+
if all(c.isalnum() or c in './-_' for c in arg):
628+
return arg
629+
else:
630+
return f'"{arg}"'
631+
632+
if SKIP_SUBPROCS:
633+
print(' ' + ' '.join([maybe_quote(a) for a in cmd]), file=sys.stderr)
634+
sys.stderr.flush()
635+
elif PRINT_SUBPROCS:
636+
print(' %s %s' % (maybe_quote(cmd[0]), shlex_join(cmd[1:])), file=sys.stderr)
623637
sys.stderr.flush()
624638

625639

tools/system_libs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def get_top_level_ninja_file():
140140
def run_ninja(build_dir):
141141
diagnostics.warning('experimental', 'ninja support is experimental')
142142
cmd = ['ninja', '-C', build_dir, f'-j{shared.get_num_cores()}']
143-
if shared.PRINT_STAGES:
143+
if shared.PRINT_SUBPROCS:
144144
cmd.append('-v')
145145
shared.check_call(cmd, env=clean_env())
146146

0 commit comments

Comments
 (0)