build system update

This commit is contained in:
2026-09-25 19:58:11 -07:00
parent 86b36f27c6
commit 1ccb591959
5 changed files with 146 additions and 11 deletions
+69 -2
View File
@@ -20,6 +20,7 @@ WAIT_FOR_PROCESS = "wait_for_process"
class DevHelper:
SHADER_EXTENSIONS = (".vert", ".frag", ".comp", ".geom", ".tesc", ".tese")
PROJECT_NAME = "sophia"
DEFAULT_PRESET = "debug"
def __init__(self):
self.last_exit_status = 0
@@ -39,9 +40,29 @@ class DevHelper:
return method(*rest, **kwargs)
# Primary command wrappers
##
# Configures and builds a CMake preset (see CMakePresets.json).
# dev build [preset] [--fresh]
# The preset defaults to debug and builds into build/<preset>. --fresh
# discards the preset's CMake cache before configuring.
def build(self, *args, **kwargs):
command = f"rm -rf build && cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug"
self._exec_in_root(command, replace=True)
preset, fresh = self._parse_preset_args(args, "build")
self._build_preset(preset, fresh)
##
# Builds the debug preset (incrementally), then runs the testbed from
# build/debug. Any arguments are passed through to the testbed.
# dev testbed [args...]
def testbed(self, *args, **kwargs):
preset = self.DEFAULT_PRESET
self._build_preset(preset, fresh=False)
preset_dir = os.path.join(self._project_root(), "build", preset)
binary = os.path.join(preset_dir, "bin", "testbed")
print(f"Running: {shlex.join([binary, *args])}")
os.chdir(preset_dir)
os.execv(binary, [binary, *args])
##
# Checks out a branch named after a Gitea issue URL.
@@ -149,6 +170,52 @@ class DevHelper:
if not name.startswith("_") and name != "call" and callable(getattr(DevHelper, name))
)
def _parse_preset_args(self, args, command):
preset = None
fresh = False
for arg in args:
if arg == "--fresh":
fresh = True
elif arg.startswith("-"):
raise ValueError(f"Unknown option: {arg}")
elif preset is None:
preset = arg
else:
raise ValueError(f"Usage: dev {command} [preset] [--fresh]")
preset = preset or self.DEFAULT_PRESET
presets = self._configure_presets()
if preset not in presets:
raise ValueError(f"Unknown preset: {preset} (available: {', '.join(presets)})")
return preset, fresh
def _configure_presets(self):
with open(os.path.join(self._project_root(), "CMakePresets.json")) as f:
presets = json.load(f)["configurePresets"]
return [preset["name"] for preset in presets if not preset.get("hidden")]
def _build_preset(self, preset, fresh):
configure = ["cmake", "--preset", preset]
if fresh:
configure.append("--fresh")
self._run_in_root(configure)
self._copy_compile_commands(preset)
self._run_in_root(["cmake", "--build", "--preset", preset])
# Editor tooling reads build/compile_commands.json, so point it at the
# most recently configured preset.
def _copy_compile_commands(self, preset):
build_dir = os.path.join(self._project_root(), "build")
source = os.path.join(build_dir, preset, "compile_commands.json")
if os.path.isfile(source):
shutil.copyfile(source, os.path.join(build_dir, "compile_commands.json"))
def _run_in_root(self, command):
print(f"Running: {shlex.join(command)}")
result = subprocess.run(command, cwd=self._project_root())
if result.returncode != 0:
sys.exit(result.returncode)
def _parse_issue_url(self, url):
match = re.match(r"^(https?://[^/]+)/([^/]+)/([^/]+)/issues/(\d+)", url)
if match is None: