Skip to content

Commit 0e946b3

Browse files
authored
Don't EXPORT_ALL for linkable code (#7371)
This is a breaking change, in which we no longer set EXPORT_ALL in MAIN_MODULEs and SIDE_MODULEs. This makes our linking behavior more "standard", and is more future-proof for wasm backend linking. Fixes #5586, fixes #7189. See more context there.
1 parent b5170dd commit 0e946b3

File tree

5 files changed

+44
-30
lines changed

5 files changed

+44
-30
lines changed

ChangeLog.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ full changeset diff at the end of each section.
1515

1616
Current Trunk
1717
-------------
18+
- Breaking change: Do not automatically set EXPORT_ALL for MAIN_MODULES or
19+
SIDE_MODULES. This means that you must explicitly export things that will
20+
be called from outside (normally, on EXPORTED_FUNCTIONS), or
21+
you can manually enable EXPORT_ALL yourself (which returns to the exact
22+
same behavior as before). This change brings us in line with more standard
23+
dynamic linking, and will match what the LLVM wasm backend will have.
24+
See #7312.
1825

1926
v1.38.14: 10/22/2018
2027
--------------------

emcc.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,6 @@ def check(input_file):
11641164
if shared.Settings.EMULATED_FUNCTION_POINTERS == 0:
11651165
shared.Settings.EMULATED_FUNCTION_POINTERS = 2 # by default, use optimized function pointer emulation
11661166
shared.Settings.ERROR_ON_UNDEFINED_SYMBOLS = shared.Settings.WARN_ON_UNDEFINED_SYMBOLS = 0
1167-
shared.Settings.EXPORT_ALL = 1
11681167

11691168
if shared.Settings.EMTERPRETIFY:
11701169
shared.Settings.FINALIZE_ASM_JS = 0

tests/test_browser.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,8 +2126,8 @@ def test_runtimelink(self):
21262126
print(wasm)
21272127
main, supp = self.setup_runtimelink_test()
21282128
open('supp.cpp', 'w').write(supp)
2129-
run_process([PYTHON, EMCC, 'supp.cpp', '-o', 'supp.' + ('wasm' if wasm else 'js'), '-s', 'SIDE_MODULE=1', '-O2', '-s', 'WASM=%d' % wasm])
2130-
self.btest(main, args=['-DBROWSER=1', '-s', 'MAIN_MODULE=1', '-O2', '-s', 'WASM=%d' % wasm, '-s', 'RUNTIME_LINKED_LIBS=["supp.' + ('wasm' if wasm else 'js') + '"]'], expected='76')
2129+
run_process([PYTHON, EMCC, 'supp.cpp', '-o', 'supp.' + ('wasm' if wasm else 'js'), '-s', 'SIDE_MODULE=1', '-O2', '-s', 'WASM=%d' % wasm, '-s', 'EXPORT_ALL=1'])
2130+
self.btest(main, args=['-DBROWSER=1', '-s', 'MAIN_MODULE=1', '-O2', '-s', 'WASM=%d' % wasm, '-s', 'RUNTIME_LINKED_LIBS=["supp.' + ('wasm' if wasm else 'js') + '"]', '-s', 'EXPORT_ALL=1'], expected='76')
21312131

21322132
def test_pre_run_deps(self):
21332133
# Adding a dependency in preRun will delay run
@@ -2319,7 +2319,7 @@ def test_emscripten_async_wget2(self):
23192319
@unittest.skip('non-fastcomp is deprecated and fails in 3.5')
23202320
def test_module(self):
23212321
run_process([PYTHON, EMCC, path_from_root('tests', 'browser_module.cpp'), '-o', 'module.js', '-O2', '-s', 'SIDE_MODULE=1', '-s', 'DLOPEN_SUPPORT=1', '-s', 'EXPORTED_FUNCTIONS=["_one", "_two"]'])
2322-
self.btest('browser_main.cpp', args=['-O2', '-s', 'MAIN_MODULE=1', '-s', 'DLOPEN_SUPPORT=1'], expected='8')
2322+
self.btest('browser_main.cpp', args=['-O2', '-s', 'MAIN_MODULE=1', '-s', 'DLOPEN_SUPPORT=1', '-s', 'EXPORT_ALL=1'], expected='8')
23232323

23242324
def test_preload_module(self):
23252325
open('library.c', 'w').write(r'''
@@ -2328,7 +2328,7 @@ def test_preload_module(self):
23282328
return 42;
23292329
}
23302330
''')
2331-
run_process([PYTHON, EMCC, 'library.c', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'library.wasm', '-s', 'WASM=1'])
2331+
run_process([PYTHON, EMCC, 'library.c', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'library.wasm', '-s', 'WASM=1', '-s', 'EXPORT_ALL=1'])
23322332
os.rename('library.wasm', 'library.so')
23332333
main = r'''
23342334
#include <dlfcn.h>
@@ -2359,7 +2359,7 @@ def test_preload_module(self):
23592359
'''
23602360
self.btest(
23612361
main,
2362-
args=['-s', 'MAIN_MODULE=1', '--preload-file', '.@/', '-O2', '-s', 'WASM=1', '--use-preload-plugins'],
2362+
args=['-s', 'MAIN_MODULE=1', '--preload-file', '.@/', '-O2', '-s', 'WASM=1', '--use-preload-plugins', '-s', 'EXPORT_ALL=1'],
23632363
expected='0')
23642364

23652365
def test_mmap_file(self):
@@ -3277,24 +3277,24 @@ def test_dynamic_link(self):
32773277
return ret;
32783278
}
32793279
''')
3280-
run_process([PYTHON, EMCC, 'side.cpp', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'side.wasm'])
3281-
self.btest(self.in_dir('main.cpp'), '2', args=['-s', 'MAIN_MODULE=1', '-O2', '--pre-js', 'pre.js'])
3280+
run_process([PYTHON, EMCC, 'side.cpp', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'side.wasm', '-s', 'EXPORT_ALL=1'])
3281+
self.btest(self.in_dir('main.cpp'), '2', args=['-s', 'MAIN_MODULE=1', '-O2', '--pre-js', 'pre.js', '-s', 'EXPORT_ALL=1'])
32823282

32833283
print('wasm in worker (we can read binary data synchronously there)')
32843284

32853285
open('pre.js', 'w').write('''
32863286
var Module = { dynamicLibraries: ['side.wasm'] };
32873287
''')
3288-
run_process([PYTHON, EMCC, 'side.cpp', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'side.wasm', '-s', 'WASM=1'])
3289-
self.btest(self.in_dir('main.cpp'), '2', args=['-s', 'MAIN_MODULE=1', '-O2', '--pre-js', 'pre.js', '-s', 'WASM=1', '--proxy-to-worker'])
3288+
run_process([PYTHON, EMCC, 'side.cpp', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'side.wasm', '-s', 'WASM=1', '-s', 'EXPORT_ALL=1'])
3289+
self.btest(self.in_dir('main.cpp'), '2', args=['-s', 'MAIN_MODULE=1', '-O2', '--pre-js', 'pre.js', '-s', 'WASM=1', '--proxy-to-worker', '-s', 'EXPORT_ALL=1'])
32903290

32913291
print('wasm (will auto-preload since no sync binary reading)')
32923292

32933293
open('pre.js', 'w').write('''
32943294
Module.dynamicLibraries = ['side.wasm'];
32953295
''')
32963296
# same wasm side module works
3297-
self.btest(self.in_dir('main.cpp'), '2', args=['-s', 'MAIN_MODULE=1', '-O2', '--pre-js', 'pre.js', '-s', 'WASM=1'])
3297+
self.btest(self.in_dir('main.cpp'), '2', args=['-s', 'MAIN_MODULE=1', '-O2', '--pre-js', 'pre.js', '-s', 'WASM=1', '-s', 'EXPORT_ALL=1'])
32983298

32993299
@requires_graphics_hardware
33003300
@requires_sync_compilation
@@ -3324,9 +3324,9 @@ def test_dynamic_link_glemu(self):
33243324
return (const char *)glGetString(GL_EXTENSIONS);
33253325
}
33263326
''')
3327-
run_process([PYTHON, EMCC, 'side.cpp', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'side.wasm', '-lSDL'])
3327+
run_process([PYTHON, EMCC, 'side.cpp', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'side.wasm', '-lSDL', '-s', 'EXPORT_ALL=1'])
33283328

3329-
self.btest(self.in_dir('main.cpp'), '1', args=['-s', 'MAIN_MODULE=1', '-O2', '-s', 'LEGACY_GL_EMULATION=1', '-lSDL', '-lGL', '--pre-js', 'pre.js'])
3329+
self.btest(self.in_dir('main.cpp'), '1', args=['-s', 'MAIN_MODULE=1', '-O2', '-s', 'LEGACY_GL_EMULATION=1', '-lSDL', '-lGL', '--pre-js', 'pre.js', '-s', 'EXPORT_ALL=1'])
33303330

33313331
def test_memory_growth_during_startup(self):
33323332
open('data.dat', 'w').write('X' * (30 * 1024 * 1024))

tests/test_core.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,10 +2426,12 @@ def test_runtimelink(self):
24262426
def prep_dlfcn_lib(self):
24272427
self.set_setting('MAIN_MODULE', 0)
24282428
self.set_setting('SIDE_MODULE', 1)
2429+
self.set_setting('EXPORT_ALL', 1)
24292430

24302431
def prep_dlfcn_main(self):
24312432
self.set_setting('MAIN_MODULE', 1)
24322433
self.set_setting('SIDE_MODULE', 0)
2434+
self.set_setting('EXPORT_ALL', 1)
24332435

24342436
with open('lib_so_pre.js', 'w') as f:
24352437
f.write('''
@@ -3325,6 +3327,9 @@ def zzztest_dlfcn_exceptions(self): # TODO: make this work. need to forward temp
33253327
''')
33263328

33273329
def dylink_test(self, main, side, expected, header=None, main_emcc_args=[], force_c=False, need_reverse=True, auto_load=True):
3330+
# shared settings
3331+
self.set_setting('EXPORT_ALL', 1)
3332+
33283333
if header:
33293334
open('header.h', 'w').write(header)
33303335

@@ -3800,7 +3805,7 @@ def test_dylink_global_var_jslib(self):
38003805
void call_side() {
38013806
printf("side: jslib_x is %d.\n", jslib_x);
38023807
}
3803-
''', expected=['main: jslib_x is 148.\nside: jslib_x is 148.\n'], main_emcc_args=['--js-library', 'lib.js'])
3808+
''', expected=['main: jslib_x is 148.\nside: jslib_x is 148.\n'], main_emcc_args=['--js-library', 'lib.js', '-s', 'EXPORTED_FUNCTIONS=["_main", "_jslib_x"]'])
38043809

38053810
@needs_dlfcn
38063811
def test_dylink_many_postSets(self):
@@ -4034,7 +4039,7 @@ def test_dylink_hyper_dupe(self):
40344039
printf("only_in_third_1: %d, %d, %d, %d\n", sidef(), sideg, second_to_third, x);
40354040
}
40364041
''')
4037-
run_process([PYTHON, EMCC, 'third.cpp', '-s', 'SIDE_MODULE=1'] + Building.COMPILER_TEST_OPTS + self.emcc_args + ['-o', 'third' + dylib_suffix])
4042+
run_process([PYTHON, EMCC, 'third.cpp', '-s', 'SIDE_MODULE=1', '-s', 'EXPORT_ALL=1'] + Building.COMPILER_TEST_OPTS + self.emcc_args + ['-o', 'third' + dylib_suffix])
40384043

40394044
self.dylink_test(main=r'''
40404045
#include <stdio.h>

tests/test_other.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3004,7 +3004,8 @@ def test_proxyfs(self):
30043004
'--embed-file', 'proxyfs_embed.txt', '--pre-js', 'proxyfs_pre.js',
30053005
'-s', 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]',
30063006
'-s', 'BINARYEN_ASYNC_COMPILATION=0',
3007-
'-s', 'MAIN_MODULE=1'])
3007+
'-s', 'MAIN_MODULE=1',
3008+
'-s', 'EXPORT_ALL=1'])
30083009
# Following shutil.copyfile just prevent 'require' of node.js from caching js-object.
30093010
# See https://nodejs.org/api/modules.html
30103011
shutil.copyfile('proxyfs_test.js', 'proxyfs_test1.js')
@@ -6230,7 +6231,7 @@ def test(main_args=[], library_args=[], expected='hello from main\nhello from li
62306231
#endif
62316232
}
62326233
''')
6233-
run_process([PYTHON, EMCC, 'library.c', '-s', 'SIDE_MODULE=1', '-O2', '-o', library_file, '-s', 'WASM=' + str(wasm)] + library_args)
6234+
run_process([PYTHON, EMCC, 'library.c', '-s', 'SIDE_MODULE=1', '-O2', '-o', library_file, '-s', 'WASM=' + str(wasm), '-s', 'EXPORT_ALL=1'] + library_args)
62346235
open('main.c', 'w').write(r'''
62356236
#include <dlfcn.h>
62366237
#include <stdio.h>
@@ -6266,12 +6267,14 @@ def percent_diff(x, y):
62666267
full = test()
62676268
# printf is not used in main, but libc was linked in, so it's there
62686269
printf = test(library_args=['-DUSE_PRINTF'])
6269-
# dce in main, and side happens to be ok since it uses puts as well
6270-
dce = test(main_args=['-s', 'MAIN_MODULE=2'])
6270+
# dce in main, and it fails since puts is not exported
6271+
dce = test(main_args=['-s', 'MAIN_MODULE=2'], expected=('cannot', 'undefined'))
6272+
# with exporting, it works
6273+
dce = test(main_args=['-s', 'MAIN_MODULE=2', '-s', 'EXPORTED_FUNCTIONS=["_main", "_puts"]'])
62716274
# printf is not used in main, and we dce, so we failz
62726275
dce_fail = test(main_args=['-s', 'MAIN_MODULE=2'], library_args=['-DUSE_PRINTF'], expected=('cannot', 'undefined'))
62736276
# exporting printf in main keeps it alive for the library
6274-
dce_save = test(main_args=['-s', 'MAIN_MODULE=2', '-s', 'EXPORTED_FUNCTIONS=["_main", "_printf"]'], library_args=['-DUSE_PRINTF'])
6277+
dce_save = test(main_args=['-s', 'MAIN_MODULE=2', '-s', 'EXPORTED_FUNCTIONS=["_main", "_printf", "_puts"]'], library_args=['-DUSE_PRINTF'])
62756278

62766279
assert percent_diff(full[0], printf[0]) < 4
62776280
assert percent_diff(dce[0], dce_fail[0]) < 4
@@ -6377,10 +6380,10 @@ def test_ld_library_path(self):
63776380
63786381
''')
63796382

6380-
run_process([PYTHON, EMCC, '-o', 'libhello1.wasm', 'hello1.c', '-s', 'SIDE_MODULE=1'])
6381-
run_process([PYTHON, EMCC, '-o', 'libhello2.wasm', 'hello2.c', '-s', 'SIDE_MODULE=1'])
6382-
run_process([PYTHON, EMCC, '-o', 'libhello3.wasm', 'hello3.c', '-s', 'SIDE_MODULE=1'])
6383-
run_process([PYTHON, EMCC, '-o', 'libhello4.wasm', 'hello4.c', '-s', 'SIDE_MODULE=1'])
6383+
run_process([PYTHON, EMCC, '-o', 'libhello1.wasm', 'hello1.c', '-s', 'SIDE_MODULE=1', '-s', 'EXPORT_ALL=1'])
6384+
run_process([PYTHON, EMCC, '-o', 'libhello2.wasm', 'hello2.c', '-s', 'SIDE_MODULE=1', '-s', 'EXPORT_ALL=1'])
6385+
run_process([PYTHON, EMCC, '-o', 'libhello3.wasm', 'hello3.c', '-s', 'SIDE_MODULE=1', '-s', 'EXPORT_ALL=1'])
6386+
run_process([PYTHON, EMCC, '-o', 'libhello4.wasm', 'hello4.c', '-s', 'SIDE_MODULE=1', '-s', 'EXPORT_ALL=1'])
63846387
run_process([PYTHON, EMCC, '-o', 'main.js', 'main.c', '-s', 'MAIN_MODULE=1', '-s', 'TOTAL_MEMORY=' + str(32 * 1024 * 1024),
63856388
'--embed-file', 'libhello1.wasm@/lib/libhello1.wasm',
63866389
'--embed-file', 'libhello2.wasm@/usr/lib/libhello2.wasm',
@@ -6453,8 +6456,8 @@ def test_dlopen_rtld_global(self):
64536456
}
64546457
''')
64556458

6456-
run_process([PYTHON, EMCC, '-o', 'libhello1.js', 'hello1.c', '-s', 'SIDE_MODULE=1', '-s', 'WASM=0'])
6457-
run_process([PYTHON, EMCC, '-o', 'libhello2.js', 'hello2.c', '-s', 'SIDE_MODULE=1', '-s', 'WASM=0'])
6459+
run_process([PYTHON, EMCC, '-o', 'libhello1.js', 'hello1.c', '-s', 'SIDE_MODULE=1', '-s', 'WASM=0', '-s', 'EXPORT_ALL=1'])
6460+
run_process([PYTHON, EMCC, '-o', 'libhello2.js', 'hello2.c', '-s', 'SIDE_MODULE=1', '-s', 'WASM=0', '-s', 'EXPORT_ALL=1'])
64586461
run_process([PYTHON, EMCC, '-o', 'main.js', 'main.c', '-s', 'MAIN_MODULE=1', '-s', 'WASM=0',
64596462
'--embed-file', 'libhello1.js',
64606463
'--embed-file', 'libhello2.js'])
@@ -8245,7 +8248,7 @@ def test(filename, expectations):
82458248
0, [], ['tempDoublePtr', 'waka'], 8, 0, 0, 0), # noqa; totally empty!
82468249
# but we don't metadce with linkable code! other modules may want it
82478250
(['-O3', '-s', 'MAIN_MODULE=1'],
8248-
1489, ['invoke_v'], ['waka'], 469663, 149, 1443, None), # noqa; don't compare the # of functions in a main module, which changes a lot
8251+
1489, ['invoke_v'], ['waka'], 226057, 30, 75, None), # noqa; don't compare the # of functions in a main module, which changes a lot
82498252
]) # noqa
82508253

82518254
print('test on a minimal pure computational thing')
@@ -8286,9 +8289,9 @@ def test_legalize_js_ffi(self):
82868289
# test disabling of JS FFI legalization
82878290
wasm_dis = os.path.join(Building.get_binaryen_bin(), 'wasm-dis')
82888291
for (args, js_ffi) in [
8289-
(['-s', 'LEGALIZE_JS_FFI=1', '-s', 'SIDE_MODULE=1', '-O2'], True),
8290-
(['-s', 'LEGALIZE_JS_FFI=0', '-s', 'SIDE_MODULE=1', '-O2'], False),
8291-
(['-s', 'LEGALIZE_JS_FFI=0', '-s', 'SIDE_MODULE=1', '-O0'], False),
8292+
(['-s', 'LEGALIZE_JS_FFI=1', '-s', 'SIDE_MODULE=1', '-O2', '-s', 'EXPORT_ALL=1'], True),
8293+
(['-s', 'LEGALIZE_JS_FFI=0', '-s', 'SIDE_MODULE=1', '-O2', '-s', 'EXPORT_ALL=1'], False),
8294+
(['-s', 'LEGALIZE_JS_FFI=0', '-s', 'SIDE_MODULE=1', '-O0', '-s', 'EXPORT_ALL=1'], False),
82928295
(['-s', 'LEGALIZE_JS_FFI=0', '-s', 'WARN_ON_UNDEFINED_SYMBOLS=0', '-O0'], False),
82938296
]:
82948297
if self.is_wasm_backend() and 'SIDE_MODULE=1' in args:

0 commit comments

Comments
 (0)