Skip to content

Commit db39c2d

Browse files
authored
Warn about linker inputs when linking is not done (emscripten-core#13921)
When in compile-only mode warn about unused linker inputs. I took the error string directly from gcc here. ``` $ gcc -c a.o -o out.o gcc: warning: a.o: linker input file unused because linking not done $ echo $? 0 $ stat out.o stat: cannot statx 'out.o': No such file or directory ``` Also, rename `temp_files` to `linker_inputs` which better reflects its purpose. Fixes: emscripten-core#13919
1 parent ac5f5cb commit db39c2d

File tree

2 files changed

+30
-23
lines changed

2 files changed

+30
-23
lines changed

emcc.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2093,22 +2093,19 @@ def get_full_import_name(name):
20932093
settings.PROFILING_FUNCS = options.profiling_funcs
20942094
settings.SOURCE_MAP_BASE = options.source_map_base or ''
20952095

2096-
## Compile source code to bitcode
2097-
2098-
logger.debug('compiling to bitcode')
2099-
2100-
temp_files = []
2101-
21022096
# exit block 'parse arguments and setup'
21032097
log_time('parse arguments and setup')
21042098

2099+
linker_inputs = []
21052100
if options.post_link:
2106-
process_libraries(libs, lib_dirs, temp_files)
2101+
process_libraries(libs, lib_dirs, linker_inputs)
21072102
if len(input_files) != 1:
21082103
exit_with_error('--post-link requires a single input file')
21092104
post_link(options, input_files[0][1], wasm_target, target)
21102105
return 0
21112106

2107+
## Compile source code to object files
2108+
logger.debug('compiling inputs')
21122109
with ToolchainProfiler.profile_block('compile inputs'):
21132110
def is_link_flag(flag):
21142111
if flag.startswith('-nostdlib'):
@@ -2202,7 +2199,8 @@ def get_object_filename(input_file):
22022199
def compile_source_file(i, input_file):
22032200
logger.debug('compiling source file: ' + input_file)
22042201
output_file = get_object_filename(input_file)
2205-
temp_files.append((i, output_file))
2202+
if not compile_only:
2203+
linker_inputs.append((i, output_file))
22062204
if get_file_suffix(input_file) in ASSEMBLY_ENDINGS:
22072205
cmd = get_clang_command_asm(input_file)
22082206
else:
@@ -2221,19 +2219,19 @@ def compile_source_file(i, input_file):
22212219
compile_source_file(i, input_file)
22222220
elif file_suffix in DYNAMICLIB_ENDINGS:
22232221
logger.debug('using shared library: ' + input_file)
2224-
temp_files.append((i, input_file))
2222+
linker_inputs.append((i, input_file))
22252223
elif building.is_ar(input_file):
22262224
logger.debug('using static library: ' + input_file)
22272225
ensure_archive_index(input_file)
2228-
temp_files.append((i, input_file))
2226+
linker_inputs.append((i, input_file))
22292227
elif language_mode:
22302228
compile_source_file(i, input_file)
22312229
elif input_file == '-':
22322230
exit_with_error('-E or -x required when input is from standard input')
22332231
else:
22342232
# Default to assuming the inputs are object files and pass them to the linker
22352233
logger.debug('using object file: ' + input_file)
2236-
temp_files.append((i, input_file))
2234+
linker_inputs.append((i, input_file))
22372235

22382236
# exit block 'compile inputs'
22392237
log_time('compile inputs')
@@ -2242,6 +2240,8 @@ def compile_source_file(i, input_file):
22422240
logger.debug('stopping after compile phase')
22432241
for flag in link_flags:
22442242
diagnostics.warning('unused-command-line-argument', "argument unused during compilation: '%s'" % flag[1])
2243+
for f in linker_inputs:
2244+
diagnostics.warning('unused-command-line-argument', "%s: linker input file unused because linking not done" % f[1])
22452245
return 0
22462246

22472247
if specified_target and specified_target.startswith('-'):
@@ -2255,17 +2255,17 @@ def compile_source_file(i, input_file):
22552255
link_flags = filter_link_flags(link_flags, using_lld)
22562256

22572257
# Decide what we will link
2258-
consumed = process_libraries(libs, lib_dirs, temp_files)
2258+
consumed = process_libraries(libs, lib_dirs, linker_inputs)
22592259
# Filter out libraries that are actually JS libs
22602260
link_flags = [l for l in link_flags if l[0] not in consumed]
2261-
temp_files = filter_out_dynamic_libs(temp_files)
2261+
linker_inputs = filter_out_dynamic_libs(linker_inputs)
22622262

2263-
linker_inputs = [val for _, val in sorted(temp_files + link_flags)]
2263+
linker_arguments = [val for _, val in sorted(linker_inputs + link_flags)]
22642264

22652265
if link_to_object:
22662266
with ToolchainProfiler.profile_block('linking to object file'):
2267-
logger.debug('link_to_object: ' + str(linker_inputs) + ' -> ' + target)
2268-
building.link_to_object(linker_inputs, target)
2267+
logger.debug('link_to_object: ' + str(linker_arguments) + ' -> ' + target)
2268+
building.link_to_object(linker_arguments, target)
22692269
logger.debug('stopping after linking to object file')
22702270
return 0
22712271

@@ -2286,8 +2286,8 @@ def compile_source_file(i, input_file):
22862286
# unless running in strict mode.
22872287
if not settings.STRICT and '-nostdlib++' not in newargs:
22882288
link_as_cxx = True
2289-
extra_files_to_link += system_libs.calculate([f for _, f in sorted(temp_files)] + extra_files_to_link, link_as_cxx, forced=forced_stdlibs)
2290-
linker_inputs += extra_files_to_link
2289+
extra_files_to_link += system_libs.calculate([f for _, f in sorted(linker_inputs)] + extra_files_to_link, link_as_cxx, forced=forced_stdlibs)
2290+
linker_arguments += extra_files_to_link
22912291

22922292
# exit block 'calculate system libraries'
22932293
log_time('calculate system libraries')
@@ -2305,7 +2305,7 @@ def dedup_list(lst):
23052305
settings.EXPORTED_FUNCTIONS = dedup_list(settings.EXPORTED_FUNCTIONS)
23062306

23072307
with ToolchainProfiler.profile_block('link'):
2308-
logger.debug('linking: ' + str(linker_inputs))
2308+
logger.debug('linking: ' + str(linker_arguments))
23092309

23102310
# if EMCC_DEBUG=2 then we must link now, so the temp files are complete.
23112311
# if using the wasm backend, we might be using vanilla LLVM, which does not allow our
@@ -2315,10 +2315,10 @@ def dedup_list(lst):
23152315
if settings.LLD_REPORT_UNDEFINED and settings.ERROR_ON_UNDEFINED_SYMBOLS:
23162316
js_funcs = get_all_js_syms()
23172317
log_time('JS symbol generation')
2318-
building.link_lld(linker_inputs, wasm_target, external_symbol_list=js_funcs)
2318+
building.link_lld(linker_arguments, wasm_target, external_symbol_list=js_funcs)
23192319
# Special handling for when the user passed '-Wl,--version'. In this case the linker
23202320
# does not create the output file, but just prints its version and exits with 0.
2321-
if '--version' in linker_inputs:
2321+
if '--version' in linker_arguments:
23222322
return 0
23232323

23242324
# exit block 'link'
@@ -3331,7 +3331,7 @@ def worker_js_script(proxy_worker_filename):
33313331
return web_gl_client_src + '\n' + proxy_client_src
33323332

33333333

3334-
def process_libraries(libs, lib_dirs, temp_files):
3334+
def process_libraries(libs, lib_dirs, linker_inputs):
33353335
libraries = []
33363336
consumed = []
33373337
suffixes = STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS
@@ -3347,7 +3347,7 @@ def process_libraries(libs, lib_dirs, temp_files):
33473347
path = os.path.join(lib_dir, name)
33483348
if os.path.exists(path):
33493349
logger.debug('found library "%s" at %s', lib, path)
3350-
temp_files.append((i, path))
3350+
linker_inputs.append((i, path))
33513351
consumed.append(i)
33523352
found = True
33533353
break

tests/test_other.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9376,6 +9376,13 @@ def test_linker_flags_unused(self):
93769376
err = self.run_process([EMCC, test_file('hello_world.cpp'), '-c', '-lbar'], stderr=PIPE).stderr
93779377
self.assertContained("warning: argument unused during compilation: '-lbar' [-Wunused-command-line-argument]", err)
93789378

9379+
def test_linker_input_unused(self):
9380+
self.run_process([EMCC, '-c', test_file('hello_world.cpp')])
9381+
err = self.run_process([EMCC, 'hello_world.o', '-c', '-o', 'out.o'], stderr=PIPE).stderr
9382+
self.assertContained("warning: hello_world.o: linker input file unused because linking not done [-Wunused-command-line-argument", err)
9383+
# In this case the compiler does not produce any output file.
9384+
self.assertNotExists('out.o')
9385+
93799386
def test_non_wasm_without_wasm_in_vm(self):
93809387
# Test that our non-wasm output does not depend on wasm support in the vm.
93819388
self.run_process([EMCC, test_file('hello_world.cpp'), '-s', 'WASM=0'])

0 commit comments

Comments
 (0)