Created
October 3, 2025 15:28
-
-
Save conundrumer/758eaf7ee26f2d1b177377895cda5a74 to your computer and use it in GitHub Desktop.
vibemake.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """Minimal Make-like build system""" | |
| import os | |
| from pathlib import Path | |
| from typing import Callable, List | |
| class Rule: | |
| def __init__(self, target: str, deps: List[str], recipe: Callable): | |
| self.target = target | |
| self.deps = deps | |
| self.recipe = recipe | |
| def needs_update(self) -> bool: | |
| """Check if target needs rebuilding""" | |
| if not os.path.exists(self.target): | |
| return True | |
| target_time = os.path.getmtime(self.target) | |
| for dep in self.deps: | |
| if not os.path.exists(dep): | |
| raise FileNotFoundError(f"Dependency not found: {dep}") | |
| if os.path.getmtime(dep) > target_time: | |
| return True | |
| return False | |
| class Make: | |
| def __init__(self): | |
| self.rules = {} | |
| def rule(self, target: str, deps: List[str] = None): | |
| """Decorator to define a rule""" | |
| deps = deps or [] | |
| def decorator(func: Callable): | |
| self.rules[target] = Rule(target, deps, func) | |
| return func | |
| return decorator | |
| def build(self, target: str): | |
| """Build a target and its dependencies""" | |
| if target not in self.rules: | |
| # Assume it's a source file | |
| if not os.path.exists(target): | |
| raise FileNotFoundError(f"No rule for target: {target}") | |
| return | |
| rule = self.rules[target] | |
| # Build dependencies first | |
| for dep in rule.deps: | |
| self.build(dep) | |
| # Build target if needed | |
| if rule.needs_update(): | |
| print(f"Building: {target}") | |
| rule.recipe() | |
| else: | |
| print(f"Up to date: {target}") | |
| """ | |
| Example usage: | |
| mk = Make() | |
| # Simple rule with dependencies | |
| @mk.rule("output.txt", ["input.txt"]) | |
| def build_output(): | |
| with open("input.txt") as f: | |
| data = f.read().upper() | |
| with open("output.txt", "w") as f: | |
| f.write(data) | |
| # Pattern-like behavior using Python | |
| for src in Path(".").glob("*.c"): | |
| obj = str(src.with_suffix(".o")) | |
| @mk.rule(obj, [str(src)]) | |
| def build_obj(s=src, o=obj): # Capture loop vars | |
| print(f"Compiling {s} -> {o}") | |
| # compile(s, o) | |
| # Collect all objects for linking | |
| objs = [str(p.with_suffix(".o")) for p in Path(".").glob("*.c")] | |
| @mk.rule("program", objs) | |
| def link(): | |
| print(f"Linking {objs} -> program") | |
| # link(objs, "program") | |
| mk.build("program") | |
| """ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment