Skip to content

Commit a3b9e32

Browse files
authored
Allow -u flag to pass through to the linker (#23679)
`-u` is one of the few linker flags that is also a compiler flag, and the compiler is supposed to pass it through. This is similar to `-z`, for example. Fixes: #23677
1 parent 2e2ec08 commit a3b9e32

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

emcc.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
'-iprefix', '-iwithprefix', '-iwithprefixbefore',
9494
'-isysroot', '-imultilib', '-A', '-isystem', '-iquote',
9595
'-install_name', '-compatibility_version', '-mllvm',
96-
'-current_version', '-I', '-L', '-include-pch',
96+
'-current_version', '-I', '-L', '-include-pch', '-u',
9797
'-undefined', '-target', '-Xlinker', '-Xclang', '-z'
9898
}
9999

@@ -703,7 +703,7 @@ def phase_parse_arguments(state):
703703
settings.WARN_DEPRECATED = 0
704704

705705
for i in range(len(newargs)):
706-
if newargs[i] in ('-l', '-L', '-I', '-z', '--js-library', '-o', '-x'):
706+
if newargs[i] in ('-l', '-L', '-I', '-z', '--js-library', '-o', '-x', '-u'):
707707
# Scan for flags that can be written as either one or two arguments
708708
# and normalize them to the single argument form.
709709
if newargs[i] == '--js-library':
@@ -788,7 +788,7 @@ def get_next_arg():
788788
add_link_arg(flag)
789789
elif arg == '-Xlinker':
790790
add_link_arg(get_next_arg())
791-
elif arg == '-s' or arg.startswith(('-l', '-L', '--js-library=', '-z')):
791+
elif arg == '-s' or arg.startswith(('-l', '-L', '--js-library=', '-z', '-u')):
792792
add_link_arg(arg)
793793
elif not arg.startswith('-o') and arg not in ('-nostdlib', '-nostartfiles', '-nolibc', '-nodefaultlibs', '-s'):
794794
# All other flags are for the compiler

test/test_other.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12375,6 +12375,29 @@ def test_linker_flags_pass_through(self):
1237512375
err = self.run_process([EMCC, test_file('hello_world.c'), '-zfoo'], stderr=PIPE).stderr
1237612376
self.assertContained('wasm-ld: warning: unknown -z value: foo', err)
1237712377

12378+
def test_linker_flags_pass_through_u(self):
12379+
# Create a static library that contains a reference to an undefined symbol: bar
12380+
create_file('test.c', '''
12381+
extern int bar();
12382+
int foo() {
12383+
return bar();
12384+
}
12385+
''')
12386+
self.run_process([EMCC, '-c', 'test.c'])
12387+
self.run_process([EMAR, 'crs', 'libtest.a', 'test.o'])
12388+
# This test uses --no-gc-sections otherwise the foo symbol never actually gets included
12389+
# in the link.
12390+
cmd = [EMCC, test_file('hello_world.c'), '-Wl,--no-gc-sections']
12391+
12392+
# Verify that the library is normally ignored and that the link succeeds
12393+
self.run_process(cmd + ['libtest.a'])
12394+
# Adding `-u baz` makes no diffeence
12395+
self.run_process(cmd + ['-ubaz', 'libtest.a'])
12396+
12397+
# But adding `-ufoo` should fail because it loads foo, which depends on bar
12398+
err = self.expect_fail(cmd + ['-ufoo', 'libtest.a'])
12399+
self.assertContained('wasm-ld: error: libtest.a(test.o): undefined symbol: bar', err)
12400+
1237812401
def test_linker_flags_unused(self):
1237912402
err = self.run_process([EMCC, test_file('hello_world.c'), '-c', '-lbar'], stderr=PIPE).stderr
1238012403
self.assertContained("warning: -lbar: 'linker' input unused [-Wunused-command-line-argument]", err)

0 commit comments

Comments
 (0)