LOCAL_SETUP_MARKER = b"# Generated by Platforms/wasm/emscripten.py\n"
+@functools.cache
def validate_emsdk_version(emsdk_cache):
"""Validate that the emsdk cache contains the required emscripten version."""
if emsdk_cache is None:
+ print("Build will use EMSDK from current environment.")
return
required_version = required_emscripten_version()
emsdk_env = emsdk_activate_path(emsdk_cache)
@subdir("host_dir")
def make_emscripten_python(context, working_dir):
"""Run `make` for the emscripten/host build."""
- validate_emsdk_version(context.emsdk_cache)
call(
["make", "--jobs", str(cpu_count()), "all"],
env=updated_env({}, context.emsdk_cache),
subprocess.check_call([exec_script, "--version"])
+def run_emscripten_python(context):
+ """Run the built emscripten Python."""
+ host_dir = context.build_paths["host_dir"]
+ exec_script = host_dir / "python.sh"
+ if not exec_script.is_file():
+ print("Emscripten not built", file=sys.stderr)
+ sys.exit(1)
+
+ args = context.args
+ # Strip the "--" separator if present
+ if args and args[0] == "--":
+ args = args[1:]
+
+ os.execv(str(exec_script), [str(exec_script)] + args)
+
+
def build_target(context):
"""Build one or more targets."""
steps = []
print(f"🧹 Deleting generated {LOCAL_SETUP} ...")
+def add_cross_build_dir_option(subcommand):
+ subcommand.add_argument(
+ "--cross-build-dir",
+ action="store",
+ default=os.environ.get("CROSS_BUILD_DIR"),
+ dest="cross_build_dir",
+ help=(
+ "Path to the cross-build directory "
+ f"(default: {DEFAULT_CROSS_BUILD_DIR}). "
+ "Can also be set with the CROSS_BUILD_DIR environment variable.",
+ ),
+ )
+
+
def main():
default_host_runner = "node"
parser = argparse.ArgumentParser()
subcommands = parser.add_subparsers(dest="subcommand")
+
install_emscripten_cmd = subcommands.add_parser(
"install-emscripten",
help="Install the appropriate version of Emscripten",
)
+
build = subcommands.add_parser("build", help="Build everything")
build.add_argument(
"target",
configure_build = subcommands.add_parser(
"configure-build-python", help="Run `configure` for the build Python"
)
+
make_mpdec_cmd = subcommands.add_parser(
"make-mpdec",
help="Clone mpdec repo, configure and build it for emscripten",
)
+
make_libffi_cmd = subcommands.add_parser(
"make-libffi",
help="Clone libffi repo, configure and build it for emscripten",
)
+
make_build = subcommands.add_parser(
"make-build-python", help="Run `make` for the build Python"
)
+
configure_host = subcommands.add_parser(
"configure-host",
- help="Run `configure` for the host/emscripten (pydebug builds are inferred from the build Python)",
+ help=(
+ "Run `configure` for the host/emscripten "
+ "(pydebug builds are inferred from the build Python)"
+ ),
)
+
make_host = subcommands.add_parser(
"make-host", help="Run `make` for the host/emscripten"
)
+
+ run = subcommands.add_parser(
+ "run",
+ help="Run the built emscripten Python",
+ )
+ run.add_argument(
+ "args",
+ nargs=argparse.REMAINDER,
+ help=(
+ "Arguments to pass to the emscripten Python "
+ "(use '--' to separate from run options)",
+ )
+ )
+ add_cross_build_dir_option(run)
clean = subcommands.add_parser(
"clean", help="Delete files and directories created by this script"
)
subcommand.add_argument(
"--quiet",
action="store_true",
- default=False,
+ default="QUIET" in os.environ,
dest="quiet",
- help="Redirect output from subprocesses to a log file",
- )
- subcommand.add_argument(
- "--cross-build-dir",
- action="store",
- default=None,
- dest="cross_build_dir",
- help="Path to the cross-build directory "
- f"(default: {DEFAULT_CROSS_BUILD_DIR})",
+ help=(
+ "Redirect output from subprocesses to a log file. "
+ "Can also be set with the QUIET environment variable."
+ ),
)
+ add_cross_build_dir_option(subcommand)
subcommand.add_argument(
"--emsdk-cache",
action="store",
- default=None,
+ default=os.environ.get("EMSDK_CACHE"),
dest="emsdk_cache",
- help="Path to emsdk cache directory. If provided, validates that "
- "the required emscripten version is installed.",
+ help=(
+ "Path to emsdk cache directory. If provided, validates that "
+ "the required emscripten version is installed. "
+ "Can also be set with the EMSDK_CACHE environment variable."
+ ),
)
+
for subcommand in configure_build, configure_host:
subcommand.add_argument(
"--clean",
dest="clean",
help="Delete any relevant directories before building",
)
+
for subcommand in build, configure_build, configure_host:
subcommand.add_argument(
"args", nargs="*", help="Extra arguments to pass to `configure`"
)
+
for subcommand in build, configure_host:
subcommand.add_argument(
"--host-runner",
if context.emsdk_cache:
context.emsdk_cache = Path(context.emsdk_cache).absolute()
- else:
- print("Build will use EMSDK from current environment.")
context.build_paths = get_build_paths(
context.cross_build_dir, context.emsdk_cache
"configure-host": configure_emscripten_python,
"make-host": make_emscripten_python,
"build": build_target,
+ "run": run_emscripten_python,
"clean": clean_contents,
}