From 69fb5f3cc1eb41b21ff2c2b30a5160e8ca971729 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 3 Dec 2025 07:36:53 +0100 Subject: [PATCH] Migrate to CMake-based build with packaging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major build system refactoring: **CMake (build authority)**: - Auto-discovers .cpp files (GLOB_RECURSE in source/core/ and source/game/) - No manual file list maintenance needed - Excludes source/legacy/ automatically - Generates build/project.h from template **Makefile (simplified wrapper)**: - Delegates compilation to CMake (make → cmake --build build) - Contains 5 release packaging targets: * macos_release: .app bundle + .dmg (Apple Silicon) * linux_release: .tar.gz * windows_release: .zip with .exe + DLLs * windows_cross: cross-compile from Linux/macOS * rpi_release: ARM64 cross-compile - Complex packaging logic preserved (code signing, symlinks, DMG creation) **Benefits**: - Add new .cpp file → automatically compiled (no manual updates) - Single source of truth in CMakeLists.txt (no duplication) - IDE-friendly (VSCode, CLion, etc.) - Complete packaging support (5 platforms) **Files changed**: - CMakeLists.txt: GLOB_RECURSE replaces 23-file hardcoded list - Makefile: Simplified compilation + added 5 release targets (~220 lines) - CLAUDE.md: Updated build system documentation - escena_titol.cpp: Fixed include path (build/project.h → project.h) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CLAUDE.md | 97 +++++-- CMakeLists.txt | 36 +-- Makefile | 388 +++++++++++++++++++-------- source/game/escenes/escena_titol.cpp | 2 +- 4 files changed, 352 insertions(+), 171 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 093d510..9c24149 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -12,59 +12,98 @@ This is **Orni Attack**, an **Asteroids-style game** originally written in **Tur ## Build System -Based on `/home/sergio/gitea/pollo` project structure. +Based on `/home/sergio/gitea/pollo` project structure, now with **CMake as build authority** and **automatic file discovery**. -### Build Commands +### Basic Build Commands ```bash -# Clean + compile -make clean && make +make # Compile (delegates to CMake) +make debug # Debug build +make clean # Clean artifacts +./orni # Run +``` -# Run -./orni +### Release Packaging -# Individual targets -make linux # Linux build -make macos # macOS build -make windows # Windows build (MinGW) +```bash +make macos_release # macOS .app bundle + .dmg (Apple Silicon) +make linux_release # Linux .tar.gz +make windows_release # Windows .zip (requires MinGW on Windows) +make windows_cross # Cross-compile Windows from Linux/macOS +make rpi_release # Raspberry Pi ARM64 cross-compile ``` ### Build Files -- **CMakeLists.txt** - CMake configuration (C++20, SDL3, project metadata) -- **Makefile** - Cross-platform wrapper, extracts project info from CMakeLists.txt +- **CMakeLists.txt** - CMake configuration (C++20, SDL3, auto-discovers .cpp files) +- **Makefile** - Wrapper for compilation + complex packaging recipes - **source/project.h.in** - Template for auto-generated project.h - **build/project.h** - Auto-generated (by CMake) with project constants -- **release/** - Platform-specific resources (icons, .rc, .plist) +- **release/** - Platform-specific resources (icons, .rc, .plist, frameworks, DLLs) + +### Architecture: Hybrid CMake + Makefile + +**CMake handles**: Compilation (simple, standard, IDE-friendly) +- Auto-discovers all `.cpp` files in `source/core/` and `source/game/` +- Excludes `source/legacy/` automatically +- Generates `build/project.h` from template +- Links SDL3 + +**Makefile handles**: Packaging (complex bash scripts) +- Delegates compilation to CMake (`make` → `cmake --build build`) +- Contains 5 release packaging targets (macOS, Linux, Windows, RPI, Windows-cross) +- Includes: code signing, framework symlinks, DMG creation, cross-compilation ### Project Metadata System -**Auto-generation with CMake**: +**Single source of truth** in `CMakeLists.txt`: -CMake generates `build/project.h` from `source/project.h.in` template on every compilation: +```cmake +project(orni VERSION 0.3.0) +set(PROJECT_LONG_NAME "Orni Attack") +set(PROJECT_COPYRIGHT "© 1999 Visente i Sergi, 2025 Port") +``` + +**Auto-generated** `build/project.h`: ```cpp -// build/project.h (generated automatically) namespace Project { - constexpr const char* NAME = "orni"; // From project(orni ...) - constexpr const char* LONG_NAME = "Orni Attack"; // From PROJECT_LONG_NAME - constexpr const char* VERSION = "0.1.0"; // From VERSION - constexpr const char* COPYRIGHT = "© 1999..."; // From PROJECT_COPYRIGHT - constexpr const char* GIT_HASH = "abc1234"; // From git rev-parse + constexpr const char* NAME = "orni"; + constexpr const char* LONG_NAME = "Orni Attack"; + constexpr const char* VERSION = "0.3.0"; + constexpr const char* COPYRIGHT = "© 1999 Visente i Sergi, 2025 Port"; + constexpr const char* GIT_HASH = "abc1234"; // From git rev-parse } ``` -**Window title format** (dynamic, in sdl_manager.cpp): -```cpp -std::format("{} v{} ({})", - Project::LONG_NAME, // "Orni Attack" - Project::VERSION, // "0.1.0" - Project::COPYRIGHT) // "© 1999 Visente i Sergi, 2025 Port" +**Window title** (dynamic): `Orni Attack v0.3.0 (© 1999 Visente i Sergi, 2025 Port)` + +### File Discovery + +**Automatic** - no manual maintenance needed: + +```cmake +# CMakeLists.txt automatically finds: +file(GLOB_RECURSE CORE_SOURCES "source/core/*.cpp") +file(GLOB_RECURSE GAME_SOURCES "source/game/*.cpp") +# + source/main.cpp +# - source/legacy/* (excluded) ``` -Result: `Orni Attack v0.1.0 (© 1999 Visente i Sergi, 2025 Port)` +**When you create a new file** like `source/game/entities/asteroide.cpp`: +1. Just create it in the appropriate directory +2. Run `make` +3. CMake automatically detects and compiles it -**Single source of truth**: All project info in CMakeLists.txt, no hardcoded strings. +**No need to edit** Makefile or CMakeLists.txt! + +### Cross-Platform Notes + +- **macOS**: Requires `create-dmg` (auto-installed via Homebrew) +- **Windows**: Compile natively with MinGW or use `make windows_cross` on Linux/macOS +- **Windows cross**: Requires `x86_64-w64-mingw32-g++` toolchain +- **RPI cross**: Requires `aarch64-linux-gnu-g++` toolchain +- **Frameworks**: macOS release includes SDL3.xcframework with symlink recreation ## Architecture diff --git a/CMakeLists.txt b/CMakeLists.txt index d497514..675ad3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,33 +31,23 @@ endif() # Configurar archivo de versión configure_file(${CMAKE_SOURCE_DIR}/source/project.h.in ${CMAKE_BINARY_DIR}/project.h @ONLY) -# --- LISTA DE FUENTES --- +# --- LISTA DE FUENTES (AUTO-DESCUBRIMIENTO) --- +# Buscar automáticamente todos los archivos .cpp en core/, game/ y main.cpp +file(GLOB_RECURSE CORE_SOURCES "${CMAKE_SOURCE_DIR}/source/core/*.cpp") +file(GLOB_RECURSE GAME_SOURCES "${CMAKE_SOURCE_DIR}/source/game/*.cpp") set(APP_SOURCES + ${CORE_SOURCES} + ${GAME_SOURCES} source/main.cpp - source/core/system/director.cpp - source/core/system/global_events.cpp - source/core/rendering/sdl_manager.cpp - source/core/rendering/line_renderer.cpp - source/core/rendering/color_oscillator.cpp - source/core/rendering/polygon_renderer.cpp - source/core/rendering/primitives.cpp - source/core/rendering/shape_renderer.cpp - source/core/graphics/shape.cpp - source/core/graphics/shape_loader.cpp - source/core/graphics/vector_text.cpp - source/core/graphics/starfield.cpp - source/core/audio/audio.cpp - source/core/audio/audio_cache.cpp - source/game/options.cpp - source/game/escenes/escena_logo.cpp - source/game/escenes/escena_titol.cpp - source/game/escenes/escena_joc.cpp - source/game/entities/nau.cpp - source/game/entities/bala.cpp - source/game/entities/enemic.cpp - source/game/effects/debris_manager.cpp ) +# Excluir archivos legacy (código Pascal de referencia) +list(FILTER APP_SOURCES EXCLUDE REGEX ".*/legacy/.*") + +# Log de archivos encontrados (útil para debug) +list(LENGTH APP_SOURCES APP_SOURCES_COUNT) +message(STATUS "Archivos .cpp encontrados: ${APP_SOURCES_COUNT}") + # Configuración de SDL3 find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3) message(STATUS "SDL3 encontrado: ${SDL3_INCLUDE_DIRS}") diff --git a/Makefile b/Makefile index c8dfd7a..40c9568 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,15 @@ TARGET_FILE := $(DIR_BIN)$(TARGET_NAME) RELEASE_FOLDER := $(TARGET_NAME)_release RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME) +# Release file names +RAW_VERSION := $(shell echo $(VERSION) | sed 's/^v//') +WINDOWS_RELEASE := $(TARGET_NAME)-$(VERSION)-windows-x64.zip +MACOS_ARM_RELEASE := $(TARGET_NAME)-$(VERSION)-macos-arm64.dmg +MACOS_INTEL_RELEASE := $(TARGET_NAME)-$(VERSION)-macos-x64.dmg +LINUX_RELEASE := $(TARGET_NAME)-$(VERSION)-linux-x64.tar.gz +RPI_RELEASE := $(TARGET_NAME)-$(VERSION)-rpi-arm64.tar.gz +APP_NAME := $(LONG_NAME) + # ============================================================================== # VERSION # ============================================================================== @@ -32,75 +41,21 @@ endif # ============================================================================== # SOURCE FILES # ============================================================================== -APP_SOURCES := \ - source/main.cpp \ - source/core/system/director.cpp \ - source/core/system/global_events.cpp \ - source/core/audio/audio.cpp \ - source/core/audio/audio_cache.cpp \ - source/core/rendering/sdl_manager.cpp \ - source/core/rendering/line_renderer.cpp \ - source/core/rendering/color_oscillator.cpp \ - source/core/rendering/polygon_renderer.cpp \ - source/core/rendering/primitives.cpp \ - source/core/rendering/shape_renderer.cpp \ - source/core/graphics/shape.cpp \ - source/core/graphics/shape_loader.cpp \ - source/core/graphics/vector_text.cpp \ - source/core/graphics/starfield.cpp \ - source/game/options.cpp \ - source/game/escenes/escena_logo.cpp \ - source/game/escenes/escena_titol.cpp \ - source/game/escenes/escena_joc.cpp \ - source/game/entities/nau.cpp \ - source/game/entities/bala.cpp \ - source/game/entities/enemic.cpp \ - source/game/effects/debris_manager.cpp +# Note: Source files are now auto-discovered by CMake using GLOB_RECURSE +# No need to maintain this list manually anymore! # ============================================================================== -# INCLUDES +# PLATFORM-SPECIFIC UTILITIES # ============================================================================== -INCLUDES := -Isource -Ibuild - -# ============================================================================== -# COMPILER FLAGS (OS-specific) -# ============================================================================== -CPP_STANDARD := c++20 - ifeq ($(OS),Windows_NT) - # Windows (MinGW) - FixPath = $(subst /,\\,$1) - CXX := g++ - CXXFLAGS := -std=$(CPP_STANDARD) -Wall -O2 -ffunction-sections -fdata-sections \ - -Wl,--gc-sections -static-libstdc++ -static-libgcc \ - -Wl,-subsystem,windows -DWINDOWS_BUILD - CXXFLAGS_DEBUG := -std=$(CPP_STANDARD) -Wall -g -D_DEBUG -DWINDOWS_BUILD - LDFLAGS := -lmingw32 -lSDL3 - WINDRES := windres - RESOURCE_FILE := release/orni.res - RM := del /Q + RMFILE := del /Q RMDIR := rmdir /S /Q MKDIR := mkdir else - # Unix-like systems (Linux/macOS) - FixPath = $1 - CXX := g++ - CXXFLAGS := -std=$(CPP_STANDARD) -Wall -O2 - CXXFLAGS_DEBUG := -std=$(CPP_STANDARD) -Wall -g -D_DEBUG - LDFLAGS := -lSDL3 RMFILE := rm -f RMDIR := rm -rf MKDIR := mkdir -p - UNAME_S := $(shell uname -s) - ifeq ($(UNAME_S),Linux) - CXXFLAGS += -DLINUX_BUILD - CXXFLAGS_DEBUG += -DLINUX_BUILD - endif - ifeq ($(UNAME_S),Darwin) - CXXFLAGS += -arch arm64 -Wno-deprecated -DMACOS_BUILD - CXXFLAGS_DEBUG += -arch arm64 -Wno-deprecated -DMACOS_BUILD - endif endif # ============================================================================== @@ -108,72 +63,258 @@ endif # ============================================================================== .PHONY: all clean debug help backup -# Default target +# ============================================================================== +# BUILD TARGETS (delegate to CMake) +# ============================================================================== + +# Default target: build with CMake all: $(TARGET_FILE) -# Generate build/project.h from template -.PHONY: generate_project_h -generate_project_h: - @$(MKDIR) build 2>/dev/null || true - @echo "Generating build/project.h..." -ifeq ($(OS),Windows_NT) - @powershell -Command \ - "$$name = '$(TARGET_NAME)'; \ - $$long = '$(LONG_NAME)'; \ - $$ver = '$(VERSION)'.TrimStart('v'); \ - $$copy = (Get-Content CMakeLists.txt | Where-Object {$$_ -match 'PROJECT_COPYRIGHT'} | ForEach-Object {if ($$_ -match '\"(.+)\"') {$$matches[1]}}); \ - $$hash = try {git rev-parse --short=7 HEAD 2>$$null} catch {'unknown'}; \ - (Get-Content source/project.h.in) -replace '@PROJECT_NAME@', $$name -replace '@PROJECT_LONG_NAME@', $$long -replace '@PROJECT_VERSION@', $$ver -replace '@PROJECT_COPYRIGHT@', $$copy -replace '@GIT_HASH@', $$hash | Set-Content build/project.h" -else - @PROJECT_COPYRIGHT=$$(grep 'PROJECT_COPYRIGHT' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/'); \ - PROJECT_VERSION=$$(echo $(VERSION) | sed 's/^v//'); \ - GIT_HASH=$$(git rev-parse --short=7 HEAD 2>/dev/null || echo "unknown"); \ - sed -e "s/@PROJECT_NAME@/$(TARGET_NAME)/g" \ - -e "s/@PROJECT_LONG_NAME@/$(LONG_NAME)/g" \ - -e "s/@PROJECT_VERSION@/$${PROJECT_VERSION}/g" \ - -e "s/@PROJECT_COPYRIGHT@/$${PROJECT_COPYRIGHT}/g" \ - -e "s/@GIT_HASH@/$${GIT_HASH}/g" \ - source/project.h.in > build/project.h -endif - @echo "build/project.h generated successfully" - -# Compile executable -$(TARGET_FILE): generate_project_h $(APP_SOURCES) -ifeq ($(OS),Windows_NT) - @if not exist build $(MKDIR) build - @if not exist release\\orni.res $(WINDRES) release\\orni.rc -O coff -o release\\orni.res - $(CXX) $(CXXFLAGS) $(INCLUDES) $(APP_SOURCES) $(RESOURCE_FILE) $(LDFLAGS) -o $(TARGET_FILE).exe -else - @$(MKDIR) build - $(CXX) $(CXXFLAGS) $(INCLUDES) $(APP_SOURCES) $(LDFLAGS) -o $(TARGET_FILE) -endif - @echo Compilation successful: $(TARGET_FILE) +$(TARGET_FILE): + @cmake -B build -DCMAKE_BUILD_TYPE=Release + @cmake --build build + @echo "Build successful: $(TARGET_FILE)" # Debug build -debug: generate_project_h $(APP_SOURCES) -ifeq ($(OS),Windows_NT) - @if not exist build $(MKDIR) build - $(CXX) $(CXXFLAGS_DEBUG) $(INCLUDES) $(APP_SOURCES) $(LDFLAGS) -o $(TARGET_FILE)_debug.exe -else - @$(MKDIR) build - $(CXX) $(CXXFLAGS_DEBUG) $(INCLUDES) $(APP_SOURCES) $(LDFLAGS) -o $(TARGET_FILE)_debug -endif - @echo Debug build successful: $(TARGET_FILE)_debug +debug: + @cmake -B build -DCMAKE_BUILD_TYPE=Debug + @cmake --build build + @echo "Debug build successful: $(TARGET_FILE)_debug" + +# ============================================================================== +# RELEASE PACKAGING TARGETS +# ============================================================================== + +# macOS Release (Apple Silicon) +.PHONY: macos_release +macos_release: + @echo "Creating macOS release - Version: $(VERSION)" + + # Check/install create-dmg + @command -v create-dmg >/dev/null || (echo "Installing create-dmg..." && brew install create-dmg) + + # Clean previous releases + @$(RMDIR) "$(RELEASE_FOLDER)" 2>/dev/null || true + @$(RMDIR) Frameworks 2>/dev/null || true + @$(RMFILE) "$(MACOS_ARM_RELEASE)" 2>/dev/null || true + + # Create .app structure + @$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks" + @$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS" + @$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources" + @$(MKDIR) Frameworks + + # Copy resources + @cp -r resources "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources/" + @ditto release/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework" + @ditto release/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework Frameworks/SDL3.framework + + # Recreate framework symlinks (may be broken) + @cd Frameworks/SDL3.framework && rm -f SDL3 Headers Resources && \ + ln -s Versions/Current/SDL3 SDL3 && \ + ln -s Versions/Current/Headers Headers && \ + ln -s Versions/Current/Resources Resources + @cd Frameworks/SDL3.framework/Versions && rm -f Current && ln -s A Current + @cd "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework" && rm -f SDL3 Headers Resources && \ + ln -s Versions/Current/SDL3 SDL3 && \ + ln -s Versions/Current/Headers Headers && \ + ln -s Versions/Current/Resources Resources + @cd "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework/Versions" && rm -f Current && ln -s A Current + + @cp release/icon.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources/" + @cp release/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/" + @cp LICENSE "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: LICENSE not found" + @cp README.md "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: README.md not found" + + # Update Info.plist version + @echo "Updating Info.plist with version $(RAW_VERSION)..." + @sed -i '' '/CFBundleShortVersionString<\/key>/{n;s|.*|$(RAW_VERSION)|;}' \ + "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist" + @sed -i '' '/CFBundleVersion<\/key>/{n;s|.*|$(RAW_VERSION)|;}' \ + "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist" + + # Compile for Apple Silicon using CMake + @cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64 + @cmake --build build + @cp $(TARGET_FILE) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)" + + # Code sign + @codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app" || echo "Warning: Code signing failed" + + # Create DMG + @echo "Creating DMG for Apple Silicon..." + @create-dmg \ + --volname "$(APP_NAME)" \ + --window-pos 200 120 \ + --window-size 720 300 \ + --icon-size 96 \ + --text-size 12 \ + --icon "$(APP_NAME).app" 278 102 \ + --app-drop-link 115 102 \ + --hide-extension "$(APP_NAME).app" \ + "$(MACOS_ARM_RELEASE)" \ + "$(RELEASE_FOLDER)" || true + @echo "✓ macOS release created: $(MACOS_ARM_RELEASE)" + + # Cleanup + @$(RMDIR) Frameworks + @$(RMDIR) "$(RELEASE_FOLDER)" + +# Linux Release +.PHONY: linux_release +linux_release: + @echo "Creating Linux release - Version: $(VERSION)" + + # Clean previous + @$(RMDIR) "$(RELEASE_FOLDER)" + @$(RMFILE) "$(LINUX_RELEASE)" + + # Create folder + @$(MKDIR) "$(RELEASE_FOLDER)" + + # Copy resources + @cp -r resources "$(RELEASE_FOLDER)/" + @cp LICENSE "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: LICENSE not found" + @cp README.md "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: README.md not found" + + # Compile with CMake + @cmake -B build -DCMAKE_BUILD_TYPE=Release + @cmake --build build + @cp $(TARGET_FILE) "$(RELEASE_FILE)" + @strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded || strip "$(RELEASE_FILE)" + + # Package + @tar -czf "$(LINUX_RELEASE)" -C "$(RELEASE_FOLDER)" . + @echo "✓ Linux release created: $(LINUX_RELEASE)" + + # Cleanup + @$(RMDIR) "$(RELEASE_FOLDER)" + +# Windows Release (requires MinGW on Windows or cross-compiler on Linux) +.PHONY: windows_release +windows_release: + @echo "Creating Windows release - Version: $(VERSION)" + @echo "Note: This target should be run on Windows with MinGW or use windows_cross on Linux" + + # Clean previous + @$(RMDIR) "$(RELEASE_FOLDER)" + @$(RMFILE) "$(WINDOWS_RELEASE)" + + # Create folder + @$(MKDIR) "$(RELEASE_FOLDER)" + + # Copy resources + @cp -r resources "$(RELEASE_FOLDER)/" + @cp release/dll/*.dll "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: DLLs not found" + @cp LICENSE "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: LICENSE not found" + @cp README.md "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: README.md not found" + + # Compile resource file + @windres release/$(TARGET_NAME).rc -O coff -o release/$(TARGET_NAME).res 2>/dev/null || echo "Warning: windres failed" + + # Compile with CMake + @cmake -B build -DCMAKE_BUILD_TYPE=Release + @cmake --build build + @cp $(TARGET_FILE).exe "$(RELEASE_FILE).exe" || cp $(TARGET_FILE) "$(RELEASE_FILE).exe" + + # Package + @cd "$(RELEASE_FOLDER)" && zip -r ../$(WINDOWS_RELEASE) * + @echo "✓ Windows release created: $(WINDOWS_RELEASE)" + + # Cleanup + @$(RMDIR) "$(RELEASE_FOLDER)" + +# Raspberry Pi Release (cross-compilation from Linux/macOS) +.PHONY: rpi_release +rpi_release: + @echo "Creating Raspberry Pi ARM64 release - Version: $(VERSION)" + @echo "Note: Requires aarch64-linux-gnu-g++ cross-compiler" + + # Check for cross-compiler + @command -v aarch64-linux-gnu-g++ >/dev/null || (echo "Error: aarch64-linux-gnu-g++ not found" && exit 1) + + # Clean previous + @$(RMDIR) "$(RELEASE_FOLDER)" + @$(RMFILE) "$(RPI_RELEASE)" + + # Create folder + @$(MKDIR) "$(RELEASE_FOLDER)" + + # Copy resources + @cp -r resources "$(RELEASE_FOLDER)/" + @cp LICENSE "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: LICENSE not found" + @cp README.md "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: README.md not found" + + # Note: Cross-compilation with CMake is complex, would need toolchain file + @echo "Warning: RPI cross-compilation requires manual setup with CMake toolchain file" + @echo "Falling back to direct g++ compilation..." + @aarch64-linux-gnu-g++ -std=c++20 -Wall -O2 -DLINUX_BUILD -DRPI_BUILD \ + -Isource -Ibuild \ + $$(find source/core source/game -name "*.cpp") source/main.cpp \ + -lSDL3 -o "$(RELEASE_FILE)" || echo "Error: Compilation failed" + @aarch64-linux-gnu-strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded || true + + # Package + @tar -czf "$(RPI_RELEASE)" -C "$(RELEASE_FOLDER)" . + @echo "✓ Raspberry Pi release created: $(RPI_RELEASE)" + + # Cleanup + @$(RMDIR) "$(RELEASE_FOLDER)" + +# Windows Cross-compilation (from Linux/macOS) +.PHONY: windows_cross +windows_cross: + @echo "Cross-compiling for Windows from $(UNAME_S) - Version: $(VERSION)" + + # Check for cross-compiler + @command -v x86_64-w64-mingw32-g++ >/dev/null || (echo "Error: x86_64-w64-mingw32-g++ not found" && exit 1) + + # Clean previous + @$(RMDIR) "$(RELEASE_FOLDER)" + @$(RMFILE) "$(WINDOWS_RELEASE)" + + # Create folder + @$(MKDIR) "$(RELEASE_FOLDER)" + + # Copy resources + @cp -r resources "$(RELEASE_FOLDER)/" + @cp release/dll/*.dll "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: DLLs not found in release/dll/" + @cp LICENSE "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: LICENSE not found" + @cp README.md "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: README.md not found" + + # Compile resource file + @x86_64-w64-mingw32-windres release/$(TARGET_NAME).rc -O coff -o release/$(TARGET_NAME).res 2>/dev/null || echo "Warning: windres failed" + + # Cross-compile + @echo "Compiling with MinGW cross-compiler..." + @x86_64-w64-mingw32-g++ -std=c++20 -Wall -O2 -DWINDOWS_BUILD -DRELEASE_BUILD \ + -static-libstdc++ -static-libgcc -Wl,-subsystem,windows \ + -Isource -Ibuild \ + $$(find source/core source/game -name "*.cpp") source/main.cpp \ + release/$(TARGET_NAME).res \ + -lmingw32 -lSDL3 -o "$(RELEASE_FILE).exe" || echo "Error: Compilation failed" + @x86_64-w64-mingw32-strip "$(RELEASE_FILE).exe" || true + + # Package + @cd "$(RELEASE_FOLDER)" && zip -r ../$(WINDOWS_RELEASE) * + @echo "✓ Windows cross-compiled release created: $(WINDOWS_RELEASE)" + + # Cleanup + @$(RMDIR) "$(RELEASE_FOLDER)" # Clean build artifacts clean: ifeq ($(OS),Windows_NT) - @if exist $(call FixPath,$(TARGET_FILE).exe) $(RM) $(call FixPath,$(TARGET_FILE).exe) - @if exist $(call FixPath,$(TARGET_FILE)_debug.exe) $(RM) $(call FixPath,$(TARGET_FILE)_debug.exe) + @if exist $(call FixPath,$(TARGET_FILE).exe) $(RMFILE) $(call FixPath,$(TARGET_FILE).exe) + @if exist $(call FixPath,$(TARGET_FILE)_debug.exe) $(RMFILE) $(call FixPath,$(TARGET_FILE)_debug.exe) @if exist build $(RMDIR) build @if exist $(RELEASE_FOLDER) $(RMDIR) $(RELEASE_FOLDER) else - @$(RMFILE) $(TARGET_FILE) - @$(RMFILE) $(TARGET_FILE)_debug - @$(RMDIR) build - @$(RMDIR) $(RELEASE_FOLDER) + @$(RMFILE) $(TARGET_FILE) $(TARGET_FILE)_debug + @$(RMDIR) build $(RELEASE_FOLDER) + @$(RMFILE) *.dmg *.zip *.tar.gz 2>/dev/null || true endif - @echo Clean complete + @echo "Clean complete" # Backup to remote server backup: @@ -191,14 +332,25 @@ backup: # Help target help: @echo "Available targets:" - @echo " all - Build the game (default)" - @echo " debug - Build with debug symbols" - @echo " clean - Remove build artifacts" - @echo " backup - Backup project to remote server" - @echo " help - Show this help message" + @echo "" + @echo "Build:" + @echo " all - Build the game (default, delegates to CMake)" + @echo " debug - Build with debug symbols" + @echo " clean - Remove build artifacts and release packages" + @echo "" + @echo "Release Packaging:" + @echo " macos_release - Create macOS .app bundle + .dmg (Apple Silicon)" + @echo " linux_release - Create Linux .tar.gz" + @echo " windows_release - Create Windows .zip (requires MinGW on Windows)" + @echo " windows_cross - Cross-compile Windows from Linux/macOS (requires MinGW)" + @echo " rpi_release - Cross-compile for Raspberry Pi ARM64" + @echo "" + @echo "Other:" + @echo " backup - Backup project to remote server" + @echo " help - Show this help message" @echo "" @echo "Current configuration:" + @echo " Project: $(LONG_NAME)" @echo " Target: $(TARGET_NAME)" @echo " Version: $(VERSION)" @echo " Platform: $(UNAME_S)" - @echo " C++ Standard: $(CPP_STANDARD)" diff --git a/source/game/escenes/escena_titol.cpp b/source/game/escenes/escena_titol.cpp index 0be706e..c2989cc 100644 --- a/source/game/escenes/escena_titol.cpp +++ b/source/game/escenes/escena_titol.cpp @@ -9,7 +9,7 @@ #include "../../core/audio/audio.hpp" #include "../../core/system/gestor_escenes.hpp" #include "../../core/system/global_events.hpp" -#include "build/project.h" +#include "project.h" EscenaTitol::EscenaTitol(SDLManager& sdl) : sdl_(sdl),