| |
| |
| |
| |
|
|
| import logging |
| import os |
| import shutil |
| import sys |
|
|
| from . import diagnostics, utils |
| from .utils import __rootpath__, exit_with_error, path_from_root |
|
|
| logger = logging.getLogger('config') |
|
|
| |
| |
| |
| |
| EMSCRIPTEN_ROOT = __rootpath__ |
| NODE_JS = None |
| BINARYEN_ROOT = None |
| LLVM_ADD_VERSION = None |
| CLANG_ADD_VERSION = None |
| CLOSURE_COMPILER = None |
| FROZEN_CACHE = None |
| CACHE = None |
| PORTS = None |
| COMPILER_WRAPPER = None |
|
|
| |
| EM_CONFIG = None |
|
|
| |
| |
| NODE_JS_TEST = None |
| SPIDERMONKEY_ENGINE = None |
| V8_ENGINE: list[str] | None = None |
| LLVM_ROOT = None |
| JS_ENGINES: list[list[str]] = [] |
| WASMER = None |
| WASMTIME = None |
| WASM_ENGINES: list[list[str]] = [] |
|
|
|
|
| def listify(x): |
| if x is None or type(x) is list: |
| return x |
| return [x] |
|
|
|
|
| def fix_js_engine(old, new): |
| if old is None: |
| return |
| global JS_ENGINES |
| JS_ENGINES = [new if x == old else x for x in JS_ENGINES] |
| return new |
|
|
|
|
| def normalize_config_settings(): |
| global CACHE, PORTS, LLVM_ADD_VERSION, CLANG_ADD_VERSION, CLOSURE_COMPILER |
| global NODE_JS, NODE_JS_TEST, V8_ENGINE, JS_ENGINES, SPIDERMONKEY_ENGINE, WASM_ENGINES |
|
|
| SPIDERMONKEY_ENGINE = fix_js_engine(SPIDERMONKEY_ENGINE, listify(SPIDERMONKEY_ENGINE)) |
| NODE_JS = fix_js_engine(NODE_JS, listify(NODE_JS)) |
| NODE_JS_TEST = fix_js_engine(NODE_JS_TEST, listify(NODE_JS_TEST)) |
| V8_ENGINE = fix_js_engine(V8_ENGINE, listify(V8_ENGINE)) |
| JS_ENGINES = [listify(engine) for engine in JS_ENGINES] |
| WASM_ENGINES = [listify(engine) for engine in WASM_ENGINES] |
| CLOSURE_COMPILER = listify(CLOSURE_COMPILER) |
| if not CACHE: |
| CACHE = path_from_root('cache') |
| if not PORTS: |
| PORTS = os.path.join(CACHE, 'ports') |
|
|
|
|
| def normalize_relative_python_path(): |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| if os.environ.get('EMSDK_PYTHON'): |
| os.environ['EMSDK_PYTHON'] = sys.executable |
|
|
|
|
| def set_config_from_tool_location(config_key, tool_binary, f): |
| val = globals()[config_key] |
| if val is None: |
| path = shutil.which(tool_binary) |
| if not path: |
| if not os.path.isfile(EM_CONFIG): |
| diagnostics.warn('config file not found: %s. You can create one by hand or run `emcc --generate-config`', EM_CONFIG) |
| exit_with_error('%s not set in config (%s), and `%s` not found in PATH', config_key, EM_CONFIG, tool_binary) |
| globals()[config_key] = f(path) |
| elif not val: |
| exit_with_error('%s is set to empty value in %s', config_key, EM_CONFIG) |
|
|
|
|
| def parse_config_file(): |
| """Parse the emscripten config file using python's exec. |
| |
| Also check EM_<KEY> environment variables to override specific config keys. |
| """ |
| config = {'__file__': EM_CONFIG} |
| config_text = utils.read_file(EM_CONFIG) |
| try: |
| exec(config_text, config) |
| except Exception as e: |
| exit_with_error('error in evaluating config file (%s): %s, text: %s', EM_CONFIG, e, config_text) |
|
|
| CONFIG_KEYS = ( |
| 'NODE_JS', |
| 'NODE_JS_TEST', |
| 'BINARYEN_ROOT', |
| 'SPIDERMONKEY_ENGINE', |
| 'V8_ENGINE', |
| 'LLVM_ROOT', |
| 'LLVM_ADD_VERSION', |
| 'CLANG_ADD_VERSION', |
| 'CLOSURE_COMPILER', |
| 'JS_ENGINES', |
| 'WASMER', |
| 'WASMTIME', |
| 'WASM_ENGINES', |
| 'FROZEN_CACHE', |
| 'CACHE', |
| 'PORTS', |
| 'COMPILER_WRAPPER', |
| ) |
|
|
| |
| for key in CONFIG_KEYS: |
| env_var = 'EM_' + key |
| env_value = os.environ.get(env_var) |
| if env_value is not None: |
| if env_value in {'', '0'}: |
| env_value = None |
| |
| if env_var in {'EM_JS_ENGINES', 'EM_WASM_ENGINES'}: |
| env_value = env_value.split(',') |
| if env_var in {'EM_CONFIG', 'EM_CACHE', 'EM_PORTS', 'EM_LLVM_ROOT', 'EM_BINARYEN_ROOT'}: |
| if not os.path.isabs(env_value): |
| exit_with_error(f'environment variable {env_var} must be an absolute path: {env_value}') |
| globals()[key] = env_value |
| elif key in config: |
| globals()[key] = config[key] |
|
|
|
|
| def read_config(): |
| if os.path.isfile(EM_CONFIG): |
| parse_config_file() |
|
|
| |
| |
| LEGACY_ENV_VARS = { |
| 'LLVM': 'EM_LLVM_ROOT', |
| 'BINARYEN': 'EM_BINARYEN_ROOT', |
| 'NODE': 'EM_NODE_JS', |
| 'LLVM_ADD_VERSION': 'EM_LLVM_ADD_VERSION', |
| 'CLANG_ADD_VERSION': 'EM_CLANG_ADD_VERSION', |
| } |
|
|
| for key, new_key in LEGACY_ENV_VARS.items(): |
| env_value = os.environ.get(key) |
| if env_value and new_key not in os.environ: |
| msg = f'legacy environment variable found: `{key}`. Please switch to using `{new_key}` instead`' |
| |
| |
| |
| if key == 'NODE': |
| logger.debug(msg) |
| else: |
| logger.warning(msg) |
|
|
| set_config_from_tool_location('LLVM_ROOT', 'clang', os.path.dirname) |
| set_config_from_tool_location('NODE_JS', 'node', lambda x: x) |
| set_config_from_tool_location('BINARYEN_ROOT', 'wasm-opt', lambda x: os.path.dirname(os.path.dirname(x))) |
|
|
| normalize_config_settings() |
| normalize_relative_python_path() |
|
|
|
|
| def generate_config(path): |
| if os.path.exists(path): |
| exit_with_error(f'config file already exists: `{path}`') |
|
|
| |
| |
|
|
| config_data = utils.read_file(path_from_root('tools/config_template.py')) |
| config_data = config_data.splitlines()[3:] |
| config_data = '\n'.join(config_data) + '\n' |
| |
| llvm_root = os.path.dirname(shutil.which('wasm-ld') or '/usr/bin/wasm-ld') |
| config_data = config_data.replace('\'{{{ LLVM_ROOT }}}\'', repr(llvm_root)) |
|
|
| binaryen_root = os.path.dirname(os.path.dirname(shutil.which('wasm-opt') or '/usr/local/bin/wasm-opt')) |
| config_data = config_data.replace('\'{{{ BINARYEN_ROOT }}}\'', repr(binaryen_root)) |
|
|
| node = shutil.which('node') or shutil.which('nodejs') or 'node' |
| config_data = config_data.replace('\'{{{ NODE }}}\'', repr(node)) |
|
|
| |
| utils.write_file(path, config_data) |
|
|
| print('''\ |
| An Emscripten settings file has been generated at: |
| |
| %s |
| |
| It contains our best guesses for the important paths, which are: |
| |
| LLVM_ROOT = %s |
| BINARYEN_ROOT = %s |
| NODE_JS = %s |
| |
| Please edit the file if any of those are incorrect.\ |
| ''' % (path, llvm_root, binaryen_root, node), file=sys.stderr) |
|
|
|
|
| def find_config_file(): |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| if '--em-config' in sys.argv: |
| i = sys.argv.index('--em-config') |
| if len(sys.argv) <= i + 1: |
| exit_with_error('--em-config must be followed by a filename') |
| del sys.argv[i] |
| |
| return sys.argv.pop(i) |
|
|
| if 'EM_CONFIG' in os.environ: |
| return os.environ['EM_CONFIG'] |
|
|
| embedded_config = path_from_root('.emscripten') |
| if os.path.isfile(embedded_config): |
| return embedded_config |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| emsdk_root = os.path.dirname(os.path.dirname(path_from_root())) |
| emsdk_embedded_config = os.path.join(emsdk_root, '.emscripten') |
|
|
| if os.path.isfile(emsdk_embedded_config): |
| return emsdk_embedded_config |
|
|
| user_home_config = os.path.expanduser('~/.emscripten') |
| if os.path.isfile(user_home_config): |
| return user_home_config |
|
|
| return embedded_config |
|
|
|
|
| def init(): |
| global EM_CONFIG |
| EM_CONFIG = find_config_file() |
|
|
| |
| if '\n' in EM_CONFIG: |
| exit_with_error('inline EM_CONFIG data no longer supported. Please use a config file.') |
|
|
| EM_CONFIG = os.path.expanduser(EM_CONFIG) |
|
|
| |
| |
| |
| if '--generate-config' in sys.argv: |
| generate_config(EM_CONFIG) |
| sys.exit(0) |
|
|
| if os.path.isfile(EM_CONFIG): |
| logger.debug(f'using config file: {EM_CONFIG}') |
| else: |
| logger.debug('config file not found; using default config') |
|
|
| |
| |
| |
| os.environ['EM_CONFIG'] = EM_CONFIG |
|
|
| read_config() |
|
|
|
|
| init() |
|
|