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)))
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
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': []}
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': [] }
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'))
def get_include_dir(*parts): dirname = shared.Cache.get_include_dir(*parts) shared.safe_ensure_dirs(dirname) return dirname
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')
def get_dir(): dirname = config.PORTS shared.safe_ensure_dirs(dirname) return dirname
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'))