Import("env")
import os
import pathlib
import subprocess
PROJECT_DIR = pathlib.Path(env.subst("$PROJECT_DIR")).resolve()
PIO_ENV = env.subst("$PIOENV")
RUST_TARGET = env.GetProjectOption("custom_rust_target")
TARGET_DIR = PROJECT_DIR / ".pio" / "rust-target"
GENERATED_DIR = PROJECT_DIR / ".pio" / "generated" / PIO_ENV
SOURCE = PROJECT_DIR / "programs" / "esp32-blinky.rss"
VMBC = GENERATED_DIR / "program.vmbc"
HEADER = GENERATED_DIR / "program_vmbc.h"
ARCHIVE = TARGET_DIR / RUST_TARGET / "release" / "librustscript_embedded.a"
def run(command, environment=None):
print("micro-rustscript:", " ".join(str(item) for item in command))
clean_env = os.environ.copy() if environment is None else environment.copy()
clean_env.pop("RUSTFLAGS", None)
subprocess.run(command, cwd=PROJECT_DIR, env=clean_env, check=True)
def write_header(payload):
rows = []
for offset in range(0, len(payload), 12):
chunk = payload[offset : offset + 12]
rows.append(" " + ", ".join(f"0x{byte:02x}" for byte in chunk) + ",")
content = "\n".join(
[
"#pragma once",
"",
"#include <stddef.h>",
"#include <stdint.h>",
"",
"static const uint8_t RUSTSCRIPT_PROGRAM_VMBC[] = {",
*rows,
"};",
"static const size_t RUSTSCRIPT_PROGRAM_VMBC_LEN = sizeof(RUSTSCRIPT_PROGRAM_VMBC);",
"",
]
)
if not HEADER.exists() or HEADER.read_text() != content:
HEADER.write_text(content)
GENERATED_DIR.mkdir(parents=True, exist_ok=True)
build_environment = os.environ.copy()
build_environment["CARGO_TARGET_DIR"] = str(TARGET_DIR)
build_environment.pop("RUSTFLAGS", None)
run(
[
"cargo",
"build",
"--release",
"--target",
RUST_TARGET,
"--no-default-features",
"--features",
"arduino",
],
build_environment,
)
run(
[
"cargo",
"run",
"--quiet",
"--bin",
"rustscript-compile-vmbc",
"--",
str(SOURCE),
str(VMBC),
],
build_environment,
)
if not ARCHIVE.is_file() or ARCHIVE.stat().st_size == 0:
raise RuntimeError(f"missing Rust static library: {ARCHIVE}")
if not VMBC.is_file() or VMBC.stat().st_size == 0:
raise RuntimeError(f"missing VMBC output: {VMBC}")
write_header(VMBC.read_bytes())
env.Append(CPPPATH=[str(PROJECT_DIR / "include"), str(GENERATED_DIR)])
env.Append(LIBS=[env.File(str(ARCHIVE))])