@@ -955,22 +955,22 @@ def test_cmake_explicit_generator(self):
955
955
# Tests that it's possible to pass C++11 or GNU++11 build modes to CMake by building code that
956
956
# needs C++11 (embind)
957
957
@requires_ninja
958
- def test_cmake_with_embind_cpp11_mode(self):
959
- for args in [[], ['-DNO_GNU_EXTENSIONS=1']]:
960
- self.clear()
961
- # Use ninja generator here since we assume its always installed on our build/test machines.
962
- configure = [EMCMAKE, 'cmake', '-GNinja', test_file('cmake/cmake_with_emval')] + args
963
- print(str(configure))
964
- self.run_process(configure)
965
- build = ['cmake', '--build', '.']
966
- print(str( build))
967
- self.run_process(build)
968
-
969
- out = self.run_js('cmake_with_emval.js')
970
- if '-DNO_GNU_EXTENSIONS=1' in args:
971
- self.assertContained('Hello! __STRICT_ANSI__: 1, __cplusplus: 201103', out)
972
- else:
973
- self.assertContained('Hello! __STRICT_ANSI__: 0, __cplusplus: 201103', out)
958
+ @parameterized({
959
+ '': [[]],
960
+ '_no_gnu': [['-DNO_GNU_EXTENSIONS=1']],
961
+ })
962
+ def test_cmake_with_embind_cpp11_mode(self, args):
963
+ # Use ninja generator here since we assume its always installed on our build/test machines.
964
+ configure = [EMCMAKE, 'cmake', '-GNinja', test_file('cmake/cmake_with_emval')] + args
965
+ self.run_process(configure)
966
+ build = ['cmake', '-- build', '.']
967
+ self.run_process(build)
968
+
969
+ out = self.run_js('cmake_with_emval.js')
970
+ if '-DNO_GNU_EXTENSIONS=1' in args:
971
+ self.assertContained('Hello! __STRICT_ANSI__: 1, __cplusplus: 201103', out)
972
+ else:
973
+ self.assertContained('Hello! __STRICT_ANSI__: 0, __cplusplus: 201103', out)
974
974
975
975
# Tests that the Emscripten CMake toolchain option
976
976
def test_cmake_bitcode_static_libraries(self):
@@ -2584,11 +2584,16 @@ def test_undefined_exported_js_function(self, outfile):
2584
2584
self.run_process(cmd)
2585
2585
2586
2586
@parameterized({
2587
- 'warn ': ('WARN',) ,
2588
- 'error ': ('ERROR',) ,
2589
- 'ignore ': (None,)
2587
+ '': [[]] ,
2588
+ 'O1 ': [['-O1']] ,
2589
+ 'GL2 ': [['-sMAX_WEBGL_VERSION=2']],
2590
2590
})
2591
- def test_undefined_symbols(self, action):
2591
+ @parameterized({
2592
+ 'warn': ['WARN'],
2593
+ 'error': ['ERROR'],
2594
+ 'ignore': [None]
2595
+ })
2596
+ def test_undefined_symbols(self, action, args):
2592
2597
create_file('main.c', r'''
2593
2598
#include <stdio.h>
2594
2599
#include <SDL.h>
@@ -2606,36 +2611,35 @@ def test_undefined_symbols(self, action):
2606
2611
}
2607
2612
''')
2608
2613
2609
- for args in ([], ['-O1'], ['-sMAX_WEBGL_VERSION=2']):
2610
- for value in ([0, 1]):
2611
- delete_file('a.out.js')
2612
- print('checking "%s" %s' % (args, value))
2613
- extra = ['-s', action + '_ON_UNDEFINED_SYMBOLS=%d' % value] if action else []
2614
- proc = self.run_process([EMCC, '-sUSE_SDL', '-sGL_ENABLE_GET_PROC_ADDRESS', 'main.c'] + extra + args, stderr=PIPE, check=False)
2615
- if common.EMTEST_VERBOSE:
2616
- print(proc.stderr)
2617
- if value or action is None:
2618
- # The default is that we error in undefined symbols
2619
- self.assertContained('undefined symbol: something', proc.stderr)
2620
- self.assertContained('undefined symbol: elsey', proc.stderr)
2621
- check_success = False
2622
- elif action == 'ERROR' and not value:
2623
- # Error disables, should only warn
2624
- self.assertContained('warning: undefined symbol: something', proc.stderr)
2625
- self.assertContained('warning: undefined symbol: elsey', proc.stderr)
2626
- self.assertNotContained('undefined symbol: emscripten_', proc.stderr)
2627
- check_success = True
2628
- elif action == 'WARN' and not value:
2629
- # Disabled warning should imply disabling errors
2630
- self.assertNotContained('undefined symbol', proc.stderr)
2631
- check_success = True
2632
-
2633
- if check_success:
2634
- self.assertEqual(proc.returncode, 0)
2635
- self.assertTrue(os.path.exists('a.out.js'))
2636
- else:
2637
- self.assertNotEqual(proc.returncode, 0)
2638
- self.assertFalse(os.path.exists('a.out.js'))
2614
+ for value in ([0, 1]):
2615
+ delete_file('a.out.js')
2616
+ print('checking %s' % value)
2617
+ extra = ['-s', action + '_ON_UNDEFINED_SYMBOLS=%d' % value] if action else []
2618
+ proc = self.run_process([EMCC, '-sUSE_SDL', '-sGL_ENABLE_GET_PROC_ADDRESS', 'main.c'] + extra + args, stderr=PIPE, check=False)
2619
+ if common.EMTEST_VERBOSE:
2620
+ print(proc.stderr)
2621
+ if value or action is None:
2622
+ # The default is that we error in undefined symbols
2623
+ self.assertContained('undefined symbol: something', proc.stderr)
2624
+ self.assertContained('undefined symbol: elsey', proc.stderr)
2625
+ check_success = False
2626
+ elif action == 'ERROR' and not value:
2627
+ # Error disables, should only warn
2628
+ self.assertContained('warning: undefined symbol: something', proc.stderr)
2629
+ self.assertContained('warning: undefined symbol: elsey', proc.stderr)
2630
+ self.assertNotContained('undefined symbol: emscripten_', proc.stderr)
2631
+ check_success = True
2632
+ elif action == 'WARN' and not value:
2633
+ # Disabled warning should imply disabling errors
2634
+ self.assertNotContained('undefined symbol', proc.stderr)
2635
+ check_success = True
2636
+
2637
+ if check_success:
2638
+ self.assertEqual(proc.returncode, 0)
2639
+ self.assertTrue(os.path.exists('a.out.js'))
2640
+ else:
2641
+ self.assertNotEqual(proc.returncode, 0)
2642
+ self.assertFalse(os.path.exists('a.out.js'))
2639
2643
2640
2644
def test_undefined_data_symbols(self):
2641
2645
create_file('main.c', r'''
@@ -4658,7 +4662,13 @@ def add_on_abort_and_verify(extra=''):
4658
4662
os.remove('a.out.wasm') # trigger onAbort by intentionally causing startup to fail
4659
4663
add_on_abort_and_verify()
4660
4664
4661
- def test_no_exit_runtime(self):
4665
+ @parameterized({
4666
+ '': ([],),
4667
+ '01': (['-O1', '-g2'],),
4668
+ 'O2': (['-O2', '-g2', '-flto'],),
4669
+ })
4670
+ @also_with_wasm2js
4671
+ def test_no_exit_runtime(self, opts):
4662
4672
create_file('code.cpp', r'''
4663
4673
#include <stdio.h>
4664
4674
@@ -4683,29 +4693,27 @@ def test_no_exit_runtime(self):
4683
4693
}
4684
4694
''')
4685
4695
4686
- for wasm in [0, 1]:
4687
- for no_exit in [1, 0]:
4688
- for opts in [[], ['-O1'], ['-O2', '-g2'], ['-O2', '-g2', '-flto']]:
4689
- print(wasm, no_exit, opts)
4690
- cmd = [EMXX] + opts + ['code.cpp', '-sEXIT_RUNTIME=' + str(1 - no_exit), '-sWASM=' + str(wasm)]
4691
- if wasm:
4692
- cmd += ['--profiling-funcs'] # for function names
4693
- self.run_process(cmd)
4694
- output = self.run_js('a.out.js')
4695
- src = read_file('a.out.js')
4696
- if wasm:
4697
- src += '\n' + self.get_wasm_text('a.out.wasm')
4698
- exit = 1 - no_exit
4699
- print(' exit:', exit, 'opts:', opts)
4700
- self.assertContained('coming around', output)
4701
- self.assertContainedIf('going away', output, exit)
4702
- # The wasm backend uses atexit to register destructors when
4703
- # constructors are called There is currently no way to exclude
4704
- # these destructors from the wasm binary.
4705
- # TODO(sbc): Re-enabled these assertions once the wasm backend
4706
- # is able to eliminate these.
4707
- # assert ('atexit(' in src) == exit, 'atexit should not appear in src when EXIT_RUNTIME=0'
4708
- # assert ('_ZN5WasteILi2EED' in src) == exit, 'destructors should not appear if no exit:\n' + src
4696
+ for no_exit in [1, 0]:
4697
+ print(no_exit)
4698
+ cmd = [EMXX] + opts + ['code.cpp', '-sEXIT_RUNTIME=' + str(1 - no_exit)] + self.get_emcc_args()
4699
+ if self.is_wasm():
4700
+ cmd += ['--profiling-funcs'] # for function names
4701
+ self.run_process(cmd)
4702
+ output = self.run_js('a.out.js')
4703
+ src = read_file('a.out.js')
4704
+ if self.is_wasm():
4705
+ src += '\n' + self.get_wasm_text('a.out.wasm')
4706
+ exit = 1 - no_exit
4707
+ print(' exit:', exit)
4708
+ self.assertContained('coming around', output)
4709
+ self.assertContainedIf('going away', output, exit)
4710
+ # The wasm backend uses atexit to register destructors when
4711
+ # constructors are called There is currently no way to exclude
4712
+ # these destructors from the wasm binary.
4713
+ # TODO(sbc): Re-enabled these assertions once the wasm backend
4714
+ # is able to eliminate these.
4715
+ # assert ('atexit(' in src) == exit, 'atexit should not appear in src when EXIT_RUNTIME=0'
4716
+ # assert ('_ZN5WasteILi2EED' in src) == exit, 'destructors should not appear if no exit:\n' + src
4709
4717
4710
4718
def test_no_exit_runtime_warnings_flush(self):
4711
4719
# check we warn if there is unflushed info
@@ -4771,19 +4779,22 @@ def test(cxx, no_exit, assertions, flush=0, keepalive=0, filesystem=1):
4771
4779
for flush in [0, 1]:
4772
4780
test(cxx, no_exit, assertions, flush)
4773
4781
4774
- def test_fs_after_main(self):
4775
- for args in [[], ['-O1']]:
4776
- print(args)
4777
- self.run_process([EMXX, test_file('fs_after_main.cpp')])
4778
- self.assertContained('Test passed.', self.run_js('a.out.js'))
4779
-
4780
- def test_opt_levels(self):
4781
- for opt in ['-O1', '-O2', '-Os', '-Oz', '-O3', '-Og', '-Ofast']:
4782
+ def test_extra_opt_levels(self):
4783
+ # Opt levels that we don't tend to test elsewhere
4784
+ for opt in ['-Og', '-Ofast']:
4782
4785
print(opt)
4783
4786
proc = self.run_process([EMCC, '-v', test_file('hello_world.c'), opt], stderr=PIPE)
4784
4787
self.assertContained(opt, proc.stderr)
4785
4788
self.assertContained('hello, world!', self.run_js('a.out.js'))
4786
4789
4790
+ @parameterized({
4791
+ '': [[]],
4792
+ 'O1': [['-O1']],
4793
+ })
4794
+ def test_fs_after_main(self, args):
4795
+ self.run_process([EMXX, test_file('fs_after_main.cpp')])
4796
+ self.assertContained('Test passed.', self.run_js('a.out.js'))
4797
+
4787
4798
def test_oz_size(self):
4788
4799
sizes = {}
4789
4800
for name, args in [
@@ -6615,17 +6626,18 @@ def test_massive_alloc(self, wasm):
6615
6626
if not wasm:
6616
6627
self.assertContained('Warning: Enlarging memory arrays, this is not fast! 16777216,1468137472\n', output)
6617
6628
6618
- def test_failing_alloc(self):
6629
+ @parameterized({
6630
+ '': (False,),
6631
+ 'growth': (True,),
6632
+ })
6633
+ @also_with_wasm2js
6634
+ def test_failing_alloc(self, growth):
6619
6635
for pre_fail, post_fail, opts in [
6620
6636
('', '', []),
6621
6637
('EM_ASM( Module.temp = _sbrk() );', 'EM_ASM( assert(Module.temp === _sbrk(), "must not adjust brk when an alloc fails!") );', []),
6622
- # also test non-wasm in normal mode
6623
- ('', '', ['-sWASM=0']),
6624
- ('EM_ASM( Module.temp = _sbrk() );', 'EM_ASM( assert(Module.temp === _sbrk(), "must not adjust brk when an alloc fails!") );', ['-sWASM=0']),
6625
6638
]:
6626
- for growth in [0, 1]:
6627
- for aborting_args in [[], ['-sABORTING_MALLOC=0']]:
6628
- create_file('main.cpp', r'''
6639
+ for aborting_args in [[], ['-sABORTING_MALLOC=0']]:
6640
+ create_file('main.cpp', r'''
6629
6641
#include <stdio.h>
6630
6642
#include <stdlib.h>
6631
6643
#include <vector>
@@ -6665,38 +6677,38 @@ def test_failing_alloc(self):
6665
6677
printf("managed another malloc!\n");
6666
6678
}
6667
6679
''' % (pre_fail, post_fail))
6668
- args = [EMXX, 'main.cpp', '-sEXPORTED_FUNCTIONS=_main,_sbrk', '-sINITIAL_MEMORY=16MB'] + opts + aborting_args
6669
- args += ['-sTEST_MEMORY_GROWTH_FAILS'] # In this test, force memory growing to fail
6680
+ args = [EMXX, 'main.cpp', '-sEXPORTED_FUNCTIONS=_main,_sbrk', '-sINITIAL_MEMORY=16MB'] + opts + aborting_args
6681
+ args += ['-sTEST_MEMORY_GROWTH_FAILS'] # In this test, force memory growing to fail
6682
+ if growth:
6683
+ args += ['-sALLOW_MEMORY_GROWTH']
6684
+ # growth disables aborting by default, but it can be overridden
6685
+ aborting = not aborting_args and not growth
6686
+ print('test_failing_alloc', args, pre_fail)
6687
+ self.run_process(args)
6688
+ # growth also disables aborting
6689
+ can_manage_another = not aborting
6690
+ split = '-DSPLIT' in args
6691
+ print('can manage another:', can_manage_another, 'split:', split, 'aborting:', aborting)
6692
+ output = self.run_js('a.out.js', assert_returncode=0 if can_manage_another else NON_ZERO)
6693
+ if can_manage_another:
6694
+ self.assertContained('an allocation failed!\n', output)
6695
+ if not split:
6696
+ # split memory allocation may fail due to GC objects no longer being allocatable,
6697
+ # and we can't expect to recover from that deterministically. So just check we
6698
+ # get to the fail.
6699
+ # otherwise, we should fail eventually, then free, then succeed
6700
+ self.assertContained('managed another malloc!\n', output)
6701
+ else:
6702
+ # we should see an abort
6703
+ self.assertContained('Aborted(Cannot enlarge memory arrays', output)
6670
6704
if growth:
6671
- args += ['-sALLOW_MEMORY_GROWTH']
6672
- # growth disables aborting by default, but it can be overridden
6673
- aborting = not aborting_args and not growth
6674
- print('test_failing_alloc', args, pre_fail)
6675
- self.run_process(args)
6676
- # growth also disables aborting
6677
- can_manage_another = not aborting
6678
- split = '-DSPLIT' in args
6679
- print('can manage another:', can_manage_another, 'split:', split, 'aborting:', aborting)
6680
- output = self.run_js('a.out.js', assert_returncode=0 if can_manage_another else NON_ZERO)
6681
- if can_manage_another:
6682
- self.assertContained('an allocation failed!\n', output)
6683
- if not split:
6684
- # split memory allocation may fail due to GC objects no longer being allocatable,
6685
- # and we can't expect to recover from that deterministically. So just check we
6686
- # get to the fail.
6687
- # otherwise, we should fail eventually, then free, then succeed
6688
- self.assertContained('managed another malloc!\n', output)
6705
+ # when growth is enabled, the default is to not abort, so just explain that
6706
+ self.assertContained('If you want malloc to return NULL (0) instead of this abort, do not link with -sABORTING_MALLOC', output)
6689
6707
else:
6690
- # we should see an abort
6691
- self.assertContained('Aborted(Cannot enlarge memory arrays', output)
6692
- if growth:
6693
- # when growth is enabled, the default is to not abort, so just explain that
6694
- self.assertContained('If you want malloc to return NULL (0) instead of this abort, do not link with -sABORTING_MALLOC', output)
6695
- else:
6696
- # when growth is not enabled, suggest 3 possible solutions (start with more memory, allow growth, or don't abort)
6697
- self.assertContained(('higher than the current value 16777216,', 'higher than the current value 33554432,'), output)
6698
- self.assertContained('compile with -sALLOW_MEMORY_GROWTH', output)
6699
- self.assertContained('compile with -sABORTING_MALLOC=0', output)
6708
+ # when growth is not enabled, suggest 3 possible solutions (start with more memory, allow growth, or don't abort)
6709
+ self.assertContained(('higher than the current value 16777216,', 'higher than the current value 33554432,'), output)
6710
+ self.assertContained('compile with -sALLOW_MEMORY_GROWTH', output)
6711
+ self.assertContained('compile with -sABORTING_MALLOC=0', output)
6700
6712
6701
6713
def test_failing_growth_2gb(self):
6702
6714
create_file('test.c', r'''
@@ -8779,37 +8791,42 @@ def test_side_module_folder_deps(self):
8779
8791
self.run_process([EMCC, test_file('hello_world.c'), '-sMAIN_MODULE', '-o', 'main.js', '-L', 'subdir', '-lside2'])
8780
8792
8781
8793
@is_slow_test
8782
- def test_lto(self):
8794
+ @parameterized({
8795
+ '': ([],),
8796
+ '01': (['-O1'],),
8797
+ 'O2': (['-O2'],),
8798
+ 'O3': (['-O3'],),
8799
+ 'Os': (['-Os'],),
8800
+ 'Oz': (['-Oz'],),
8801
+ })
8802
+ def test_lto(self, args):
8783
8803
# test building of non-wasm-object-files libraries, building with them, and running them
8784
8804
8785
- src = test_file('hello_libcxx.cpp')
8786
8805
# test codegen in lto mode, and compare to normal (wasm object) mode
8787
- for args in [[], ['-O1'], ['-O2'], ['-O3'], ['-Os'], ['-Oz']]:
8788
- print(args)
8789
-
8790
- print('wasm in object')
8791
- self.run_process([EMXX, src] + args + ['-c', '-o', 'hello_obj.o'])
8792
- self.assertTrue(building.is_wasm('hello_obj.o'))
8793
- self.assertFalse(is_bitcode('hello_obj.o'))
8794
-
8795
- print('bitcode in object')
8796
- self.run_process([EMXX, src] + args + ['-c', '-o', 'hello_bitcode.o', '-flto'])
8797
- self.assertFalse(building.is_wasm('hello_bitcode.o'))
8798
- self.assertTrue(is_bitcode('hello_bitcode.o'))
8799
-
8800
- print('use bitcode object (LTO)')
8801
- self.run_process([EMXX, 'hello_bitcode.o'] + args + ['-flto'])
8802
- self.assertContained('hello, world!', self.run_js('a.out.js'))
8803
- print('use bitcode object (non-LTO)')
8804
- self.run_process([EMXX, 'hello_bitcode.o'] + args)
8805
- self.assertContained('hello, world!', self.run_js('a.out.js'))
8806
+ src = test_file('hello_libcxx.cpp')
8807
+ # wasm in object
8808
+ self.run_process([EMXX, src] + args + ['-c', '-o', 'hello_obj.o'])
8809
+ self.assertTrue(building.is_wasm('hello_obj.o'))
8810
+ self.assertFalse(is_bitcode('hello_obj.o'))
8811
+
8812
+ # bitcode in object
8813
+ self.run_process([EMXX, src] + args + ['-c', '-o', 'hello_bitcode.o', '-flto'])
8814
+ self.assertFalse(building.is_wasm('hello_bitcode.o'))
8815
+ self.assertTrue(is_bitcode('hello_bitcode.o'))
8816
+
8817
+ # use bitcode object (LTO)
8818
+ self.run_process([EMXX, 'hello_bitcode.o'] + args + ['-flto'])
8819
+ self.assertContained('hello, world!', self.run_js('a.out.js'))
8820
+ # use bitcode object (non-LTO)
8821
+ self.run_process([EMXX, 'hello_bitcode.o'] + args)
8822
+ self.assertContained('hello, world!', self.run_js('a.out.js'))
8806
8823
8807
- print(' use native object (LTO)' )
8808
- self.run_process([EMXX, 'hello_obj.o'] + args + ['-flto'])
8809
- self.assertContained('hello, world!', self.run_js('a.out.js'))
8810
- print(' use native object (non-LTO)' )
8811
- self.run_process([EMXX, 'hello_obj.o'] + args)
8812
- self.assertContained('hello, world!', self.run_js('a.out.js'))
8824
+ # use native object (LTO)
8825
+ self.run_process([EMXX, 'hello_obj.o'] + args + ['-flto'])
8826
+ self.assertContained('hello, world!', self.run_js('a.out.js'))
8827
+ # use native object (non-LTO)
8828
+ self.run_process([EMXX, 'hello_obj.o'] + args)
8829
+ self.assertContained('hello, world!', self.run_js('a.out.js'))
8813
8830
8814
8831
@parameterized({
8815
8832
'noexcept': [],
0 commit comments