diff --git a/embuilder.py b/embuilder.py index ad3ba1683fe16..4ddd19862ad2d 100755 --- a/embuilder.py +++ b/embuilder.py @@ -127,6 +127,9 @@ 'libwasmfs-debug', 'libwasmfs_no_fs', 'giflib', + 'sdl2', + 'sdl2_gfx', + 'sdl3', ] PORTS = sorted(list(ports.ports_by_name.keys()) + list(ports.port_variants.keys())) diff --git a/test/test_core.py b/test/test_core.py index 0356186905712..e521446d71d9f 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -1854,15 +1854,14 @@ def test_set_align(self): self.do_core_test('test_set_align.c') @no_modularize_instance('uses Module object directly') - @no_js_math('JS_MATH is not compatible with LINKABLE') @parameterized({ '': (['-sEXPORTED_FUNCTIONS=_main,_save_me_aimee'],), # test EXPORT_ALL too - 'export_all': (['-Wno-deprecated', '-sEXPORT_ALL', '-sLINKABLE'],), + 'export_all': (['-sEXPORT_ALL', '-sMAIN_MODULE'],), }) def test_emscripten_api(self, args): - if '-sLINKABLE' in args and '-lllvmlibc' in self.cflags: - self.skipTest('LLVM-libc overlay mode is not compatible with whole-archive (LINKABLE)') + if '-sMAIN_MODULE' in args: + self.check_dylink() self.do_core_test('test_emscripten_api.c', cflags=args) def test_emscripten_run_script_string_int(self): @@ -6646,8 +6645,7 @@ def test_cubescript(self): @needs_dylink def test_relocatable_void_function(self): - self.set_setting('RELOCATABLE') - self.do_core_test('test_relocatable_void_function.c', cflags=['-Wno-deprecated']) + self.do_core_test('test_relocatable_void_function.c', cflags=['-sMAIN_MODULE=2']) @wasm_simd @parameterized({ diff --git a/test/test_other.py b/test/test_other.py index 22b2861d27835..fb44c910f9393 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -1580,12 +1580,11 @@ def test_dot_a_all_contents_invalid(self): self.assertContained(['unknown file type', "libfoo.a: archive member 'native.o' is neither Wasm object file nor LLVM bitcode"], stderr) def test_export_all(self): - lib = r''' + create_file('main.c', r''' #include void libf1() { printf("libf1\n"); } void libf2() { printf("libf2\n"); } - ''' - create_file('lib.c', lib) + ''') create_file('pre.js', ''' Module.onRuntimeInitialized = () => { @@ -1596,8 +1595,10 @@ def test_export_all(self): # Explicitly test with -Oz to ensure libc_optz is included alongside # libc when `--whole-archive` is used. - self.emcc('lib.c', ['-Oz', '-sEXPORT_ALL', '-sLINKABLE', '-Wno-deprecated', '--pre-js', 'pre.js'], output_filename='a.out.js') - self.assertContained('libf1\nlibf2\n', self.run_js('a.out.js')) + self.do_runf('main.c', 'libf1\nlibf2\n', cflags=['-Oz', '-sEXPORT_ALL', '-sMAIN_MODULE', '--pre-js', 'pre.js']) + + # Without the `-sEXPORT_ALL` these symbols will not be visible from JS + self.do_runf('main.c', '_libf1 is not defined', assert_returncode=NON_ZERO, cflags=['-Oz', '-sMAIN_MODULE', '--pre-js', 'pre.js']) def test_export_keepalive(self): create_file('main.c', r''' @@ -2532,23 +2533,23 @@ def test_sdl2_mixer_wav(self): self.emcc('browser/test_sdl2_mixer_wav.c', ['--use-port=sdl2_mixer:formats=ogg'], output_filename='a.out.js') def test_sdl2_linkable(self): - # Ensure that SDL2 can be built with LINKABLE. This implies there are no undefined - # symbols in the library (because LINKABLE includes the entire library). - self.emcc('browser/test_sdl2_misc.c', ['-sLINKABLE', '-Wno-deprecated', '-sUSE_SDL=2'], output_filename='a.out.js') - self.emcc('browser/test_sdl2_misc.c', ['-sLINKABLE', '-Wno-deprecated', '--use-port=sdl2'], output_filename='a.out.js') + # Ensure that SDL2 can be built with MAIN_MODULE. This implies there are no undefined + # symbols in the library (because MAIN_MODULE=1 includes the entire library). + self.emcc('browser/test_sdl2_misc.c', ['-sMAIN_MODULE', '-sUSE_SDL=2'], output_filename='a.out.js') + self.emcc('browser/test_sdl2_misc.c', ['-sMAIN_MODULE', '--use-port=sdl2'], output_filename='a.out.js') def test_sdl3_linkable(self): - # Ensure that SDL3 can be built with LINKABLE. This implies there are no undefined - # symbols in the library (because LINKABLE includes the entire library). + # Ensure that SDL3 can be built with MAIN_MODULE. This implies there are no undefined + # symbols in the library (because MAIN_MODULE=1 includes the entire library). self.cflags.append('-Wno-experimental') - self.emcc('browser/test_sdl3_misc.c', ['-sLINKABLE', '-Wno-deprecated', '-sUSE_SDL=3'], output_filename='a.out.js') - self.emcc('browser/test_sdl3_misc.c', ['-sLINKABLE', '-Wno-deprecated', '--use-port=sdl3'], output_filename='a.out.js') + self.emcc('browser/test_sdl3_misc.c', ['-sMAIN_MODULE', '-sUSE_SDL=3'], output_filename='a.out.js') + self.emcc('browser/test_sdl3_misc.c', ['-sMAIN_MODULE', '--use-port=sdl3'], output_filename='a.out.js') @requires_network def test_sdl2_gfx_linkable(self): # Same as above but for sdl2_gfx library - self.emcc('browser/test_sdl2_misc.c', ['-Wl,-fatal-warnings', '-sLINKABLE', '-Wno-deprecated', '-sUSE_SDL_GFX=2'], output_filename='a.out.js') - self.emcc('browser/test_sdl2_misc.c', ['-Wl,-fatal-warnings', '-sLINKABLE', '-Wno-deprecated', '--use-port=sdl2_gfx'], output_filename='a.out.js') + self.emcc('browser/test_sdl2_misc.c', ['-Wl,-fatal-warnings', '-sMAIN_MODULE', '-sUSE_SDL_GFX=2'], output_filename='a.out.js') + self.emcc('browser/test_sdl2_misc.c', ['-Wl,-fatal-warnings', '-sMAIN_MODULE', '--use-port=sdl2_gfx'], output_filename='a.out.js') @requires_network def test_libpng(self): @@ -5118,9 +5119,9 @@ def test_bad_function_pointer_cast(self, opts, wasm, safe): ''') for emulate_casts in (0, 1): - for relocatable in (0, 1): - # wasm2js is not compatible with relocatable mode - if not wasm and relocatable: + for dylink in (0, 1): + # wasm2js is not compatible with dynamic linking + if dylink and not wasm: continue cmd = [EMXX, 'src.cpp'] + opts if not wasm: @@ -5129,8 +5130,8 @@ def test_bad_function_pointer_cast(self, opts, wasm, safe): cmd += ['-sSAFE_HEAP'] if emulate_casts: cmd += ['-sEMULATE_FUNCTION_POINTER_CASTS'] - if relocatable: - cmd += ['-sRELOCATABLE'] # disables asm-optimized safe heap + if dylink: + cmd += ['-sMAIN_MODULE=2'] # disables asm-optimized safe heap print(cmd) self.run_process(cmd) returncode = 0 if emulate_casts or not wasm else NON_ZERO @@ -12134,10 +12135,10 @@ def test_pthread_export_es6(self, args): self.assertContained('hello, world!', output) def test_wasm2js_no_dylink(self): - for arg in ('-sMAIN_MODULE', '-sSIDE_MODULE', '-sRELOCATABLE'): + for arg in ('-sMAIN_MODULE', '-sSIDE_MODULE'): print(arg) err = self.expect_fail([EMCC, test_file('hello_world.c'), '-sWASM=0', arg]) - self.assertContained('emcc: error: WASM2JS is not compatible with RELOCATABLE', err) + self.assertContained(r'emcc: error: WASM2JS is not compatible with .*_MODULE \(wasm2js does not support dynamic linking\)', err, regex=True) def test_wasm2js_standalone(self): self.do_run_in_out_file_test('hello_world.c', cflags=['-sSTANDALONE_WASM', '-sWASM=0']) @@ -12373,12 +12374,12 @@ def test_gen_struct_info_env(self): with env_modify({'EMCC_CFLAGS': '-O2 BAD_ARG', 'EMCC_FORCE_STDLIBS': '1', 'EMCC_ONLY_FORCED_STDLIBS': '1'}): self.run_process([PYTHON, path_from_root('tools/gen_struct_info.py'), '-o', 'out.json']) - def test_relocatable_limited_exports(self): - # Building with RELOCATABLE should *not* automatically export all sybmols. - self.run_process([EMCC, test_file('hello_world.c'), '-sRELOCATABLE', '-o', 'out.wasm']) + def test_dylink_limited_exports(self): + # Building with MAIN_MODULE=2 should *not* automatically export all sybmols. + self.run_process([EMCC, test_file('hello_world.c'), '-sMAIN_MODULE=2', '-o', 'out.wasm']) - # Building with RELOCATABLE + LINKABLE should include and export all of the standard library - self.run_process([EMCC, test_file('hello_world.c'), '-sRELOCATABLE', '-sLINKABLE', '-o', 'out_linkable.wasm']) + # Building with MAIN_MODULE=1 should include and export all of the standard library + self.run_process([EMCC, test_file('hello_world.c'), '-sMAIN_MODULE', '-o', 'out_linkable.wasm']) exports = self.parse_wasm('out.wasm')[1] exports_linkable = self.parse_wasm('out_linkable.wasm')[1] @@ -12569,18 +12570,13 @@ def test_reverse_deps_allow_undefined(self): ''') self.do_runf('test.c', cflags=['-sERROR_ON_UNDEFINED_SYMBOLS=0']) - @parameterized({ - 'relocatable': ('-sRELOCATABLE',), - 'linkable': ('-sLINKABLE',), - 'main_module': ('-sMAIN_MODULE',), - }) - def test_check_undefined(self, flag): + def test_dylink_undefined(self): # positive case: no undefined symbols - self.run_process([EMCC, flag, '-sERROR_ON_UNDEFINED_SYMBOLS', test_file('hello_world.c')]) + self.run_process([EMCC, '-sMAIN_MODULE', test_file('hello_world.c')]) self.run_js('a.out.js') # negative case: foo is undefined in test_check_undefined.c - err = self.expect_fail([EMCC, flag, '-sERROR_ON_UNDEFINED_SYMBOLS', test_file('other/test_check_undefined.c')]) + err = self.expect_fail([EMCC, '-sMAIN_MODULE', test_file('other/test_check_undefined.c')]) self.assertContained('undefined symbol: foo', err) @also_with_wasm64 @@ -13471,7 +13467,7 @@ def test_wasm_worker_errors(self): self.assertContained('-sSINGLE_FILE is not supported with -sWASM_WORKERS', err) err = self.expect_fail([EMCC, test_file('hello_world.c'), '-sWASM_WORKERS', '-sPROXY_TO_WORKER']) self.assertContained('-sPROXY_TO_WORKER is not supported with -sWASM_WORKERS', err) - err = self.expect_fail([EMCC, test_file('hello_world.c'), '-sWASM_WORKERS', '-sRELOCATABLE']) + err = self.expect_fail([EMCC, test_file('hello_world.c'), '-sWASM_WORKERS', '-sMAIN_MODULE']) self.assertContained('dynamic linking is not supported with -sWASM_WORKERS', err) def test_clock_nanosleep(self): @@ -15195,3 +15191,18 @@ def has_defined_function(file, func): self.assertIn('main.cpp', out) self.assertIn('foo.cpp', out) self.assertIn('/emsdk/emscripten/system/lib/libc/musl/src/string/strcmp.c', out) + + def test_relocatable(self): + # This setting is due for removal: + # https://github.com/emscripten-core/emscripten/issues/25262 + self.do_run_in_out_file_test('hello_world.c', cflags=['-Wno-deprecated', '-sRELOCATABLE']) + + def test_linkable(self): + # This setting is due for removal: + # https://github.com/emscripten-core/emscripten/issues/25262 + self.do_run_in_out_file_test('hello_world.c', cflags=['-Wno-deprecated', '-sLINKABLE']) + + def test_linkable_relocatable(self): + # These setting is due for removal: + # https://github.com/emscripten-core/emscripten/issues/25262 + self.do_run_in_out_file_test('hello_world.c', cflags=['-Wno-deprecated', '-sLINKABLE', '-sRELOCATABLE']) diff --git a/tools/settings.py b/tools/settings.py index a52c92c2e29d9..b315e9e82fe6c 100644 --- a/tools/settings.py +++ b/tools/settings.py @@ -137,7 +137,8 @@ # List of incompatible settings, of the form (SETTINGS_A, SETTING_B, OPTIONAL_REASON_FOR_INCOMPAT) INCOMPATIBLE_SETTINGS = [ ('MINIMAL_RUNTIME', 'RELOCATABLE', None), - ('WASM2JS', 'RELOCATABLE', None), + ('WASM2JS', 'MAIN_MODULE', 'wasm2js does not support dynamic linking'), + ('WASM2JS', 'SIDE_MODULE', 'wasm2js does not support dynamic linking'), ('MODULARIZE', 'PROXY_TO_WORKER', 'if you want to run in a worker with -sMODULARIZE, you likely want to do the worker side setup manually'), ('MODULARIZE', 'NO_DECLARE_ASM_MODULE_EXPORTS', None), ('EVAL_CTORS', 'WASM2JS', None),