Beispiel #1
0
    def test_vanilla(self):
        restore_and_set_up()
        Cache.erase()

        def make_fake(report):
            with open(config_file, 'a') as f:
                f.write('LLVM_ROOT = "' + self.in_dir('fake', 'bin') + '"\n')
                # BINARYEN_ROOT needs to exist in the config, even though this test
                # doesn't actually use it.
                f.write('BINARYEN_ROOT= "%s"\n' % self.in_dir('fake', 'bin'))

            make_fake_clang(self.in_dir('fake', 'bin', 'clang'),
                            EXPECTED_LLVM_VERSION)
            make_fake_llc(self.in_dir('fake', 'bin', 'llc'), report)
            make_fake_lld(self.in_dir('fake', 'bin', 'wasm-ld'))

        # fake llc output

        def test_with_fake(report, expected):
            make_fake(report)
            with env_modify({'EMCC_DEBUG': '1'}):
                self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                                   expected)

        test_with_fake(
            'got js backend! JavaScript (asm.js, emscripten) backend',
            'LLVM has not been built with the WebAssembly backend')
        try_delete(CANONICAL_TEMP_DIR)
Beispiel #2
0
  def test_emcc_caching(self):
    INCLUDING_MESSAGE = 'including X'
    BUILDING_MESSAGE = 'building X for cache'
    ERASING_MESSAGE = 'clearing cache'

    EMCC_CACHE = Cache.dirname

    restore_and_set_up()

    Cache.erase()
    assert not os.path.exists(EMCC_CACHE)

    with env_modify({'EMCC_DEBUG': '1'}):
      # Building a file that *does* need something *should* trigger cache
      # generation, but only the first time
      for filename, libname in [('hello_libcxx.cpp', 'libcxx')]:
        for i in range(3):
          print(filename, libname, i)
          self.clear()
          output = self.do([EMCC, '-O' + str(i), '-s', '--llvm-lto', '0', path_from_root('tests', filename), '--save-bc', 'a.bc', '-s', 'DISABLE_EXCEPTION_CATCHING=0'])
          # print '\n\n\n', output
          assert INCLUDING_MESSAGE.replace('X', libname) in output
          if libname == 'libc':
            assert INCLUDING_MESSAGE.replace('X', 'libcxx') not in output # we don't need libcxx in this code
          else:
            assert INCLUDING_MESSAGE.replace('X', 'libc') in output # libcxx always forces inclusion of libc
          assert (BUILDING_MESSAGE.replace('X', libname) in output) == (i == 0), 'Must only build the first time'
          self.assertContained('hello, world!', run_js('a.out.js'))
          assert os.path.exists(EMCC_CACHE)
          full_libname = libname + '.bc' if libname != 'libcxx' else libname + '.a'
          assert os.path.exists(os.path.join(EMCC_CACHE, full_libname))

    try_delete(CANONICAL_TEMP_DIR)
    restore_and_set_up()

    def ensure_cache():
      self.do([PYTHON, EMCC, '-O2', path_from_root('tests', 'hello_world.c')])

    # Manual cache clearing
    ensure_cache()
    self.assertTrue(os.path.exists(EMCC_CACHE))
    output = self.do([PYTHON, EMCC, '--clear-cache'])
    self.assertIn(ERASING_MESSAGE, output)
    self.assertFalse(os.path.exists(EMCC_CACHE))
    self.assertIn(SANITY_MESSAGE, output)

    # Changing LLVM_ROOT, even without altering .emscripten, clears the cache
    ensure_cache()
    with env_modify({'LLVM': 'waka'}):
      self.assertTrue(os.path.exists(EMCC_CACHE))
      output = self.do([PYTHON, EMCC])
      self.assertIn(ERASING_MESSAGE, output)
      self.assertFalse(os.path.exists(EMCC_CACHE))
Beispiel #3
0
    def test_emcc_multiprocess_cache_access(self):
        restore_and_set_up()

        create_file(
            'test.c', r'''
      #include <stdio.h>
      int main() {
        printf("hello, world!\n");
        return 0;
      }
      ''')
        cache_dir_name = self.in_dir('test_cache')
        libname = Cache.get_lib_name('libc.a')
        with env_modify({'EM_CACHE': cache_dir_name}):
            tasks = []
            num_times_libc_was_built = 0
            for i in range(3):
                p = self.run_process(
                    [EMCC, 'test.c', '-o', '%d.js' % i],
                    stderr=STDOUT,
                    stdout=PIPE)
                tasks += [p]
            for p in tasks:
                print('stdout:\n', p.stdout)
                if 'generating system library: ' + libname in p.stdout:
                    num_times_libc_was_built += 1

        # The cache directory must exist after the build
        self.assertExists(cache_dir_name)
        # The cache directory must contain a built libc
        self.assertExists(os.path.join(cache_dir_name, libname))
        # Exactly one child process should have triggered libc build!
        self.assertEqual(num_times_libc_was_built, 1)
Beispiel #4
0
    def test_wacky_env(self):
        restore_and_set_up()

        def build():
            return self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')

        def test():
            self.assertContained('hello, world!', run_js('a.out.js'))

        print('normal build')
        with env_modify({'EMCC_FORCE_STDLIBS': None}):
            Cache.erase()
            build()
            test()

        print('wacky env vars, these should not mess our bootstrapping')
        with env_modify({'EMCC_FORCE_STDLIBS': '1'}):
            Cache.erase()
            build()
            test()
Beispiel #5
0
  def test_wacky_env(self):
    restore_and_set_up()

    def build():
      return self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')

    def test():
      self.assertContained('hello, world!', run_js('a.out.js'))

    print('normal build')
    with env_modify({'EMCC_FORCE_STDLIBS': None}):
      Cache.erase()
      build()
      test()

    print('wacky env vars, these should not mess our bootstrapping')
    with env_modify({'EMCC_FORCE_STDLIBS': '1'}):
      Cache.erase()
      build()
      test()
Beispiel #6
0
  def test_nostdincxx(self):
    restore_and_set_up()
    Cache.erase()

    for compiler in [EMCC]:
      print(compiler)
      run_process([PYTHON, EMCC] + MINIMAL_HELLO_WORLD + ['-v']) # run once to ensure binaryen port is all ready
      proc = run_process([PYTHON, EMCC] + MINIMAL_HELLO_WORLD + ['-v'], stdout=PIPE, stderr=PIPE)
      out = proc.stdout
      err = proc.stderr
      proc2 = run_process([PYTHON, EMCC] + MINIMAL_HELLO_WORLD + ['-v', '-nostdinc++'], stdout=PIPE, stderr=PIPE)
      out2 = proc2.stdout
      err2 = proc2.stderr
      self.assertIdentical(out, out2)

      def focus(e):
        assert 'search starts here:' in e, e
        assert e.count('End of search list.') == 1, e
        return e[e.index('search starts here:'):e.index('End of search list.') + 20]

      err = focus(err)
      err2 = focus(err2)
      assert err == err2, err + '\n\n\n\n' + err2
Beispiel #7
0
  def test_emcc_caching(self):
    BUILDING_MESSAGE = 'generating system library: %s'

    restore_and_set_up()
    self.clear_cache()

    # Building a file that *does* need something *should* trigger cache
    # generation, but only the first time
    libname = Cache.get_lib_name('libc++.a')
    for i in range(3):
      print(i)
      self.clear()
      output = self.do([EMCC, '-O' + str(i), path_from_root('tests', 'hello_libcxx.cpp'), '-s', 'DISABLE_EXCEPTION_CATCHING=0'])
      print('\n\n\n', output)
      self.assertContainedIf(BUILDING_MESSAGE % libname, output, i == 0)
      self.assertContained('hello, world!', self.run_js('a.out.js'))
      self.assertExists(Cache.dirname)
      self.assertExists(os.path.join(Cache.dirname, libname))
Beispiel #8
0
    def test_vanilla(self):
        restore_and_set_up()
        Cache.erase()

        with env_modify({'EMCC_DEBUG': '1'}):
            # see that we test vanilla status, and just once
            TESTING = 'testing for asm.js target'
            print(self.check_working(EMCC, TESTING))

            for i in range(3):
                output = self.check_working(EMCC, 'check tells us to use')
                self.assertNotContained(TESTING, output)
            # if env var tells us, do what it says
            with env_modify({'EMCC_WASM_BACKEND': '1'}):
                self.check_working(
                    EMCC, 'EMCC_WASM_BACKEND tells us to use wasm backend')
            with env_modify({'EMCC_WASM_BACKEND': '0'}):
                self.check_working(
                    EMCC, 'EMCC_WASM_BACKEND tells us to use asm.js backend')

        def make_fake(report):
            with open(CONFIG_FILE, 'a') as f:
                f.write('LLVM_ROOT = "' + self.in_dir('fake', 'bin') + '"\n')
                # BINARYEN_ROOT needs to exist in the config, even though this test
                # doesn't actually use it.
                f.write('BINARYEN_ROOT= "%s"\n' % self.in_dir('fake', 'bin'))

            make_fake_clang(self.in_dir('fake', 'bin', 'clang'),
                            expected_llvm_version())
            make_fake_llc(self.in_dir('fake', 'bin', 'llc'), report)
            make_fake_lld(self.in_dir('fake', 'bin', 'wasm-ld'))

        with env_modify({'EMCC_DEBUG': '1'}):
            make_fake('wasm32-unknown-unknown-elf')
            # see that we request the right backend from llvm
            with env_modify({'EMCC_WASM_BACKEND': '1'}):
                self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                                   'wasm32-unknown-unknown-elf')
            make_fake('asmjs-unknown-emscripten')
            with env_modify({'EMCC_WASM_BACKEND': '0'}):
                self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                                   'asmjs-unknown-emscripten')
            # check the current installed one is ok
            restore_and_set_up()
            self.check_working(EMCC)
            output = self.check_working(EMCC, 'check tells us to use')
            if 'wasm backend' in output:
                self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                                   'wasm32-unknown-unknown-elf')
            else:
                assert 'asm.js backend' in output
                self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                                   'asmjs-unknown-emscripten')

        # fake llc output

        def test_with_fake(report, expected):
            make_fake(report)
            with env_modify({'EMCC_DEBUG': '1'}):
                output = self.check_working([EMCC] + MINIMAL_HELLO_WORLD +
                                            ['-c'], expected)
                self.assertContained(
                    'config file changed since we checked vanilla', output)

        test_with_fake(
            'got js backend! JavaScript (asm.js, emscripten) backend',
            'check tells us to use asm.js backend')
        test_with_fake('got wasm32 backend! WebAssembly 32-bit',
                       'check tells us to use wasm backend')

        # use LLVM env var to modify LLVM between vanilla checks

        assert not os.environ.get(
            'EM_LLVM_ROOT'), 'we need to modify EM_LLVM_ROOT env var for this'

        f = open(CONFIG_FILE, 'a')
        f.write('LLVM_ROOT = "' + self.in_dir('fake1', 'bin') + '"\n')
        f.close()

        safe_ensure_dirs(self.in_dir('fake1', 'bin'))
        f = open(self.in_dir('fake1', 'bin', 'llc'), 'w')
        f.write('#!/bin/sh\n')
        f.write('echo "llc fake1 output\nRegistered Targets:\n%s"' %
                'got js backend! JavaScript (asm.js, emscripten) backend')
        f.close()
        os.chmod(self.in_dir('fake1', 'bin', 'llc'),
                 stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

        safe_ensure_dirs(self.in_dir('fake2', 'bin'))
        f = open(self.in_dir('fake2', 'bin', 'llc'), 'w')
        f.write('#!/bin/sh\n')
        f.write('echo "llc fake2 output\nRegistered Targets:\n%s"' %
                'got wasm32 backend! WebAssembly 32-bit')
        f.close()
        os.chmod(self.in_dir('fake2', 'bin', 'llc'),
                 stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

        with env_modify({'EMCC_DEBUG': '1'}):
            self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                               'use asm.js backend')
            with env_modify({'EM_LLVM_ROOT': self.in_dir('fake2', 'bin')}):
                self.check_working(
                    [EMCC] + MINIMAL_HELLO_WORLD + ['-c'],
                    'regenerating vanilla check since other llvm')

        try_delete(CANONICAL_TEMP_DIR)
        return  # TODO: the rest of this

        # check separate cache dirs are used

        restore_and_set_up()
        self.check_working([EMCC], '')

        root_cache = os.path.expanduser('~/.emscripten_cache')
        if os.path.exists(os.path.join(root_cache, 'asmjs')):
            shutil.rmtree(os.path.join(root_cache, 'asmjs'))
        if os.path.exists(os.path.join(root_cache, 'wasm')):
            shutil.rmtree(os.path.join(root_cache, 'wasm'))

        with env_modify({'EMCC_WASM_BACKEND': '1'}):
            self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
            self.assertExists(os.path.join(root_cache, 'wasm'))

        with env_modify({'EMCC_WASM_BACKEND': '0'}):
            self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
            self.assertExists(os.path.join(root_cache, 'asmjs'))
            shutil.rmtree(os.path.join(root_cache, 'asmjs'))

        self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
        self.assertExists(os.path.join(root_cache, 'asmjs'))
Beispiel #9
0
 def erase_cache(self):
     Cache.erase()
     self.assertCacheEmpty()
 def erase_cache(self):
     Cache.erase()
     assert not os.path.exists(Cache.dirname)
Beispiel #11
0
  def test_binaryen(self):
    import tools.ports.binaryen as binaryen
    tag_file = Cache.get_path('binaryen_tag_' + binaryen.TAG + '.txt')

    assert not os.environ.get('BINARYEN') # must not have binaryen env var set

    # test in 2 modes - with BINARYEN_ROOT in the config file, set to '', and without it entirely
    for binaryen_root_in_config in [1, 0]:
      print('binaryen_root_in_config:', binaryen_root_in_config)

      def prep():
        restore_and_set_up()
        print('clearing ports...')
        print(self.do([PYTHON, EMCC, '--clear-ports']))
        wipe()
        self.do([PYTHON, EMCC]) # first run stage
        try_delete(tag_file)
        # if BINARYEN_ROOT is set, we don't build the port. Check we do build it if not
        if binaryen_root_in_config:
          config = open(CONFIG_FILE).read()
          assert '''BINARYEN_ROOT = os.path.expanduser(os.getenv('BINARYEN', ''))''' in config, config # setup created it to be ''
          print('created config:')
          print(config)
          restore_and_set_up()
          config = open(CONFIG_FILE).read()
          config = config.replace('BINARYEN_ROOT', '''BINARYEN_ROOT = os.path.expanduser(os.getenv('BINARYEN', '')) # ''')
        else:
          restore_and_set_up()
          config = open(CONFIG_FILE).read()
          config = config.replace('BINARYEN_ROOT', '#')
        print('modified config:')
        print(config)
        open(CONFIG_FILE, 'w').write(config)

      print('build using embuilder')
      prep()
      run_process([PYTHON, EMBUILDER, 'build', 'binaryen'])
      assert os.path.exists(tag_file)
      run_process([PYTHON, EMCC] + MINIMAL_HELLO_WORLD + ['-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-binary"'])
      self.assertContained('hello, world!', run_js('a.out.js'))

      print('see we show an error for emmake (we cannot build natively under emmake)')
      prep()
      try_delete('a.out.js')
      out = self.do([PYTHON, path_from_root('emmake.py'), EMCC] + MINIMAL_HELLO_WORLD + ['-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-binary"'])
      assert not os.path.exists(tag_file)
      assert not os.path.exists('a.out.js')
      self.assertContained('For example, for binaryen, do "python embuilder.py build binaryen"', out)

      if not binaryen_root_in_config:
        print('build on demand')
        for side_module in (False, True):
          print(side_module)
          prep()
          assert not os.path.exists(tag_file)
          try_delete('a.out.js')
          try_delete('a.out.wasm')
          cmd = [PYTHON, EMCC]
          if not side_module:
            cmd += MINIMAL_HELLO_WORLD
          else:
            # EM_ASM doesn't work in a wasm side module, build a normal program
            cmd += [path_from_root('tests', 'hello_world.c'), '-s', 'SIDE_MODULE=1']
          cmd += ['-s', 'BINARYEN=1', '-s', 'BINARYEN_METHOD="interpret-binary"']
          run_process(cmd)
          assert os.path.exists(tag_file)
          assert os.path.exists('a.out.wasm')
          if not side_module:
            assert os.path.exists('a.out.js')
            self.assertContained('hello, world!', run_js('a.out.js'))
Beispiel #12
0
  def test_vanilla(self):
    restore_and_set_up()
    Cache.erase()

    with env_modify({'EMCC_DEBUG': '1'}):
      # see that we test vanilla status, and just once
      TESTING = 'testing for asm.js target'
      self.check_working(EMCC, TESTING)
      for i in range(3):
        output = self.check_working(EMCC, 'check tells us to use')
        assert TESTING not in output
      # if env var tells us, do what it says
      with env_modify({'EMCC_WASM_BACKEND': '1'}):
        self.check_working(EMCC, 'EMCC_WASM_BACKEND tells us to use wasm backend')
      with env_modify({'EMCC_WASM_BACKEND': '0'}):
        self.check_working(EMCC, 'EMCC_WASM_BACKEND tells us to use asm.js backend')

    def make_fake(report):
      with open(CONFIG_FILE, 'a') as f:
        f.write('LLVM_ROOT = "' + path_from_root('tests', 'fake', 'bin') + '"\n')
        # BINARYEN_ROOT needs to exist in the config, even though this test
        # doesn't actually use it.
        f.write('BINARYEN_ROOT= "%s"\n' % path_from_root('tests', 'fake', 'bin'))

      with open(path_from_root('tests', 'fake', 'bin', 'llc'), 'w') as f:
        f.write('#!/bin/sh\n')
        f.write('echo "llc fake output\nRegistered Targets:\n%s"' % report)
      os.chmod(path_from_root('tests', 'fake', 'bin', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
      with open(path_from_root('tests', 'fake', 'bin', 'wasm-ld'), 'w') as f:
        f.write('#!/bin/sh\n')
        f.write('exit 0\n')
      os.chmod(path_from_root('tests', 'fake', 'bin', 'wasm-ld'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

    with env_modify({'EMCC_DEBUG': '1'}):
      make_fake('wasm32-unknown-unknown-elf')
      # see that we request the right backend from llvm
      with env_modify({'EMCC_WASM_BACKEND': '1'}):
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'wasm32-unknown-unknown-elf')
      make_fake('asmjs-unknown-emscripten')
      with env_modify({'EMCC_WASM_BACKEND': '0'}):
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'asmjs-unknown-emscripten')
      # check the current installed one is ok
      restore_and_set_up()
      self.check_working(EMCC)
      output = self.check_working(EMCC, 'check tells us to use')
      if 'wasm backend' in output:
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'wasm32-unknown-unknown-elf')
      else:
        assert 'asm.js backend' in output
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'asmjs-unknown-emscripten')

    # fake llc output

    try_delete(path_from_root('tests', 'fake'))
    os.makedirs(path_from_root('tests', 'fake', 'bin'))

    def test_with_fake(report, expected):
      make_fake(report)
      with env_modify({'EMCC_DEBUG': '1'}):
        output = self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], expected)
        self.assertContained('config file changed since we checked vanilla', output)

    test_with_fake('got js backend! JavaScript (asm.js, emscripten) backend', 'check tells us to use asm.js backend')
    test_with_fake('got wasm32 backend! WebAssembly 32-bit',                  'check tells us to use wasm backend')

    # use LLVM env var to modify LLVM between vanilla checks

    assert not os.environ.get('LLVM'), 'we need to modify LLVM env var for this'

    f = open(CONFIG_FILE, 'a')
    f.write('LLVM_ROOT = os.getenv("LLVM", "' + path_from_root('tests', 'fake1', 'bin') + '")\n')
    f.close()

    safe_ensure_dirs(path_from_root('tests', 'fake1', 'bin'))
    f = open(path_from_root('tests', 'fake1', 'bin', 'llc'), 'w')
    f.write('#!/bin/sh\n')
    f.write('echo "llc fake1 output\nRegistered Targets:\n%s"' % 'got js backend! JavaScript (asm.js, emscripten) backend')
    f.close()
    os.chmod(path_from_root('tests', 'fake1', 'bin', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

    safe_ensure_dirs(path_from_root('tests', 'fake2', 'bin'))
    f = open(path_from_root('tests', 'fake2', 'bin', 'llc'), 'w')
    f.write('#!/bin/sh\n')
    f.write('echo "llc fake2 output\nRegistered Targets:\n%s"' % 'got wasm32 backend! WebAssembly 32-bit')
    f.close()
    os.chmod(path_from_root('tests', 'fake2', 'bin', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)

    with env_modify({'EMCC_DEBUG': '1'}):
      self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'use asm.js backend')
      with env_modify({'LLVM': path_from_root('tests', 'fake2', 'bin')}):
        self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-c'], 'regenerating vanilla check since other llvm')

    try_delete(CANONICAL_TEMP_DIR)
    return # TODO: the rest of this

    # check separate cache dirs are used

    restore_and_set_up()
    self.check_working([EMCC], '')

    root_cache = os.path.expanduser('~/.emscripten_cache')
    if os.path.exists(os.path.join(root_cache, 'asmjs')):
      shutil.rmtree(os.path.join(root_cache, 'asmjs'))
    if os.path.exists(os.path.join(root_cache, 'wasm')):
      shutil.rmtree(os.path.join(root_cache, 'wasm'))

    with env_modify({'EMCC_WASM_BACKEND': '1'}):
      self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
      assert os.path.exists(os.path.join(root_cache, 'wasm'))

    with env_modify({'EMCC_WASM_BACKEND': '0'}):
      self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
      assert os.path.exists(os.path.join(root_cache, 'asmjs'))
      shutil.rmtree(os.path.join(root_cache, 'asmjs'))

    self.check_working([EMCC] + MINIMAL_HELLO_WORLD, '')
    assert os.path.exists(os.path.join(root_cache, 'asmjs'))
Beispiel #13
0
  def test_embuilder(self):
    restore_and_set_up()

    tests = [
      ([PYTHON, EMBUILDER], ['Emscripten System Builder Tool', 'build libc', 'native_optimizer'], True, []),
      ([PYTHON, EMBUILDER, 'build', 'waka'], 'ERROR', False, []),
      ([PYTHON, EMBUILDER, 'build', 'struct_info'], ['building and verifying struct_info', 'success'], True, ['generated_struct_info.json']),
      ([PYTHON, EMBUILDER, 'build', 'libc'], ['building and verifying libc', 'success'], True, ['libc.bc']),
      ([PYTHON, EMBUILDER, 'build', 'libc-mt'], ['building and verifying libc-mt', 'success'], True, ['libc-mt.bc']),
      ([PYTHON, EMBUILDER, 'build', 'libc-extras'], ['building and verifying libc-extras', 'success'], True, ['libc-extras.bc']),
      ([PYTHON, EMBUILDER, 'build', 'dlmalloc'], ['building and verifying dlmalloc', 'success'], True, ['dlmalloc.bc']),
      ([PYTHON, EMBUILDER, 'build', 'dlmalloc_debug'], ['building and verifying dlmalloc', 'success'], True, ['dlmalloc_debug.bc']),
      ([PYTHON, EMBUILDER, 'build', 'dlmalloc_threadsafe'], ['building and verifying dlmalloc_threadsafe', 'success'], True, ['dlmalloc_threadsafe.bc']),
      ([PYTHON, EMBUILDER, 'build', 'dlmalloc_threadsafe_debug'], ['building and verifying dlmalloc', 'success'], True, ['dlmalloc_threadsafe_debug.bc']),
      ([PYTHON, EMBUILDER, 'build', 'emmalloc'], ['building and verifying emmalloc', 'success'], True, ['emmalloc.bc']),
      ([PYTHON, EMBUILDER, 'build', 'emmalloc_debug'], ['building and verifying emmalloc', 'success'], True, ['emmalloc_debug.bc']),
      ([PYTHON, EMBUILDER, 'build', 'pthreads'], ['building and verifying pthreads', 'success'], True, ['pthreads.bc']),
      ([PYTHON, EMBUILDER, 'build', 'libcxx'], ['success'], True, ['libcxx.a']),
      ([PYTHON, EMBUILDER, 'build', 'libcxx_noexcept'], ['success'], True, ['libcxx_noexcept.a']),
      ([PYTHON, EMBUILDER, 'build', 'libcxxabi'], ['success'], True, ['libcxxabi.bc']),
      ([PYTHON, EMBUILDER, 'build', 'gl'], ['success'], True, ['gl.bc']),
      ([PYTHON, EMBUILDER, 'build', 'native_optimizer'], ['success'], True, ['optimizer.2.exe']),
      ([PYTHON, EMBUILDER, 'build', 'zlib'], ['building and verifying zlib', 'success'], True, ['zlib.bc']),
      ([PYTHON, EMBUILDER, 'build', 'libpng'], ['building and verifying libpng', 'success'], True, ['libpng.bc']),
      ([PYTHON, EMBUILDER, 'build', 'bullet'], ['building and verifying bullet', 'success'], True, ['bullet.bc']),
      ([PYTHON, EMBUILDER, 'build', 'vorbis'], ['building and verifying vorbis', 'success'], True, ['vorbis.bc']),
      ([PYTHON, EMBUILDER, 'build', 'ogg'], ['building and verifying ogg', 'success'], True, ['ogg.bc']),
      ([PYTHON, EMBUILDER, 'build', 'sdl2'], ['success'], True, ['sdl2.bc']),
      ([PYTHON, EMBUILDER, 'build', 'sdl2-gfx'], ['success'], True, ['sdl2-gfx.bc']),
      ([PYTHON, EMBUILDER, 'build', 'sdl2-image'], ['success'], True, ['sdl2-image.bc']),
      ([PYTHON, EMBUILDER, 'build', 'freetype'], ['building and verifying freetype', 'success'], True, ['freetype.bc']),
      ([PYTHON, EMBUILDER, 'build', 'harfbuzz'], ['building and verifying harfbuzz', 'success'], True, ['harfbuzz.bc']),
      ([PYTHON, EMBUILDER, 'build', 'icu'], ['building and verifying icu', 'success'], True, ['icu.bc']),
      ([PYTHON, EMBUILDER, 'build', 'sdl2-ttf'], ['building and verifying sdl2-ttf', 'success'], True, ['sdl2-ttf.bc']),
      ([PYTHON, EMBUILDER, 'build', 'sdl2-net'], ['building and verifying sdl2-net', 'success'], True, ['sdl2-net.bc']),
      ([PYTHON, EMBUILDER, 'build', 'binaryen'], ['building and verifying binaryen', 'success'], True, []),
      ([PYTHON, EMBUILDER, 'build', 'cocos2d'], ['building and verifying cocos2d', 'success'], True, ['libCocos2d.bc']),
      ([PYTHON, EMBUILDER, 'build', 'wasm-libc'], ['building and verifying wasm-libc', 'success'], True, ['wasm-libc.bc']),
    ]
    if Settings.WASM_BACKEND:
      tests.append(([PYTHON, EMBUILDER, 'build', 'wasm_compiler_rt'], ['building and verifying wasm_compiler_rt', 'success'], True, ['wasm_compiler_rt.a']),)

    Cache.erase()

    for command, expected, success, result_libs in tests:
      print(command)
      for lib in result_libs:
        if os.path.sep in lib:
          dirname = os.path.dirname(Cache.get_path(lib))
          print('    erase dir', dirname)
          try_delete(dirname)
        else:
          print('    erase file', lib)
          try_delete(Cache.get_path(lib))
      proc = run_process(command, stdout=PIPE, stderr=STDOUT, check=False)
      out = proc.stdout
      if success and proc.returncode != 0:
        print(out)
      assert (proc.returncode == 0) == success
      if not isinstance(expected, list):
        expected = [expected]
      for ex in expected:
        print('    seek', ex)
        assert ex in out, out
      for lib in result_libs:
        print('    verify', lib)
        assert os.path.exists(Cache.get_path(lib))
Beispiel #14
0
  def test_native_optimizer(self):
    restore_and_set_up()

    def build():
      return self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-O2', '-s', 'WASM=0'], 'running js post-opts')

    def test():
      self.assertContained('hello, world!', run_js('a.out.js'))

    with env_modify({'EMCC_DEBUG': '1'}):
      # basic usage or lack of usage
      for native in [None, 0, 1]:
        print('phase 1, part', native)
        Cache.erase()
        try:
          if native is not None:
            os.environ['EMCC_NATIVE_OPTIMIZER'] = str(native)
          output = build()
          assert ('js optimizer using native' in output) == (not not (native or native is None)), output
          test()
          if native or native is None: # None means use the default, which is to use the native optimizer
            assert 'building native optimizer' in output, output
            # compile again, no rebuild of optimizer
            output = build()
            assert 'building native optimizer' not in output
            assert 'js optimizer using native' in output
            test()
        finally:
          if native is not None:
            del os.environ['EMCC_NATIVE_OPTIMIZER']

      # force a build failure, see we fall back to non-native

      for native in [1, 'g']:
        with env_modify({'EMCC_NATIVE_OPTIMIZER': str(native)}):
          print('phase 2, part', native)
          Cache.erase()

          try:
            # break it
            f = path_from_root('tools', 'optimizer', 'optimizer-main.cpp')
            src = open(f).read()
            bad = src.replace('main', '!waka waka<')
            assert bad != src
            open(f, 'w').write(bad)
            # first try
            output = build()
            assert 'failed to build native optimizer' in output, output
            if native == 1:
              assert 'to see compiler errors, build with EMCC_NATIVE_OPTIMIZER=g' in output
              assert 'waka waka' not in output
            else:
              assert 'output from attempt' in output, output
              assert 'waka waka' in output, output
            assert 'js optimizer using native' not in output
            test() # still works, without native optimizer
            # second try, see previous failure
            output = build()
            assert 'failed to build native optimizer' not in output
            assert 'seeing that optimizer could not be built' in output
            test() # still works, without native optimizer
            # clear cache, try again
            Cache.erase()
            output = build()
            assert 'failed to build native optimizer' in output
            test() # still works, without native optimizer
          finally:
            open(f, 'w').write(src)

          Cache.erase()

          # now it should work again
          output = build()
          assert 'js optimizer using native' in output
          test() # still works

    try_delete(CANONICAL_TEMP_DIR)