120 lines
2.7 KiB
Python
120 lines
2.7 KiB
Python
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)
|
|
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, [])
|
|
|
|
|
|
|