import sys import yaml from pathlib import Path class Style: RED = '\033[91m' GREEN = '\033[92m' YELLOW = '\033[93m' BLUE = '\033[94m' BOLD = '\033[1m' END = '\033[0m' def die(msg): print(f"{Style.RED}{Style.BOLD}❌ Error:{Style.END} {msg}") sys.exit(1) def warn(msg): print(f"{Style.YELLOW}⚠️ {msg}{Style.END}") def success(msg): print(f"{Style.GREEN}✅ {msg}{Style.END}") def info(msg): print(f"{Style.BLUE}{msg}{Style.END}") config_path = Path("remake.yaml") default_config = """\ # 🔧 Remake Build Configuration # Source folders to recursively find .c/.cpp files src_dirs: - src # Include directories (-I) include_dirs: - include - C:/msys64/mingw64/include # Library search paths (-L) lib_dirs: - C:/msys64/mingw64/lib - C:/libs # Output paths build_dir: build target: build/app.exe log_file: remake/build.log # C compiler and flags cc: gcc cflags: - -std=c99 - -Wall # C++ compiler and flags cxx: g++ cxxflags: - -std=c++20 - -Wall # Auto-detect these libraries (e.g. "glfw3" or "opengl32" ) auto_libs: [] # Auto-detect headers from these include folders auto_includes: [] """ # Create default if missing if not config_path.exists(): config_path.write_text(default_config, encoding="utf-8") success("Generated default remake.yaml ✨") # Load YAML try: with open(config_path, "r", encoding="utf-8") as f: config = yaml.safe_load(f) except yaml.YAMLError as e: die(f"Failed to parse remake.yaml:\n{e}") if config is None: die("remake.yaml is empty or invalid YAML. Please fix the file.") # Validate fields def get_field(name, expected_type, default=None): val = config.get(name, default) if val is None: warn(f"Missing field '{name}', using default: {default}") return default if not isinstance(val, expected_type): die(f"{name} -> Expected {expected_type.__name__}, got {type(val).__name__}") return val SRC_DIRS = get_field("src_dirs", list, ["src"]) INCLUDE_DIRS = get_field("include_dirs", list, ["include", "C:/msys64/mingw64/include"]) LIB_DIRS = get_field("lib_dirs", list, ["C:/msys64/mingw64/lib", "C:/libs"]) BUILD_DIR = Path(get_field("build_dir", str, "build")) TARGET = Path(get_field("target", str, "build/app.exe")) LOG_FILE = Path(get_field("log_file", str, "remake/build.log")) CACHE_FILE = Path(get_field("cache_file", str, "remake/.remake_cache.json")) CC = get_field("cc", str, "gcc") CFLAGS = get_field("cflags", list, ["-std=c99", "-Wall"]) CXX = get_field("cxx", str, "g++") CXXFLAGS = get_field("cxxflags", list, ["-std=c++20", "-Wall"]) AUTO_LIBS = get_field("auto_libs", list, []) AUTO_INCLUDES = get_field("auto_includes", list, [])