Example #1
0
 def install_headers(src_dir, pattern='*.h', target=None):
     logger.debug('install_headers')
     dest = Ports.get_include_dir()
     if target:
         dest = os.path.join(dest, target)
         shared.safe_ensure_dirs(dest)
     matches = glob.glob(os.path.join(src_dir, pattern))
     assert matches, f'no headers found to install in {src_dir}'
     for f in matches:
         logger.debug('installing: ' +
                      os.path.join(dest, os.path.basename(f)))
         shutil.copyfile(f, os.path.join(dest, os.path.basename(f)))
Example #2
0
def main():
    parser = argparse.ArgumentParser(description=__doc__,
                                     usage="%(prog)s [options] [files ...]")
    parser.add_argument('files',
                        metavar='files',
                        type=str,
                        nargs='*',
                        help='symbol files to regenerate (default: all)')
    args = parser.parse_args()

    if not shared.Settings.WASM:
        sys.stderr.write('This script only runs in WASM mode\n')
        sys.exit(1)

    shared.safe_ensure_dirs(get_symbols_dir())
    if args.files:
        for symbol_file in args.files:
            if not is_symbol_file_supported(symbol_file):
                print('skipping %s because it is not supported' % symbol_file)
                continue
            lib_file = get_lib_file(symbol_file)
            if not os.path.exists(lib_file):
                print('skipping %s because %s does not exist' %
                      (symbol_file, lib_file))
                continue
            generate_symbol_file(symbol_file, lib_file)
    else:
        # Build all combinations of libraries and generate symbols files
        system_libs = Library.get_all_variations()
        for lib in system_libs.values():
            if lib.name not in target_libs:
                continue
            lib_file = lib.get_path()
            symbol_file = get_symbol_file(lib_file)
            generate_symbol_file(symbol_file, lib_file)

        # Not to generate too many symbols files with the same contents, if there
        # exists a default symbols file (that has a library name without any
        # suffices, such as -mt) and its contents are the same as another symbols
        # file with suffices, remove it.
        for lib in system_libs.values():
            if lib.name not in target_libs:
                continue
            lib_file = lib.get_path()
            symbol_file = get_symbol_file(lib_file)
            default_symbol_file = os.path.join(get_symbols_dir(),
                                               lib.name + '.symbols')
            if symbol_file != default_symbol_file and \
               os.path.isfile(default_symbol_file) and \
               filecmp.cmp(default_symbol_file, symbol_file):
                os.unlink(symbol_file)
    return 0
Example #3
0
    def handle_static_lib(self, f):
        temp_dir = tempfile.mkdtemp('_archive_contents', 'emscripten_temp_')
        with chdir(temp_dir):
            contents = [
                x for x in run_process([CHEERP_BIN + 'llvm-ar', 't', f],
                                       stdout=PIPE).stdout.splitlines()
                if len(x)
            ]
            shared.warn_if_duplicate_entries(contents, f)
            if len(contents) == 0:
                print(
                    'Archive %s appears to be empty (recommendation: link an .so instead of .a)'
                    % f)
                return {'returncode': 0, 'dir': temp_dir, 'files': []}

            # We are about to ask llvm-ar to extract all the files in the .a archive file, but
            # it will silently fail if the directory for the file does not exist, so make all the necessary directories
            for content in contents:
                dirname = os.path.dirname(content)
                if dirname:
                    shared.safe_ensure_dirs(dirname)
            proc = run_process([CHEERP_BIN + 'llvm-ar', 'xo', f],
                               stdout=PIPE,
                               stderr=PIPE)
            # if absolute paths, files will appear there. otherwise, in this directory
            contents = list(map(os.path.abspath, contents))
            nonexisting_contents = [
                x for x in contents if not os.path.exists(x)
            ]
            if len(nonexisting_contents) != 0:
                raise Exception('llvm-ar failed to extract file(s) ' +
                                str(nonexisting_contents) +
                                ' from archive file ' + f + '!  Error:' +
                                str(proc.stdout) + str(proc.stderr))

            return {
                'returncode': proc.returncode,
                'dir': temp_dir,
                'files': contents
            }

        return {'returncode': 1, 'dir': None, 'files': []}
Example #4
0
  def handle_static_lib(self, f):
    temp_dir = tempfile.mkdtemp('_archive_contents', 'emscripten_temp_')
    with chdir(temp_dir):
      contents = [x for x in run_process([CHEERP_BIN + 'llvm-ar', 't', f], stdout=PIPE).stdout.splitlines() if len(x)]
      shared.warn_if_duplicate_entries(contents, f)
      if len(contents) == 0:
        print('Archive %s appears to be empty (recommendation: link an .so instead of .a)' % f)
        return {
          'returncode': 0,
          'dir': temp_dir,
          'files': []
        }

      # We are about to ask llvm-ar to extract all the files in the .a archive file, but
      # it will silently fail if the directory for the file does not exist, so make all the necessary directories
      for content in contents:
        dirname = os.path.dirname(content)
        if dirname:
          shared.safe_ensure_dirs(dirname)
      proc = run_process([CHEERP_BIN + 'llvm-ar', 'xo', f], stdout=PIPE, stderr=PIPE)
      # if absolute paths, files will appear there. otherwise, in this directory
      contents = list(map(os.path.abspath, contents))
      nonexisting_contents = [x for x in contents if not os.path.exists(x)]
      if len(nonexisting_contents) != 0:
        raise Exception('llvm-ar failed to extract file(s) ' + str(nonexisting_contents) + ' from archive file ' + f + '!  Error:' + str(proc.stdout) + str(proc.stderr))

      return {
        'returncode': proc.returncode,
        'dir': temp_dir,
        'files': contents
      }

    return {
      'returncode': 1,
      'dir': None,
      'files': []
    }
Example #5
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'))
Example #6
0
 def get_include_dir(*parts):
     dirname = shared.Cache.get_include_dir(*parts)
     shared.safe_ensure_dirs(dirname)
     return dirname
Example #7
0
 def unpack():
     logger.info(f'unpacking port: {name}')
     shared.safe_ensure_dirs(fullname)
     shutil.unpack_archive(filename=fullpath, extract_dir=fullname)
     utils.write_file(marker, url + '\n')
Example #8
0
 def get_dir():
     dirname = config.PORTS
     shared.safe_ensure_dirs(dirname)
     return dirname
Example #9
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'))