From 42329f03c0ac989426e47e84496f5b9e52758658 Mon Sep 17 00:00:00 2001 From: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:33:24 -0500 Subject: [PATCH] updated config system , and made it able to support c files --- .remake_cache.json | 1 + remake.yaml | 41 ++++++++++++ remake/remake.py | 32 ++++++++-- remake/remake_config.py | 138 ++++++++++++++++++++++++++++++++-------- 4 files changed, 178 insertions(+), 34 deletions(-) create mode 100644 .remake_cache.json create mode 100644 remake.yaml diff --git a/.remake_cache.json b/.remake_cache.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.remake_cache.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/remake.yaml b/remake.yaml new file mode 100644 index 0000000..6af9137 --- /dev/null +++ b/remake.yaml @@ -0,0 +1,41 @@ +# Remake Build Configuration + +# Source folders to recursively find .c/.cpp files +src_dirs: + - src + - lua + +# Include directories (-I) +include_dirs: + - include + - lua + - 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 +cache_file: remake/.remake_cache.json + +# 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 → -lglfw3) +auto_libs: [] + +# Auto-detect headers from these include folders +auto_includes: [] diff --git a/remake/remake.py b/remake/remake.py index cbb1665..8b68a01 100644 --- a/remake/remake.py +++ b/remake/remake.py @@ -105,13 +105,26 @@ def resolve_packages(): # ========== BUILD SYSTEM ========== def find_cpp_files(): - cpp_files = [] + extensions = [".c", ".cpp"] + files = [] for folder in SRC_DIRS: - for path in Path(folder).rglob("*.cpp"): - cpp_files.append(path) - return cpp_files + for ext in extensions: + for path in Path(folder).rglob(f"*{ext}"): + files.append(path) + return files + +def obj_path(source): + source_abs = source.resolve() + for src_root in SRC_DIRS: + try: + base = Path(src_root).resolve() + rel = source_abs.relative_to(base) + return BUILD_DIR / rel.with_suffix(".o") + except ValueError: + continue + # fallback: flatten path + return BUILD_DIR / source.name.replace("/", "_").replace("\\", "_") + ".o" -def obj_path(source): return BUILD_DIR / source.relative_to("src").with_suffix(".o") def dep_path(obj): return obj.with_suffix(".d") def parse_dep_file(dep_file): @@ -127,7 +140,13 @@ def parse_dep_file(dep_file): def compile_source(source, obj, includes): obj.parent.mkdir(parents=True, exist_ok=True) - cmd = [CXX, *CXXFLAGS, *[f"-I{inc}" for inc in includes], "-MMD", "-MP", "-c", str(source), "-o", str(obj)] + + is_cpp = source.suffix == ".cpp" + compiler = CXX if is_cpp else CC + flags = CXXFLAGS if is_cpp else CFLAGS + + cmd = [compiler, *flags, *[f"-I{inc}" for inc in includes], "-MMD", "-MP", "-c", str(source), "-o", str(obj)] + try: print(f"{color('🔨 Compiling:', Colors.OKCYAN)} {source}") subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -139,6 +158,7 @@ def compile_source(source, obj, includes): log(f"[ERROR] {' '.join(cmd)}\n{e.stderr.decode()}") sys.exit(1) + def link_objects(obj_files, link_dirs, libs): cmd = [CXX, *map(str, obj_files), "-o", str(TARGET), *[f"-L{p}" for p in link_dirs], *libs] try: diff --git a/remake/remake_config.py b/remake/remake_config.py index 4837fa3..8385efd 100644 --- a/remake/remake_config.py +++ b/remake/remake_config.py @@ -1,34 +1,116 @@ +import sys +import yaml from pathlib import Path -# Source and header directories -SRC_DIRS = ["src/src", "src/vendor"] -INCLUDE_DIRS = [ - "src/include", - "src/vendor", - "src/vendor/imgui", - "C:/msys64/mingw64/include" -] +class Style: + RED = '\033[91m' + GREEN = '\033[92m' + YELLOW = '\033[93m' + BLUE = '\033[94m' + BOLD = '\033[1m' + END = '\033[0m' -# Default library search paths -LIB_DIRS = [ - "C:/msys64/mingw64/lib", - "C:/Program Files", - "C:/Program Files (x86)", - "C:/libs", -] +def die(msg): + print(f"{Style.RED}{Style.BOLD}❌ Error:{Style.END} {msg}") + sys.exit(1) -# Compiler and build options -BUILD_DIR = Path("src/build") -TARGET = BUILD_DIR / "app.exe" -LOG_FILE = Path("build.log") -CACHE_FILE = Path("./remake/.remake_cache.json") -CXX = "g++" -CXXFLAGS = ["-std=c++20", "-Wall"] + [f"-I{inc}" for inc in INCLUDE_DIRS] +def warn(msg): + print(f"{Style.YELLOW}⚠️ {msg}{Style.END}") -# Libraries and includes to auto-discover -AUTO_LIBS = [ - "glfw3", "glew32", "opengl32", "gdi32", - "yaml-cpp", "comdlg32", "ssl", "crypto" -] +def success(msg): + print(f"{Style.GREEN}✅ {msg}{Style.END}") -AUTO_INCLUDES = ["imgui", "yaml-cpp"] +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 + - lua + +# Include directories (-I) +include_dirs: + - include + - lua + - 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 +cache_file: remake/.remake_cache.json + +# 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 → -lglfw3) +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): + try: + val = config[name] + if not isinstance(val, expected_type): + raise TypeError(f"Expected {expected_type.__name__}, got {type(val).__name__}") + return val + except KeyError: + die(f"Missing required field: {Style.BOLD}{name}{Style.END}") + except TypeError as e: + die(f"{name} -> {e}") + +# Extract values safely +SRC_DIRS = get_field("src_dirs", list) +INCLUDE_DIRS = get_field("include_dirs", list) +LIB_DIRS = get_field("lib_dirs", list) + +BUILD_DIR = Path(get_field("build_dir", str)) +TARGET = Path(get_field("target", str)) +LOG_FILE = Path(get_field("log_file", str)) +CACHE_FILE = Path(get_field("cache_file", str)) + +CC = get_field("cc", str) +CFLAGS = get_field("cflags", list) + +CXX = get_field("cxx", str) +CXXFLAGS = get_field("cxxflags", list) + +AUTO_LIBS = get_field("auto_libs", list) +AUTO_INCLUDES = get_field("auto_includes", list)