Ejemplo n.º 1
0
    def test_llvm_fastcomp(self):
        WARNING = 'fastcomp in use, but LLVM has not been built with the JavaScript backend as a target'

        restore_and_set_up()

        # Should see js backend during sanity check
        self.assertTrue(shared.check_llvm())
        output = self.check_working(EMCC)
        self.assertNotIn(WARNING, output)

        # Fake incorrect llc output, no mention of js backend
        restore_and_set_up()
        with open(CONFIG_FILE, 'a') as f:
            f.write('LLVM_ROOT = "' + self.in_dir('fake', 'bin') + '"')
        # print '1', open(CONFIG_FILE).read()

        make_fake_clang(self.in_dir('fake', 'bin', 'clang'),
                        expected_llvm_version())
        make_fake_llc(self.in_dir('fake', 'bin', 'llc'),
                      'no j-s backend for you!')
        self.check_working(EMCC, WARNING)

        # fake some more
        for fake in [
                'llvm-link', 'llvm-ar', 'opt', 'llvm-as', 'llvm-dis',
                'llvm-nm', 'lli'
        ]:
            open(self.in_dir('fake', 'bin', fake), 'w').write('.')
        try_delete(SANITY_FILE)
        self.check_working(EMCC, WARNING)
Ejemplo n.º 2
0
    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'))
Ejemplo n.º 3
0
 def test_cache_clearing_auto(self):
   # Changing LLVM_ROOT, even without altering .emscripten, clears the cache
   restore_and_set_up()
   self.ensure_cache()
   make_fake_clang(self.in_dir('fake', 'bin', 'clang'), expected_llvm_version())
   make_fake_llc(self.in_dir('fake', 'bin', 'llc'), 'got wasm32 backend! WebAssembly 32-bit')
   with env_modify({'EM_LLVM_ROOT': self.in_dir('fake', 'bin')}):
     self.assertTrue(os.path.exists(Cache.dirname))
     output = self.do([EMCC])
     self.assertIn('clearing cache', output)
     self.assertCacheEmpty()
Ejemplo n.º 4
0
  def test_llvm(self):
    LLVM_WARNING = 'LLVM version appears incorrect'

    restore_and_set_up()

    # Clang should report the version number we expect, and emcc should not warn
    assert shared.check_clang_version()
    output = self.check_working(EMCC)
    assert LLVM_WARNING not in output, output

    # Fake a different llvm version
    restore_and_set_up()
    with open(CONFIG_FILE, 'a') as f:
      f.write('LLVM_ROOT = "' + path_from_root('tests', 'fake') + '"')

    if not os.path.exists(path_from_root('tests', 'fake')):
      os.makedirs(path_from_root('tests', 'fake'))

    with env_modify({'EM_IGNORE_SANITY': '1'}):
      for x in range(-2, 3):
        for y in range(-2, 3):
          f = open(path_from_root('tests', 'fake', 'clang'), 'w')
          f.write('#!/bin/sh\n')
          expected_x, expected_y = (int(x) for x in expected_llvm_version().split('.'))
          expected_x += x
          expected_y += y
          if expected_x < 0 or expected_y < 0:
            continue # must be a valid llvm version
          print(expected_llvm_version(), x, y, expected_x, expected_y)
          f.write('echo "clang version %d.%d" 1>&2\n' % (expected_x, expected_y))
          f.close()
          shutil.copyfile(path_from_root('tests', 'fake', 'clang'), path_from_root('tests', 'fake', 'clang++'))
          os.chmod(path_from_root('tests', 'fake', 'clang'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
          os.chmod(path_from_root('tests', 'fake', 'clang++'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
          if x != 0 or y != 0:
            output = self.check_working(EMCC, LLVM_WARNING)
          else:
            output = self.check_working(EMCC)
            assert LLVM_WARNING not in output, output
Ejemplo n.º 5
0
    def test_emcc_caching(self):
        BUILDING_MESSAGE = 'generating system library: X'
        ERASING_MESSAGE = 'clearing cache'

        restore_and_set_up()
        self.erase_cache()

        # Building a file that *does* need something *should* trigger cache
        # generation, but only the first time
        libname = 'libc++'
        for i in range(3):
            print(i)
            self.clear()
            output = self.do([
                EMCC, '-O' + str(i), '-s', '--llvm-lto', '0',
                path_from_root('tests', 'hello_libcxx.cpp'), '--save-bc',
                'a.bc', '-s', 'DISABLE_EXCEPTION_CATCHING=0'
            ])
            print('\n\n\n', output)
            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'))
            self.assertExists(Cache.dirname)
            full_libname = libname + '.bc' if libname != 'libc++' else libname + '.a'
            self.assertExists(os.path.join(Cache.dirname, full_libname))

        restore_and_set_up()

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

        # Changing LLVM_ROOT, even without altering .emscripten, clears the cache
        self.ensure_cache()
        make_fake_clang(path_from_root('tests', 'fake', 'bin', 'clang'),
                        expected_llvm_version())
        make_fake_llc(path_from_root('tests', 'fake', 'bin', 'llc'),
                      'js - JavaScript (asm.js, emscripten)')
        with env_modify({'LLVM': path_from_root('tests', 'fake', 'bin')}):
            self.assertTrue(os.path.exists(Cache.dirname))
            output = self.do([PYTHON, EMCC])
            self.assertIn(ERASING_MESSAGE, output)
            self.assertFalse(os.path.exists(Cache.dirname))
Ejemplo n.º 6
0
    def test_llvm(self):
        LLVM_WARNING = 'LLVM version appears incorrect'

        restore_and_set_up()

        # Clang should report the version number we expect, and emcc should not warn
        assert shared.check_llvm_version()
        output = self.check_working(EMCC)
        self.assertNotContained(LLVM_WARNING, output)

        # Fake a different llvm version
        restore_and_set_up()
        with open(CONFIG_FILE, 'a') as f:
            f.write('LLVM_ROOT = "' + self.in_dir('fake') + '"')

        real_version_x, real_version_y = (
            int(x) for x in expected_llvm_version().split('.'))
        if shared.get_llvm_target() == shared.WASM_TARGET:
            make_fake_llc(self.in_dir('fake', 'llc'),
                          'wasm32 - WebAssembly 32-bit')
            make_fake_lld(self.in_dir('fake', 'wasm-ld'))
        else:
            make_fake_llc(self.in_dir('fake', 'llc'),
                          'js - JavaScript (asm.js, emscripten)')

        with env_modify({'EM_IGNORE_SANITY': '1'}):
            for inc_x in range(-2, 3):
                for inc_y in range(-2, 3):
                    expected_x = real_version_x + inc_x
                    expected_y = real_version_y + inc_y
                    if expected_x < 0 or expected_y < 0:
                        continue  # must be a valid llvm version
                    print("mod LLVM version: %d %d -> %d %d" %
                          (real_version_x, real_version_x, expected_x,
                           expected_y))
                    make_fake_clang(self.in_dir('fake', 'clang'),
                                    '%s.%s' % (expected_x, expected_y))
                    did_modify = inc_x != 0 or inc_y != 0
                    if did_modify:
                        output = self.check_working(EMCC, LLVM_WARNING)
                    else:
                        output = self.check_working(EMCC)
                        self.assertNotContained(LLVM_WARNING, output)
Ejemplo n.º 7
0
  def test_llvm_fastcomp(self):
    WARNING = 'fastcomp in use, but LLVM has not been built with the JavaScript backend as a target'
    WARNING2 = 'you can fall back to the older (pre-fastcomp) compiler core, although that is not recommended, see http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html'

    restore_and_set_up()

    # Should see js backend during sanity check
    assert shared.check_fastcomp()
    output = self.check_working(EMCC)
    self.assertNotIn(WARNING, output)
    self.assertNotIn(WARNING2, output)

    # Fake incorrect llc output, no mention of js backend
    restore_and_set_up()
    with open(CONFIG_FILE, 'a') as f:
      f.write('LLVM_ROOT = "' + path_from_root('tests', 'fake', 'bin') + '"')
    # print '1', open(CONFIG_FILE).read()

    try_delete(path_from_root('tests', 'fake'))
    os.makedirs(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:\nno j-s backend for you!"')
    os.chmod(path_from_root('tests', 'fake', 'bin', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
    output = self.check_working(EMCC, WARNING)
    output = self.check_working(EMCC, WARNING2)

    # fake some more
    for fake in ['llvm-link', 'clang', 'clang++', 'llvm-ar', 'opt', 'llvm-as', 'llvm-dis', 'llvm-nm', 'lli']:
      open(path_from_root('tests', 'fake', 'bin', fake), 'w').write('.')
    try_delete(SANITY_FILE)
    output = self.check_working(EMCC, WARNING)
    # make sure sanity checks notice there is no source dir with version #
    open(path_from_root('tests', 'fake', 'bin', 'llc'), 'w').write('#!/bin/sh\necho "Registered Targets: there IZ a js backend: JavaScript (asm.js, emscripten) backend"')
    open(path_from_root('tests', 'fake', 'bin', 'clang++'), 'w').write('#!/bin/sh\necho "clang version %s (blah blah)" >&2\necho "..." >&2\n' % expected_llvm_version())
    os.chmod(path_from_root('tests', 'fake', 'bin', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
    os.chmod(path_from_root('tests', 'fake', 'bin', 'clang++'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
    try_delete(SANITY_FILE)
    output = self.check_working(EMCC, 'did not see a source tree above or next to the LLVM root directory')

    VERSION_WARNING = 'Emscripten, llvm and clang repo versions do not match, this is dangerous'
    BUILD_VERSION_WARNING = 'Emscripten, llvm and clang build versions do not match, this is dangerous'

    # add version number
    open(path_from_root('tests', 'fake', 'emscripten-version.txt'), 'w').write('waka')
    try_delete(SANITY_FILE)
    output = self.check_working(EMCC, VERSION_WARNING)

    os.makedirs(path_from_root('tests', 'fake', 'tools', 'clang'))

    open(path_from_root('tests', 'fake', 'tools', 'clang', 'emscripten-version.txt'), 'w').write(EMSCRIPTEN_VERSION)
    try_delete(SANITY_FILE)
    output = self.check_working(EMCC, VERSION_WARNING)

    open(path_from_root('tests', 'fake', 'emscripten-version.txt'), 'w').write(EMSCRIPTEN_VERSION)
    try_delete(SANITY_FILE)
    output = self.check_working(EMCC)
    self.assertNotIn(VERSION_WARNING, output)

    open(path_from_root('tests', 'fake', 'tools', 'clang', 'emscripten-version.txt'), 'w').write('waka')
    try_delete(SANITY_FILE)
    output = self.check_working(EMCC, VERSION_WARNING)

    # restore clang version to ok, and fake the *build* versions
    open(path_from_root('tests', 'fake', 'tools', 'clang', 'emscripten-version.txt'), 'w').write(EMSCRIPTEN_VERSION)
    output = self.check_working(EMCC)
    self.assertNotIn(VERSION_WARNING, output)
    fake = '#!/bin/sh\necho "clang version %s (blah blah) (emscripten waka : waka)"\necho "..."\n' % expected_llvm_version()
    open(path_from_root('tests', 'fake', 'bin', 'clang'), 'w').write(fake)
    open(path_from_root('tests', 'fake', 'bin', 'clang++'), 'w').write(fake)
    os.chmod(path_from_root('tests', 'fake', 'bin', 'clang'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
    os.chmod(path_from_root('tests', 'fake', 'bin', 'clang++'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
    try_delete(SANITY_FILE)
    output = self.check_working(EMCC, BUILD_VERSION_WARNING)
    self.assertNotIn(VERSION_WARNING, output)
    # break clang repo version again, see it hides the build warning
    open(path_from_root('tests', 'fake', 'tools', 'clang', 'emscripten-version.txt'), 'w').write('waka')
    output = self.check_working(EMCC, VERSION_WARNING)
    self.assertNotIn(BUILD_VERSION_WARNING, output)

    restore_and_set_up()

    self.check_working([EMCC] + MINIMAL_HELLO_WORLD + ['-s', 'ASM_JS=0'], '''Compiler settings are incompatible with fastcomp. You can fall back to the older compiler core, although that is not recommended''')