| Index: sky/tools/mojo_cache_linker.py
|
| diff --git a/sky/tools/mojo_cache_linker.py b/sky/tools/mojo_cache_linker.py
|
| index 4636c9b943c8b67e6bf4bedfebc3de4d7285cb42..10685af6fa7121400bab8f763e4812d24b06f7af 100755
|
| --- a/sky/tools/mojo_cache_linker.py
|
| +++ b/sky/tools/mojo_cache_linker.py
|
| @@ -8,10 +8,71 @@ import logging
|
| import os
|
| import sys
|
| import subprocess
|
| +import json
|
| +
|
| +
|
| +def library_paths(build_dir):
|
| + for name in os.listdir(build_dir):
|
| + path = os.path.realpath(os.path.join(build_dir, name))
|
| + if not os.path.isfile(path):
|
| + continue
|
| +
|
| + # Only include suffixes we care about:
|
| + basename, ext = os.path.splitext(name)
|
| + if ext not in ('', '.mojo', '.so'):
|
| + continue
|
| +
|
| + # Ignore ninja's dot-files.
|
| + if basename.startswith('.'):
|
| + continue
|
| + yield path
|
| +
|
| +
|
| +def get_cached_app_id(path, cache, cache_mtime):
|
| + if not cache_mtime:
|
| + return None
|
| + try:
|
| + if os.path.getmtime(path) > cache_mtime:
|
| + return None
|
| + except:
|
| + return None
|
| + return cache.get(path)
|
| +
|
| +
|
| +def compute_path_to_app_id_map(paths, cache, cache_mtime):
|
| + path_to_app_id_map = {}
|
| + for path in paths:
|
| + app_id = get_cached_app_id(path, cache, cache_mtime)
|
| + if not app_id:
|
| + logging.info('md5sum %s' % path)
|
| + # Example output:
|
| + # f82a3551478a9a0e010adccd675053b9 png_viewer.mojo
|
| + output = subprocess.check_output(['md5sum', path])
|
| + app_id = output.strip().split()[0]
|
| + path_to_app_id_map[path] = app_id
|
| + return path_to_app_id_map
|
| +
|
| +
|
| +def read_app_id_cache(cache_path):
|
| + try:
|
| + with open(cache_path, 'r') as cache_file:
|
| + return json.load(cache_file), os.path.getmtime(cache_path)
|
| + except:
|
| + logging.warn('Failed to read file: %s' % cache_path)
|
| + return {}, None
|
| +
|
| +
|
| +def write_app_id_cache(cache_path, cache):
|
| + try:
|
| + with open(cache_path, 'w') as cache_file:
|
| + json.dump(cache, cache_file, indent=2, sort_keys=True)
|
| + except:
|
| + logging.warn('Failed to write file: %s' % cache_path)
|
| +
|
|
|
| # TODO(eseidel): Share logic with tools/android_stack_parser/stack
|
| def main():
|
| - logging.basicConfig(level=logging.INFO)
|
| + logging.basicConfig(level=logging.WARN)
|
| parser = argparse.ArgumentParser(
|
| description='Builds a directory of app_id symlinks to symbols'
|
| ' to match expected dlopen names from mojo_shell\'s NetworkLoader.')
|
| @@ -23,42 +84,39 @@ def main():
|
| logging.fatal('links_dir: %s is not a directory' % args.links_dir)
|
| sys.exit(1)
|
|
|
| - for name in os.listdir(args.build_dir):
|
| - path = os.path.join(args.build_dir, name)
|
| - if not os.path.isfile(path):
|
| - continue
|
| -
|
| - # md5sum is slow, so only bother for suffixes we care about:
|
| - basename, ext = os.path.splitext(name)
|
| - if ext not in ('', '.mojo', '.so'):
|
| - continue
|
| + # Some of the .so files are 100s of megabytes. Cache the md5s to save time.
|
| + cache_path = os.path.join(args.build_dir, '.app_id_cache')
|
| + cache, cache_mtime = read_app_id_cache(cache_path)
|
|
|
| - # Ignore ninja's dot-files.
|
| - if basename.startswith('.'):
|
| - continue
|
| + paths = library_paths(args.build_dir)
|
| + path_to_app_id_map = compute_path_to_app_id_map(list(paths),
|
| + cache, cache_mtime)
|
|
|
| - # Example output:
|
| - # f82a3551478a9a0e010adccd675053b9 png_viewer.mojo
|
| - md5 = subprocess.check_output(['md5sum', path]).strip().split()[0]
|
| - link_path = os.path.join(args.links_dir, '%s.mojo' % md5)
|
| + # The cache contains unmodified app-ids.
|
| + write_app_id_cache(cache_path, path_to_app_id_map)
|
|
|
| - lib_path = os.path.realpath(os.path.join(args.build_dir, name))
|
| + for path, app_id in path_to_app_id_map.items():
|
| + basename = os.path.basename(path)
|
| + root_name, ext = os.path.splitext(basename)
|
|
|
| # On android foo.mojo is stripped, but libfoo_library.so is not.
|
| if ext == '.mojo':
|
| - symboled_name = 'lib%s_library.so' % basename
|
| + symboled_name = 'lib%s_library.so' % root_name
|
| symboled_path = os.path.realpath(
|
| os.path.join(args.build_dir, symboled_name))
|
| if os.path.exists(symboled_path):
|
| - lib_path = symboled_path
|
| + path = symboled_path
|
|
|
| - print "%s -> %s" % (link_path, lib_path)
|
| + link_path = os.path.join(args.links_dir, '%s.mojo' % app_id)
|
| +
|
| + logging.info("%s -> %s" % (link_path, path))
|
|
|
| if os.path.lexists(link_path):
|
| - logging.debug('link already exists %s, replacing' % lib_path)
|
| + logging.debug('link already exists %s, replacing' % path)
|
| os.unlink(link_path)
|
|
|
| - os.symlink(lib_path, link_path)
|
| + os.symlink(path, link_path)
|
| +
|
|
|
| if __name__ == '__main__':
|
| main()
|
|
|