Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 73 additions & 17 deletions Platforms/emscripten/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ def get_build_paths(cross_build_dir=None, emsdk_cache=None):
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)
Expand Down Expand Up @@ -530,7 +532,6 @@ def configure_emscripten_python(context, working_dir):
@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),
Expand All @@ -541,6 +542,22 @@ def make_emscripten_python(context, working_dir):
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 = []
Expand Down Expand Up @@ -581,15 +598,31 @@ def clean_contents(context):
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",
Expand All @@ -605,24 +638,46 @@ def main():
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"
)
Expand Down Expand Up @@ -651,26 +706,26 @@ def main():
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",
Expand All @@ -679,10 +734,12 @@ def main():
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",
Expand All @@ -699,8 +756,6 @@ def main():

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
Expand All @@ -715,6 +770,7 @@ def main():
"configure-host": configure_emscripten_python,
"make-host": make_emscripten_python,
"build": build_target,
"run": run_emscripten_python,
"clean": clean_contents,
}

Expand Down
Loading