From 2868236d6a7ec4ec46c7e0224e3bb1821fa2be7c Mon Sep 17 00:00:00 2001 From: dawidg81 Date: Fri, 13 Feb 2026 10:39:08 +0100 Subject: Updated README.md; Implemented more backends; more build files, native for windows --- Makefile | 255 ++++++++++++++++++++------------------------------------------ README.md | 224 ++++++++++++++++++++++++++++++++++++++---------------- build.bat | 119 +++++++++++++++++++++++++++++ build.ps1 | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 565 insertions(+), 238 deletions(-) create mode 100644 build.bat create mode 100644 build.ps1 diff --git a/Makefile b/Makefile index 73fd5cd..6342e67 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,8 @@ # Makefile for libgraffik -# Smart build system with interactive backend and example selection - -# Colors for output -COLOR_RESET = \033[0m -COLOR_BOLD = \033[1m -COLOR_GREEN = \033[32m -COLOR_BLUE = \033[34m -COLOR_YELLOW = \033[33m -COLOR_RED = \033[31m +# Windows-compatible build system # Compiler -CXX ?= g++ +CXX = g++ # Directories LIB_DIR = lib @@ -24,25 +16,22 @@ CXXFLAGS = -std=c++11 -Wall -Wextra -I$(LIB_DIR) LIB_SOURCE = $(LIB_DIR)/graphics.cpp # Detect platform -ifeq ($(OS),Windows_NT) - PLATFORM = Windows - EXE_EXT = .exe - RM = del /Q - RMDIR = rmdir /S /Q - MKDIR = mkdir - PATH_SEP = \\ +ifdef OS + ifeq ($(OS),Windows_NT) + PLATFORM = Windows + EXE_EXT = .exe + RM = del /Q + RMDIR = rmdir /S /Q + MKDIR = if not exist $(BUILD_DIR) mkdir $(BUILD_DIR) + endif else PLATFORM = Linux EXE_EXT = RM = rm -f RMDIR = rm -rf - MKDIR = mkdir -p - PATH_SEP = / + MKDIR = mkdir -p $(BUILD_DIR) endif -# Available backends -AVAILABLE_BACKENDS = sdl win32 x11 - # Backend-specific settings ifeq ($(BACKEND),sdl) BACKEND_DEFINE = -DUSE_SDL @@ -69,205 +58,127 @@ else ifeq ($(BACKEND),x11) endif # Find all example files -EXAMPLE_FILES = $(wildcard $(EXAMPLES_DIR)/*.cpp) -EXAMPLE_NAMES = $(basename $(notdir $(EXAMPLE_FILES))) +EXAMPLE_FILES := $(wildcard $(EXAMPLES_DIR)/*.cpp) +EXAMPLE_NAMES := $(basename $(notdir $(EXAMPLE_FILES))) -# Default target - show menu +# Default target - show help .PHONY: all -all: menu +all: help -# Interactive menu -.PHONY: menu -menu: - @echo "$(COLOR_BOLD)$(COLOR_BLUE)╔════════════════════════════════════════╗$(COLOR_RESET)" - @echo "$(COLOR_BOLD)$(COLOR_BLUE)║ libgraffik Build System ║$(COLOR_RESET)" - @echo "$(COLOR_BOLD)$(COLOR_BLUE)╚════════════════════════════════════════╝$(COLOR_RESET)" - @echo "" - @echo "$(COLOR_BOLD)Platform:$(COLOR_RESET) $(COLOR_GREEN)$(PLATFORM)$(COLOR_RESET)" - @echo "" - @echo "$(COLOR_BOLD)Usage:$(COLOR_RESET)" - @echo " make build BACKEND= EXAMPLE=" - @echo "" - @echo "$(COLOR_BOLD)Available Backends:$(COLOR_RESET)" - @echo " $(COLOR_GREEN)sdl$(COLOR_RESET) - SDL2 (cross-platform)" - @echo " $(COLOR_YELLOW)win32$(COLOR_RESET) - Win32 API (Windows only)" - @echo " $(COLOR_YELLOW)x11$(COLOR_RESET) - X11 (Linux only)" - @echo "" - @echo "$(COLOR_BOLD)Available Examples:$(COLOR_RESET)" - @for example in $(EXAMPLE_NAMES); do \ - echo " $(COLOR_BLUE)$$example$(COLOR_RESET)"; \ - done - @echo "" - @echo "$(COLOR_BOLD)Examples:$(COLOR_RESET)" - @echo " make build BACKEND=sdl EXAMPLE=sample1" - @echo " make build BACKEND=x11 EXAMPLE=sample2" - @echo "" - @echo "$(COLOR_BOLD)Quick Build:$(COLOR_RESET)" - @echo " make quick - Interactive mode" - @echo " make clean - Clean build files" - @echo "" - -# Interactive quick build -.PHONY: quick -quick: - @echo "$(COLOR_BOLD)$(COLOR_GREEN)Select Backend:$(COLOR_RESET)" - @echo "1) SDL2 (recommended, cross-platform)" -ifeq ($(PLATFORM),Windows) - @echo "2) Win32 (Windows native)" -else - @echo "2) X11 (Linux native)" -endif - @read -p "Enter choice [1-2]: " choice; \ - if [ "$$choice" = "1" ]; then \ - BACKEND_CHOICE="sdl"; \ - elif [ "$$choice" = "2" ]; then \ - if [ "$(PLATFORM)" = "Windows" ]; then \ - BACKEND_CHOICE="win32"; \ - else \ - BACKEND_CHOICE="x11"; \ - fi; \ - else \ - echo "$(COLOR_RED)Invalid choice$(COLOR_RESET)"; \ - exit 1; \ - fi; \ - echo ""; \ - echo "$(COLOR_BOLD)$(COLOR_GREEN)Select Example:$(COLOR_RESET)"; \ - i=1; \ - for example in $(EXAMPLE_NAMES); do \ - echo "$$i) $$example"; \ - i=$$((i+1)); \ - done; \ - read -p "Enter choice [1-$(words $(EXAMPLE_NAMES))]: " choice; \ - EXAMPLE_CHOICE=$$(echo "$(EXAMPLE_NAMES)" | cut -d' ' -f$$choice); \ - if [ -z "$$EXAMPLE_CHOICE" ]; then \ - echo "$(COLOR_RED)Invalid choice$(COLOR_RESET)"; \ - exit 1; \ - fi; \ - echo ""; \ - echo "$(COLOR_BOLD)Building $$EXAMPLE_CHOICE with $$BACKEND_CHOICE backend...$(COLOR_RESET)"; \ - $(MAKE) build BACKEND=$$BACKEND_CHOICE EXAMPLE=$$EXAMPLE_CHOICE +# Help menu +.PHONY: help +help: + @echo ======================================== + @echo libgraffik Build System + @echo ======================================== + @echo. + @echo Platform: $(PLATFORM) + @echo. + @echo Usage: + @echo make build BACKEND=^ EXAMPLE=^ + @echo. + @echo Available Backends: + @echo sdl - SDL2 (cross-platform) + @echo win32 - Win32 API (Windows only) + @echo x11 - X11 (Linux only) + @echo. + @echo Available Examples: + @for %%f in ($(EXAMPLES_DIR)\*.cpp) do @echo %%~nf + @echo. + @echo Example Commands: + @echo make build BACKEND=sdl EXAMPLE=sample1 + @echo make build BACKEND=win32 EXAMPLE=sample2 + @echo make run BACKEND=sdl EXAMPLE=sample1 + @echo make build-all BACKEND=sdl + @echo make clean + @echo. # Build target .PHONY: build build: validate - @echo "$(COLOR_BOLD)$(COLOR_GREEN)Building $(EXAMPLE) with $(BACKEND) backend...$(COLOR_RESET)" - @$(MKDIR) $(BUILD_DIR) 2>/dev/null || true + @echo Building $(EXAMPLE) with $(BACKEND) backend... + @$(MKDIR) $(CXX) $(CXXFLAGS) $(BACKEND_DEFINE) $(INCLUDES) \ $(EXAMPLES_DIR)/$(EXAMPLE).cpp $(LIB_SOURCE) \ -o $(BUILD_DIR)/$(EXAMPLE)$(EXE_EXT) \ $(LDFLAGS) $(LIBS) - @echo "$(COLOR_BOLD)$(COLOR_GREEN)✓ Build successful!$(COLOR_RESET)" - @echo "$(COLOR_BOLD)Output:$(COLOR_RESET) $(BUILD_DIR)/$(EXAMPLE)$(EXE_EXT)" + @echo Build successful! + @echo Output: $(BUILD_DIR)/$(EXAMPLE)$(EXE_EXT) ifeq ($(BACKEND),sdl) ifeq ($(PLATFORM),Windows) - @if [ -f "$(LIB_DIR)/SDL2.dll" ]; then \ - cp $(LIB_DIR)/SDL2.dll $(BUILD_DIR)/ 2>/dev/null || copy $(LIB_DIR)$(PATH_SEP)SDL2.dll $(BUILD_DIR)$(PATH_SEP) 2>nul || true; \ - echo "$(COLOR_BLUE)✓ SDL2.dll copied to build directory$(COLOR_RESET)"; \ - elif [ -f "$(SDL2_PATH)/bin/SDL2.dll" ]; then \ - cp $(SDL2_PATH)/bin/SDL2.dll $(BUILD_DIR)/ 2>/dev/null || copy $(SDL2_PATH)$(PATH_SEP)bin$(PATH_SEP)SDL2.dll $(BUILD_DIR)$(PATH_SEP) 2>nul || true; \ - echo "$(COLOR_BLUE)✓ SDL2.dll copied from SDL2 installation$(COLOR_RESET)"; \ - fi + @if exist $(LIB_DIR)\SDL2.dll copy $(LIB_DIR)\SDL2.dll $(BUILD_DIR)\ >nul 2>&1 + @if exist $(SDL2_PATH)\bin\SDL2.dll if not exist $(BUILD_DIR)\SDL2.dll copy $(SDL2_PATH)\bin\SDL2.dll $(BUILD_DIR)\ >nul 2>&1 endif endif - @echo "" - @echo "$(COLOR_BOLD)Run with:$(COLOR_RESET)" - @echo " ./$(BUILD_DIR)/$(EXAMPLE)$(EXE_EXT)" + @echo. + @echo Run with: $(BUILD_DIR)\$(EXAMPLE)$(EXE_EXT) # Validate inputs .PHONY: validate validate: ifndef BACKEND - @echo "$(COLOR_RED)Error: BACKEND not specified$(COLOR_RESET)" - @echo "Run 'make' or 'make quick' for interactive mode" + @echo Error: BACKEND not specified + @echo Usage: make build BACKEND=^ EXAMPLE=^ + @echo Run 'make help' for more information @exit 1 endif ifndef EXAMPLE - @echo "$(COLOR_RED)Error: EXAMPLE not specified$(COLOR_RESET)" - @echo "Run 'make' or 'make quick' for interactive mode" + @echo Error: EXAMPLE not specified + @echo Usage: make build BACKEND=^ EXAMPLE=^ + @echo Run 'make help' for more information @exit 1 endif - @if ! echo "$(AVAILABLE_BACKENDS)" | grep -w "$(BACKEND)" > /dev/null; then \ - echo "$(COLOR_RED)Error: Invalid backend '$(BACKEND)'$(COLOR_RESET)"; \ - echo "Available: $(AVAILABLE_BACKENDS)"; \ - exit 1; \ - fi - @if [ ! -f "$(EXAMPLES_DIR)/$(EXAMPLE).cpp" ]; then \ - echo "$(COLOR_RED)Error: Example '$(EXAMPLE)' not found$(COLOR_RESET)"; \ - echo "Available examples:"; \ - for ex in $(EXAMPLE_NAMES); do echo " $$ex"; done; \ - exit 1; \ - fi -ifeq ($(BACKEND),win32) -ifneq ($(PLATFORM),Windows) - @echo "$(COLOR_RED)Error: win32 backend only available on Windows$(COLOR_RESET)" - @exit 1 -endif -endif -ifeq ($(BACKEND),x11) -ifeq ($(PLATFORM),Windows) - @echo "$(COLOR_RED)Error: x11 backend only available on Linux$(COLOR_RESET)" - @exit 1 -endif -endif + @if not exist $(EXAMPLES_DIR)\$(EXAMPLE).cpp (echo Error: Example '$(EXAMPLE)' not found & exit 1) # Build all examples with specified backend .PHONY: build-all build-all: ifndef BACKEND - @echo "$(COLOR_RED)Error: BACKEND not specified$(COLOR_RESET)" - @echo "Usage: make build-all BACKEND=" + @echo Error: BACKEND not specified + @echo Usage: make build-all BACKEND=^ @exit 1 endif - @echo "$(COLOR_BOLD)$(COLOR_GREEN)Building all examples with $(BACKEND) backend...$(COLOR_RESET)" - @for example in $(EXAMPLE_NAMES); do \ - echo ""; \ - $(MAKE) build BACKEND=$(BACKEND) EXAMPLE=$$example; \ - done - @echo "" - @echo "$(COLOR_BOLD)$(COLOR_GREEN)✓ All examples built successfully!$(COLOR_RESET)" + @echo Building all examples with $(BACKEND) backend... + @for %%f in ($(EXAMPLES_DIR)\*.cpp) do @$(MAKE) --no-print-directory build BACKEND=$(BACKEND) EXAMPLE=%%~nf + @echo. + @echo All examples built successfully! # Run an example .PHONY: run run: build - @echo "$(COLOR_BOLD)$(COLOR_GREEN)Running $(EXAMPLE)...$(COLOR_RESET)" - @cd $(BUILD_DIR) && ./$(EXAMPLE)$(EXE_EXT) + @echo Running $(EXAMPLE)... + @cd $(BUILD_DIR) && $(EXAMPLE)$(EXE_EXT) # Clean build files .PHONY: clean clean: - @echo "$(COLOR_BOLD)Cleaning build files...$(COLOR_RESET)" + @echo Cleaning build files... ifeq ($(PLATFORM),Windows) - @if exist $(BUILD_DIR) $(RMDIR) $(BUILD_DIR) 2>nul || true + @if exist $(BUILD_DIR) $(RMDIR) $(BUILD_DIR) 2>nul else @$(RMDIR) $(BUILD_DIR) 2>/dev/null || true endif - @echo "$(COLOR_GREEN)✓ Clean complete$(COLOR_RESET)" - -# Help -.PHONY: help -help: menu + @echo Clean complete # Show configuration .PHONY: config config: - @echo "$(COLOR_BOLD)Current Configuration:$(COLOR_RESET)" - @echo " Platform: $(PLATFORM)" - @echo " Compiler: $(CXX)" - @echo " Lib Dir: $(LIB_DIR)" - @echo " Examples: $(EXAMPLES_DIR)" - @echo " Build Dir: $(BUILD_DIR)" - @echo "" - @echo "$(COLOR_BOLD)Available Examples:$(COLOR_RESET)" - @for example in $(EXAMPLE_NAMES); do \ - echo " - $$example"; \ - done - @echo "" - @echo "$(COLOR_BOLD)Available Backends:$(COLOR_RESET)" - @echo " - sdl (SDL2)" + @echo Current Configuration: + @echo Platform: $(PLATFORM) + @echo Compiler: $(CXX) + @echo Lib Dir: $(LIB_DIR) + @echo Examples: $(EXAMPLES_DIR) + @echo Build Dir: $(BUILD_DIR) + @echo. + @echo Available Examples: + @for %%f in ($(EXAMPLES_DIR)\*.cpp) do @echo - %%~nf + @echo. + @echo Available Backends: + @echo - sdl (SDL2) ifeq ($(PLATFORM),Windows) - @echo " - win32 (Win32 API)" + @echo - win32 (Win32 API) else - @echo " - x11 (X11)" + @echo - x11 (X11) endif -.DEFAULT_GOAL := menu +.DEFAULT_GOAL := help diff --git a/README.md b/README.md index ac59927..f5187f6 100644 --- a/README.md +++ b/README.md @@ -1,90 +1,158 @@ -# libgraffik +# libgraffik - Cross-Platform Graphics Library A simple cross-platform graphics abstraction layer with support for multiple backends (SDL2, Win32, X11). -## Current Implementation +## Implemented Backends -Currently implemented backends: -- **SDL2** (Windows) - Fully implemented - -Planned backends: -- **Win32** (Windows native) - Placeholder -- **X11** (Linux) - Placeholder +- ✅ **SDL2** (Windows, Linux, macOS) - Fully implemented +- ✅ **Win32** (Windows native) - Fully implemented +- ✅ **X11** (Linux native) - Fully implemented ## Features - Window creation and management +- Double buffering for smooth rendering - Basic drawing primitives: - Lines - Rectangles (filled and outlined) - Circles (filled and outlined) - Pixels -- Color support with alpha channel -- Simple event handling +- Color support with alpha channel (SDL only) +- Simple event handling (ESC key, window close) - Cross-platform delay function -## Building +## Building on Windows + +### Option 1: Batch File (Easiest for Windows) + +```cmd +REM Build with SDL2 +build.bat sdl sample1 + +REM Build with Win32 +build.bat win32 sample1 + +REM Clean +build.bat clean + +REM Show help +build.bat help +``` + +### Option 2: PowerShell Script (Recommended for Windows) + +```powershell +# Build with SDL2 +.\build.ps1 -Backend sdl -Example sample1 -### Windows (with SDL2) +# Build with Win32 +.\build.ps1 -Backend win32 -Example sample2 -#### Prerequisites -1. **C++ compiler**: MinGW or MSVC -2. **SDL2 development libraries**: Download from [libsdl.org](https://www.libsdl.org/download-2.0.php) - - For MinGW: Download `SDL2-devel-2.x.x-mingw.tar.gz` - - For MSVC: Download `SDL2-devel-2.x.x-VC.zip` +# Build and run +.\build.ps1 -Backend sdl -Example sample1 -Run -#### Installing SDL2 +# Build all examples +.\build.ps1 -Backend sdl -All -1. **Download SDL2** development libraries for your compiler -2. **Extract** the archive -3. **Place SDL2** in one of these locations: - - `C:/SDL2` - - `D:/SDL2` - - Or in your project directory: `/SDL2` +# Clean +.\build.ps1 -Clean -#### Option 1: Using Makefile (MinGW - Easiest) +# Show help +.\build.ps1 -Help +``` + +### Option 3: Makefile (MinGW Make) ```bash -# If SDL2 is in C:/SDL2 +# Show help make -# If SDL2 is elsewhere -make SDL2_PATH=D:/path/to/SDL2 +# Build specific example +make build BACKEND=sdl EXAMPLE=sample1 +make build BACKEND=win32 EXAMPLE=sample2 + +# Build all examples +make build-all BACKEND=sdl -# Run the demo -make run +# Build and run +make run BACKEND=sdl EXAMPLE=sample1 + +# Clean +make clean ``` -**Note**: Make sure `SDL2.dll` from `SDL2/bin` is in the same directory as the executable or in your PATH. +### Prerequisites for Windows + +1. **MinGW** with g++ compiler +2. **SDL2** (only for SDL backend): + - Download from [libsdl.org](https://www.libsdl.org/download-2.0.php) + - Get `SDL2-devel-2.x.x-mingw.tar.gz` + - Extract to `C:\SDL2` or set `SDL2_PATH` environment variable + +**Note**: Win32 backend has no external dependencies! -#### Option 2: Manual compilation with g++/MinGW +## Building on Linux + +### Using Makefile ```bash -# Adjust paths to match your SDL2 installation -g++ -std=c++11 -DUSE_SDL -o GraphicsDemo.exe main.cpp graphics.cpp ^ - -IC:/SDL2/include ^ - -LC:/SDL2/lib ^ - -lmingw32 -lSDL2main -lSDL2 -mwindows +# Build with SDL2 +make build BACKEND=sdl EXAMPLE=sample1 + +# Build with X11 (native Linux) +make build BACKEND=x11 EXAMPLE=sample1 -# Copy SDL2.dll to the same directory -copy C:\SDL2\bin\SDL2.dll . +# Build all examples +make build-all BACKEND=x11 + +# Clean +make clean ``` -#### Option 3: Manual compilation with MSVC +### Prerequisites for Linux +For SDL2 backend: ```bash -cl /EHsc /DUSE_SDL main.cpp graphics.cpp ^ - /I"C:\SDL2\include" ^ - /link "C:\SDL2\lib\x64\SDL2.lib" "C:\SDL2\lib\x64\SDL2main.lib" ^ - /SUBSYSTEM:CONSOLE +sudo apt-get install libsdl2-dev # Debian/Ubuntu +sudo dnf install SDL2-devel # Fedora +``` + +For X11 backend: +```bash +sudo apt-get install libx11-dev # Debian/Ubuntu +sudo dnf install libX11-devel # Fedora +``` -# Copy SDL2.dll -copy C:\SDL2\lib\x64\SDL2.dll . +## Manual Compilation + +### Windows with SDL2 +```cmd +g++ -std=c++11 -DUSE_SDL -o build\sample1.exe ^ + examples\sample1.cpp lib\graphics.cpp ^ + -IC:\SDL2\include ^ + -LC:\SDL2\lib ^ + -lmingw32 -lSDL2main -lSDL2 -mwindows +``` + +### Windows with Win32 +```cmd +g++ -std=c++11 -DUSE_WIN32 -o build\sample1.exe ^ + examples\sample1.cpp lib\graphics.cpp ^ + -lgdi32 -luser32 +``` + +### Linux with SDL2 +```bash +g++ -std=c++11 -DUSE_SDL -o build/sample1 \ + examples/sample1.cpp lib/graphics.cpp \ + $(sdl2-config --cflags --libs) ``` -### Linux (X11 - Not yet implemented) +### Linux with X11 ```bash -g++ -o demo main.cpp graphics.cpp -lX11 -DUSE_X11 +g++ -std=c++11 -DUSE_X11 -o build/sample1 \ + examples/sample1.cpp lib/graphics.cpp \ + -lX11 ``` ## Usage Example @@ -120,23 +188,6 @@ int main() { } ``` -## Architecture - -The library uses a simple abstraction pattern: - -1. **graphics.h** - Platform-independent API declarations -2. **graphics.cpp** - Platform-specific implementations (selected at compile time) -3. **Compile-time selection** - Backend is chosen via preprocessor defines - -### Adding a New Backend - -To add a new backend (e.g., Vulkan, DirectX): - -1. Add a new `#ifdef USE_BACKEND` section in `graphics.cpp` -2. Implement all functions declared in `graphics.h` -3. Update the platform detection logic in `graphics.h` if needed -4. Add compilation instructions to this README - ## API Reference ### Window Management @@ -167,6 +218,47 @@ struct Color { }; ``` +## Backend Comparison + +| Feature | SDL2 | Win32 | X11 | +|---------|------|-------|-----| +| Platform | Cross-platform | Windows only | Linux only | +| Dependencies | SDL2 library | None (native) | X11 library | +| Performance | Good | Excellent | Good | +| Complexity | Easy | Medium | Medium | +| Alpha blending | Yes | Limited | Limited | + +## Project Structure + +``` +libgraffik/ +├── lib/ +│ ├── graphics.h # Header file with API declarations +│ ├── graphics.cpp # Implementation for all backends +│ └── SDL2.dll # SDL2 DLL (Windows only) +├── examples/ +│ ├── sample1.cpp # Basic shapes demo +│ ├── sample2.cpp # Animation demo +│ └── sample3.cpp # Interactive demo +├── build/ # Output directory (created automatically) +├── Makefile # Unix-style Makefile +├── build.ps1 # PowerShell build script +├── build.bat # Batch build script +└── README.md # This file +``` + +## Native options + +- **Windows native**: Use `build.bat` for CMD or `build.ps1` for PowerShell. +- **Linux users**: Use the universal Makefile, also most recommended for all OSes. +- **Win32 backend**: Windows-native, uses CPU for rendering, may cause lack of performance, although may use less resources. +- **SDL2 backend**: Best for cross-platform development, works natively on both Linux and Windows, uses GPU for rendering. May be more resource heavy than these simplier backends like X11 or Win32. +- **X11 backend**: Native Linux performance, uses CPU for rendering. Will work for desktops using Xorg server. + ## License -MIT License. See [LICENSE](LICENSE) file. \ No newline at end of file +MIT License. See [LICENSE](LICENSE) file for details. + +# Important notice + +AI had a hand in this. I try to review and improve everything it generates. diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..9c4631c --- /dev/null +++ b/build.bat @@ -0,0 +1,119 @@ +@echo off +REM build.bat - Batch build script for libgraffik +REM Usage: build.bat + +setlocal enabledelayedexpansion + +set LIB_DIR=lib +set EXAMPLES_DIR=examples +set BUILD_DIR=build +set CXX=g++ +set CXXFLAGS=-std=c++11 -Wall -Wextra -I%LIB_DIR% + +if "%1"=="" goto show_help +if "%1"=="help" goto show_help +if "%1"=="-h" goto show_help +if "%1"=="--help" goto show_help +if "%1"=="clean" goto clean + +set BACKEND=%1 +set EXAMPLE=%2 + +if "%EXAMPLE%"=="" ( + echo Error: Example not specified + echo Usage: build.bat ^ ^ + echo Example: build.bat sdl sample1 + exit /b 1 +) + +REM Validate example exists +if not exist "%EXAMPLES_DIR%\%EXAMPLE%.cpp" ( + echo Error: Example '%EXAMPLE%' not found + echo. + echo Available examples: + for %%f in (%EXAMPLES_DIR%\*.cpp) do echo %%~nf + exit /b 1 +) + +REM Create build directory +if not exist "%BUILD_DIR%" mkdir "%BUILD_DIR%" + +REM Set backend-specific flags +if /i "%BACKEND%"=="sdl" ( + set BACKEND_DEFINE=-DUSE_SDL + if not defined SDL2_PATH set SDL2_PATH=C:\SDL2 + set INCLUDES=-I!SDL2_PATH!\include -I!SDL2_PATH!\include\SDL2 + set LDFLAGS=-L!SDL2_PATH!\lib + set LIBS=-lmingw32 -lSDL2main -lSDL2 -mwindows + + REM Copy SDL2.dll + if exist "%LIB_DIR%\SDL2.dll" ( + copy /y "%LIB_DIR%\SDL2.dll" "%BUILD_DIR%\" >nul 2>&1 + ) else if exist "!SDL2_PATH!\bin\SDL2.dll" ( + copy /y "!SDL2_PATH!\bin\SDL2.dll" "%BUILD_DIR%\" >nul 2>&1 + ) +) else if /i "%BACKEND%"=="win32" ( + set BACKEND_DEFINE=-DUSE_WIN32 + set INCLUDES= + set LDFLAGS= + set LIBS=-lgdi32 -luser32 +) else ( + echo Error: Invalid backend '%BACKEND%' + echo Available backends: sdl, win32 + exit /b 1 +) + +echo Building %EXAMPLE% with %BACKEND% backend... +echo. + +REM Build command +%CXX% %CXXFLAGS% %BACKEND_DEFINE% %INCLUDES% ^ + %EXAMPLES_DIR%\%EXAMPLE%.cpp %LIB_DIR%\graphics.cpp ^ + -o %BUILD_DIR%\%EXAMPLE%.exe ^ + %LDFLAGS% %LIBS% + +if %errorlevel% equ 0 ( + echo. + echo Build successful! + echo Output: %BUILD_DIR%\%EXAMPLE%.exe + echo. + echo Run with: %BUILD_DIR%\%EXAMPLE%.exe + exit /b 0 +) else ( + echo. + echo Build failed! + exit /b 1 +) + +:show_help +echo ======================================== +echo libgraffik Build System +echo ======================================== +echo. +echo Usage: +echo build.bat ^ ^ +echo build.bat clean +echo. +echo Available Backends: +echo sdl - SDL2 (cross-platform) +echo win32 - Win32 API (Windows native) +echo. +echo Available Examples: +for %%f in (%EXAMPLES_DIR%\*.cpp) do echo %%~nf +echo. +echo Examples: +echo build.bat sdl sample1 +echo build.bat win32 sample2 +echo build.bat clean +echo. +exit /b 0 + +:clean +echo Cleaning build files... +if exist "%BUILD_DIR%" ( + rmdir /s /q "%BUILD_DIR%" + echo Clean complete +) else ( + echo Nothing to clean +) +exit /b 0 diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..93608ad --- /dev/null +++ b/build.ps1 @@ -0,0 +1,205 @@ +# build.ps1 - PowerShell build script for libgraffik +# Usage: .\build.ps1 [options] + +param( + [string]$Backend = "", + [string]$Example = "", + [string]$Action = "build", + [switch]$Help, + [switch]$Clean, + [switch]$All, + [switch]$Run +) + +$LIB_DIR = "lib" +$EXAMPLES_DIR = "examples" +$BUILD_DIR = "build" +$CXX = "g++" +$CXXFLAGS = "-std=c++11 -Wall -Wextra -I$LIB_DIR" + +# Colors +function Write-ColorOutput($ForegroundColor) { + $fc = $host.UI.RawUI.ForegroundColor + $host.UI.RawUI.ForegroundColor = $ForegroundColor + if ($args) { + Write-Output $args + } + $host.UI.RawUI.ForegroundColor = $fc +} + +function Show-Help { + Write-Host "" + Write-ColorOutput Cyan "╔════════════════════════════════════════╗" + Write-ColorOutput Cyan "║ libgraffik Build System (PS) ║" + Write-ColorOutput Cyan "╚════════════════════════════════════════╝" + Write-Host "" + Write-ColorOutput Yellow "Usage:" + Write-Host " .\build.ps1 -Backend -Example " + Write-Host " .\build.ps1 -Backend -All" + Write-Host " .\build.ps1 -Clean" + Write-Host "" + Write-ColorOutput Yellow "Available Backends:" + Write-Host " sdl - SDL2 (cross-platform)" + Write-Host " win32 - Win32 API (Windows native)" + Write-Host "" + Write-ColorOutput Yellow "Available Examples:" + Get-ChildItem -Path $EXAMPLES_DIR -Filter "*.cpp" | ForEach-Object { + Write-Host " $($_.BaseName)" + } + Write-Host "" + Write-ColorOutput Yellow "Examples:" + Write-Host " .\build.ps1 -Backend sdl -Example sample1" + Write-Host " .\build.ps1 -Backend win32 -Example sample2" + Write-Host " .\build.ps1 -Backend sdl -Example sample1 -Run" + Write-Host " .\build.ps1 -Backend sdl -All" + Write-Host " .\build.ps1 -Clean" + Write-Host "" +} + +function Build-Example { + param( + [string]$Backend, + [string]$Example + ) + + # Validate backend + if ($Backend -notin @("sdl", "win32")) { + Write-ColorOutput Red "Error: Invalid backend '$Backend'" + Write-Host "Available backends: sdl, win32" + exit 1 + } + + # Validate example + $examplePath = Join-Path $EXAMPLES_DIR "$Example.cpp" + if (-not (Test-Path $examplePath)) { + Write-ColorOutput Red "Error: Example '$Example' not found" + Write-Host "Available examples:" + Get-ChildItem -Path $EXAMPLES_DIR -Filter "*.cpp" | ForEach-Object { + Write-Host " $($_.BaseName)" + } + exit 1 + } + + # Create build directory + if (-not (Test-Path $BUILD_DIR)) { + New-Item -ItemType Directory -Path $BUILD_DIR | Out-Null + } + + # Set backend-specific flags + $backendDefine = "" + $includes = "" + $ldflags = "" + $libs = "" + + if ($Backend -eq "sdl") { + $backendDefine = "-DUSE_SDL" + $SDL2_PATH = if ($env:SDL2_PATH) { $env:SDL2_PATH } else { "C:\SDL2" } + $includes = "-I$SDL2_PATH\include -I$SDL2_PATH\include\SDL2" + $ldflags = "-L$SDL2_PATH\lib" + $libs = "-lmingw32 -lSDL2main -lSDL2 -mwindows" + + # Copy SDL2.dll if needed + $sdlDllSource = if (Test-Path "$LIB_DIR\SDL2.dll") { + "$LIB_DIR\SDL2.dll" + } elseif (Test-Path "$SDL2_PATH\bin\SDL2.dll") { + "$SDL2_PATH\bin\SDL2.dll" + } else { + $null + } + + if ($sdlDllSource -and -not (Test-Path "$BUILD_DIR\SDL2.dll")) { + Copy-Item $sdlDllSource "$BUILD_DIR\SDL2.dll" + Write-ColorOutput Cyan "✓ SDL2.dll copied to build directory" + } + } + elseif ($Backend -eq "win32") { + $backendDefine = "-DUSE_WIN32" + $libs = "-lgdi32 -luser32" + } + + Write-ColorOutput Green "Building $Example with $Backend backend..." + + # Build command + $libSource = Join-Path $LIB_DIR "graphics.cpp" + $outputExe = Join-Path $BUILD_DIR "$Example.exe" + + $buildCmd = "$CXX $CXXFLAGS $backendDefine $includes $examplePath $libSource -o $outputExe $ldflags $libs" + + Write-Host "Command: $buildCmd" + Invoke-Expression $buildCmd + + if ($LASTEXITCODE -eq 0) { + Write-ColorOutput Green "✓ Build successful!" + Write-Host "Output: $outputExe" + return $true + } else { + Write-ColorOutput Red "✗ Build failed!" + return $false + } +} + +function Clean-BuildFiles { + Write-ColorOutput Yellow "Cleaning build files..." + if (Test-Path $BUILD_DIR) { + Remove-Item -Recurse -Force $BUILD_DIR + Write-ColorOutput Green "✓ Clean complete" + } else { + Write-Host "Nothing to clean" + } +} + +# Main script logic +if ($Help) { + Show-Help + exit 0 +} + +if ($Clean) { + Clean-BuildFiles + exit 0 +} + +if ($All) { + if (-not $Backend) { + Write-ColorOutput Red "Error: -Backend required when using -All" + Write-Host "Usage: .\build.ps1 -Backend sdl -All" + exit 1 + } + + Write-ColorOutput Green "Building all examples with $Backend backend..." + $success = $true + + Get-ChildItem -Path $EXAMPLES_DIR -Filter "*.cpp" | ForEach-Object { + Write-Host "" + if (-not (Build-Example -Backend $Backend -Example $_.BaseName)) { + $success = $false + } + } + + Write-Host "" + if ($success) { + Write-ColorOutput Green "✓ All examples built successfully!" + } else { + Write-ColorOutput Red "✗ Some builds failed" + exit 1 + } + exit 0 +} + +if (-not $Backend -or -not $Example) { + Write-ColorOutput Red "Error: -Backend and -Example required" + Write-Host "" + Show-Help + exit 1 +} + +$success = Build-Example -Backend $Backend -Example $Example + +if ($success -and $Run) { + Write-Host "" + Write-ColorOutput Green "Running $Example..." + $exePath = Join-Path $BUILD_DIR "$Example.exe" + & $exePath +} + +exit $(if ($success) { 0 } else { 1 }) -- cgit v1.2.3