import os
import shutil
import subprocess
import sys
from pathlib import Path
from subprocess import PIPE, CompletedProcess, Popen
from typing import Union
import tomli
class Paths:
PACKAGE: Path = Path(__file__).parent
REPO: Path = (PACKAGE.parent)
BUILD: Path = (Path.cwd()/"build")
class Tools:
PYTHON: tuple[str] = (sys.executable,)
MESON: tuple[str] = (*PYTHON, "-m", "mesonbuild.mesonmain")
NINJA: tuple[str] = (*PYTHON, "-m", "ninja")
RUSTUP: tuple[str] = (shutil.which("rustup"),)
CARGO: tuple[str] = (shutil.which("cargo"),)
def rustlith(
*args: list[str],
Popen: bool=False,
toolchain: str="stable",
**kwargs
) -> Union[CompletedProcess, Popen]:
args = list(map(str, (args or sys.argv[1:])))
if subprocess.run(
(*Tools.RUSTUP, "run", toolchain, "rustc", "--version"),
stdout=PIPE, stderr=PIPE
).returncode != 0:
subprocess.check_call((
*Tools.RUSTUP,
"default", toolchain
))
cargo = tomli.loads((Paths.PACKAGE/"Cargo.toml").read_text(encoding="utf-8"))
features = list()
for feature in cargo["features"]:
if (flag := f"--{feature}") in args:
features.append("--features")
features.append(feature)
args.remove(flag)
os.environ.update(RUSTFLAGS="-C target-cpu=native")
return (subprocess.Popen if Popen else subprocess.run)((
*Tools.CARGO, "run",
"--manifest-path", (Paths.PACKAGE/"Cargo.toml"),
"--target-dir", str(Path.cwd()/"target"),
"--release", *features,
"--", *args,
), **kwargs)
def cudalith(
*args: list[str],
Popen: bool=False,
**kwargs
) -> Union[CompletedProcess, Popen]:
args = list(map(str, (args or sys.argv[1:])))
if not shutil.which("nvcc"):
raise RuntimeError("nvcc wasn't found in path, do you have cuda toolkit?")
subprocess.check_call((
*Tools.MESON,
"setup", Paths.BUILD,
"--buildtype", "release",
"--reconfigure"
), cwd=Paths.PACKAGE)
subprocess.check_call((
*Tools.NINJA, "-C",
Paths.BUILD
))
return (subprocess.Popen if Popen else subprocess.run)((
Paths.BUILD/"cudalith",
*args
), **kwargs)