alineat amb AEEA: cmake, makefile, clang-* i hooks

This commit is contained in:
2026-05-19 08:48:25 +02:00
parent 79d6e71fff
commit 851e6d35a2
11 changed files with 612 additions and 1423 deletions
+285 -325
View File
@@ -1,380 +1,340 @@
# ==============================================================================
# DIRECTORIES
# ==============================================================================
DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST)))
DIR_SOURCES := $(addprefix $(DIR_ROOT), source/)
DIR_BIN := $(DIR_ROOT)
PROJECT := orni
BUILDDIR := build
# ==============================================================================
# TARGET NAMES
# ==============================================================================
# Detecció de plataforma. En Windows CMake defaulteja a "NMake Makefiles"
# (que requereix Visual Studio); forcem MinGW Makefiles per usar el g++ de
# MinGW. nproc tampoc existeix en cmd.exe → fem servir NUMBER_OF_PROCESSORS.
ifeq ($(OS),Windows_NT)
TARGET_NAME := $(shell powershell -Command "(Select-String -Path 'CMakeLists.txt' -Pattern 'project\s*\x28(\w+)').Matches.Groups[1].Value")
LONG_NAME := $(shell powershell -Command "(Select-String -Path 'CMakeLists.txt' -Pattern 'PROJECT_LONG_NAME\s+\x22(.+?)\x22').Matches.Groups[1].Value")
ifneq ($(MSYSTEM),)
NULDEV := /dev/null
else
NULDEV := NUL
endif
JOBS ?= $(NUMBER_OF_PROCESSORS)
HAS_NINJA := $(shell ninja --version 2>$(NULDEV))
ifneq ($(HAS_NINJA),)
CMAKE_GEN := -G "Ninja"
else
CMAKE_GEN := -G "MinGW Makefiles"
endif
else
TARGET_NAME := $(shell awk '/^project/ {gsub(/[)(]/, " "); print $$2}' CMakeLists.txt)
LONG_NAME := $(shell grep 'PROJECT_LONG_NAME' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/')
NULDEV := /dev/null
JOBS ?= $(shell nproc 2>/dev/null || echo 4)
HAS_NINJA := $(shell ninja --version 2>/dev/null)
ifneq ($(HAS_NINJA),)
CMAKE_GEN := -G "Ninja"
else
CMAKE_GEN :=
endif
endif
TARGET_FILE := $(DIR_BIN)$(TARGET_NAME)
RELEASE_FOLDER := $(TARGET_NAME)_release
RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME)
# ==============================================================================
# VERSION
# ==============================================================================
# VERSION (única font de veritat: CMakeLists.txt project(...) VERSION ...).
# Lazy (=): només es calcula quan s'invoca un target que la usa.
ifeq ($(OS),Windows_NT)
VERSION := v$(shell powershell -Command "(Select-String -Path 'CMakeLists.txt' -Pattern 'project.*VERSION\s+([0-9.]+)').Matches.Groups[1].Value")
VERSION = v$(shell powershell -Command "(Select-String -Path 'CMakeLists.txt' -Pattern 'project.*VERSION\s+([0-9.]+)').Matches.Groups[1].Value")
else
VERSION := v$(shell grep "^project" CMakeLists.txt | tr -cd 0-9.)
VERSION = v$(shell grep '^project' CMakeLists.txt | sed -E 's/.*VERSION[[:space:]]+([0-9.]+).*/\1/')
endif
# Release file names (depend on VERSION, so must come after)
ifeq ($(OS),Windows_NT)
RAW_VERSION := $(shell powershell -Command "\"$(VERSION)\" -replace '^v', ''")
else
RAW_VERSION := $(shell echo $(VERSION) | sed 's/^v//')
# GIT_HASH calculat al host i passat a CMake (evita problemes si CMake corre en
# entorns sense accés a git).
GIT_HASH := $(shell git rev-parse --short=7 HEAD 2>$(NULDEV))
ifeq ($(GIT_HASH),)
GIT_HASH := unknown
endif
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)
CMAKE_DEFS := -DGIT_HASH=$(GIT_HASH)
# ==============================================================================
# SOURCE FILES
# RELEASE — variables d'empaquetat per distribució
# ==============================================================================
# Note: Source files are now auto-discovered by CMake using GLOB_RECURSE
# No need to maintain this list manually anymore!
APP_NAME := Orni Attack
DIST_DIR := dist
RELEASE_FOLDER := $(DIST_DIR)/_tmp
TARGET_FILE := $(BUILDDIR)/$(PROJECT)
RELEASE_FILE := $(RELEASE_FOLDER)/$(PROJECT)
# ==============================================================================
# PLATFORM-SPECIFIC UTILITIES
# ==============================================================================
# Use Unix commands always (MinGW Make uses bash even on Windows)
RMFILE := rm -f
RMDIR := rm -rf
MKDIR := mkdir -p
# Noms dels artefactes finals (amb VERSION i PROJECT)
WINDOWS_RELEASE := $(DIST_DIR)/$(PROJECT)-$(VERSION)-win32-x64.zip
MACOS_APPLE_SILICON_RELEASE := $(DIST_DIR)/$(PROJECT)-$(VERSION)-macos-apple-silicon.dmg
LINUX_RELEASE := $(DIST_DIR)/$(PROJECT)-$(VERSION)-linux.tar.gz
# Variables específiques de Windows (PowerShell). El subst escapa apòstrofs.
ifeq ($(OS),Windows_NT)
# Windows-specific: Force cmd.exe shell for PowerShell commands
SHELL := cmd.exe
WIN_TARGET_FILE := $(BUILDDIR)/$(APP_NAME)
WIN_RELEASE_FILE := $(RELEASE_FOLDER)/$(APP_NAME)
WIN_RELEASE_FILE_PS := $(subst ','',$(WIN_RELEASE_FILE))
UNAME_S :=
else
# Unix-specific
UNAME_S := $(shell uname -s)
WIN_TARGET_FILE := $(TARGET_FILE)
WIN_RELEASE_FILE := $(RELEASE_FILE)
WIN_RELEASE_FILE_PS := $(WIN_RELEASE_FILE)
UNAME_S := $(shell uname -s)
endif
# Helpers cross-platform.
ifeq ($(OS),Windows_NT)
RMFILE := del /Q
RMDIR := rmdir /S /Q
MKDIR := mkdir
else
RMFILE := rm -f
RMDIR := rm -rdf
MKDIR := mkdir -p
endif
.PHONY: all debug release _windows-release _macos-release _linux-release \
run run-debug clean rebuild show-version pack \
format format-check tidy tidy-fix cppcheck hooks-install help
# ==============================================================================
# COMPILACIÓ
# ==============================================================================
# make → Release (binari d'ús normal)
# make debug → Debug
# make release → Release + empaquetat per a distribució (zip/dmg/tar.gz segons SO)
# ==============================================================================
all:
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) -j$(JOBS)
debug:
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Debug $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) -j$(JOBS)
run: all
@./$(BUILDDIR)/$(PROJECT)
run-debug: debug
@./$(BUILDDIR)/$(PROJECT)
# Release + empaquetat: detecta el SO i delega al sub-target corresponent.
release:
ifeq ($(OS),Windows_NT)
@"$(MAKE)" _windows-release
else
ifeq ($(UNAME_S),Darwin)
@$(MAKE) _macos-release
else
@$(MAKE) _linux-release
endif
endif
# ==============================================================================
# PACKING TOOL
# RELEASE — Linux (.tar.gz)
# ==============================================================================
PACK_TOOL := tools/pack_resources/pack_resources
_linux-release:
@echo "Creando release para Linux - Version: $(VERSION)"
# ==============================================================================
# DEFAULT GOAL
# ==============================================================================
.DEFAULT_GOAL := all
# Compila Release (genera resources.pack i binari)
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) -j$(JOBS)
.PHONY: pack_tool resources.pack
pack_tool:
@make -C tools/pack_resources
resources.pack: pack_tool
@echo "Creating resources.pack..."
@./$(PACK_TOOL) data resources.pack
# ==============================================================================
# TARGETS
# ==============================================================================
.PHONY: all clean debug help backup
# ==============================================================================
# BUILD TARGETS (delegate to CMake)
# ==============================================================================
# Default target: build with CMake + resources
all: resources.pack $(TARGET_FILE)
$(TARGET_FILE):
@cmake -B build -DCMAKE_BUILD_TYPE=Release
@cmake --build build
@echo "Build successful: $(TARGET_FILE)"
# Debug build
debug: resources.pack
@cmake -B build -DCMAKE_BUILD_TYPE=Debug
@cmake --build build
@echo "Debug build successful: $(TARGET_FILE)"
# ==============================================================================
# RELEASE PACKAGING TARGETS
# ==============================================================================
# macOS Release (Apple Silicon)
.PHONY: macos_release
macos_release: pack_tool resources.pack
@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
# Recrea la carpeta temporal
@$(MKDIR) "$(DIST_DIR)" 2>/dev/null || true
@$(RMDIR) "$(RELEASE_FOLDER)" 2>/dev/null || true
@$(RMDIR) Frameworks 2>/dev/null || true
@$(RMFILE) "$(MACOS_ARM_RELEASE)" 2>/dev/null || true
$(MKDIR) "$(RELEASE_FOLDER)"
# 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
# Còpia de fitxers
cp $(BUILDDIR)/resources.pack "$(RELEASE_FOLDER)"
cp README.md "$(RELEASE_FOLDER)"
@[ -f LICENSE ] && cp LICENSE "$(RELEASE_FOLDER)" || true
cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
# Copy resources.pack to Resources
@cp resources.pack "$(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
# Empaqueta a .tar.gz
$(RMFILE) "$(LINUX_RELEASE)"
tar -czvf "$(LINUX_RELEASE)" -C "$(RELEASE_FOLDER)" .
@echo "Release creado: $(LINUX_RELEASE)"
# 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
# Neteja la carpeta temporal
$(RMDIR) "$(RELEASE_FOLDER)"
@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 and names
@echo "Updating Info.plist with version $(RAW_VERSION) and names..."
@sed -i '' '/<key>CFBundleShortVersionString<\/key>/{n;s|<string>.*</string>|<string>$(RAW_VERSION)</string>|;}' \
"$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
@sed -i '' '/<key>CFBundleVersion<\/key>/{n;s|<string>.*</string>|<string>$(RAW_VERSION)</string>|;}' \
"$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
@sed -i '' '/<key>CFBundleExecutable<\/key>/{n;s|<string>.*</string>|<string>$(TARGET_NAME)</string>|;}' \
"$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
@sed -i '' '/<key>CFBundleName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' \
"$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
@sed -i '' '/<key>CFBundleDisplayName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' \
"$(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 \
--icon "LICENSE" 441 102 \
--icon "README.md" 604 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: pack_tool resources.pack
@echo "Creating Linux release - Version: $(VERSION)"
@echo "Note: SDL3 must be installed on the target system (libsdl3-dev)"
# Clean previous
@$(RMDIR) "$(RELEASE_FOLDER)"
@$(RMFILE) "$(LINUX_RELEASE)"
# Create folder
@$(MKDIR) "$(RELEASE_FOLDER)"
# Copy resources
@cp resources.pack "$(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: pack_tool resources.pack
# ==============================================================================
# RELEASE — Windows (.zip)
# ==============================================================================
_windows-release:
@echo off
@echo Creating Windows release - Version: $(VERSION)
@powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
@powershell if (Test-Path "$(WINDOWS_RELEASE)") {Remove-Item "$(WINDOWS_RELEASE)"}
@powershell if (-not (Test-Path "$(RELEASE_FOLDER)")) {New-Item "$(RELEASE_FOLDER)" -ItemType Directory}
@powershell Copy-Item -Path "resources.pack" -Destination "$(RELEASE_FOLDER)"
@powershell Copy-Item "release\dll\SDL3.dll" -Destination "$(RELEASE_FOLDER)"
@powershell Copy-Item "release\dll\libwinpthread-1.dll" -Destination "$(RELEASE_FOLDER)"
@powershell if (Test-Path "LICENSE") {Copy-Item "LICENSE" -Destination "$(RELEASE_FOLDER)"}
@powershell if (Test-Path "README.md") {Copy-Item "README.md" -Destination "$(RELEASE_FOLDER)"}
@windres release/$(TARGET_NAME).rc -O coff -o release/$(TARGET_NAME).res 2>nul || echo Warning: windres failed
@cmake -B build -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
@cmake --build build
@powershell if (Test-Path "$(TARGET_FILE).exe") {Copy-Item "$(TARGET_FILE).exe" -Destination "$(RELEASE_FILE).exe"} else {Copy-Item "$(TARGET_FILE)" -Destination "$(RELEASE_FILE).exe"}
@strip "$(RELEASE_FILE).exe" 2>nul || echo Warning: strip not available
@powershell Compress-Archive -Path "$(RELEASE_FOLDER)\*" -DestinationPath "$(WINDOWS_RELEASE)" -Force
@echo Release created: $(WINDOWS_RELEASE)
@powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
@echo Creando release para Windows - Version: $(VERSION)
# 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"
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) -j$(JOBS)
# Check for cross-compiler
@command -v aarch64-linux-gnu-g++ >/dev/null || (echo "Error: aarch64-linux-gnu-g++ not found" && exit 1)
@powershell -Command "if (-not (Test-Path '$(DIST_DIR)')) {New-Item '$(DIST_DIR)' -ItemType Directory}"
@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"
@powershell -Command "if (-not (Test-Path '$(RELEASE_FOLDER)')) {New-Item '$(RELEASE_FOLDER)' -ItemType Directory}"
# Clean previous
@$(RMDIR) "$(RELEASE_FOLDER)"
@$(RMFILE) "$(RPI_RELEASE)"
@powershell -Command "Copy-Item -Path '$(BUILDDIR)/resources.pack' -Destination '$(RELEASE_FOLDER)'"
@powershell -Command "if (Test-Path 'LICENSE') { Copy-Item 'LICENSE' -Destination '$(RELEASE_FOLDER)' }"
@powershell -Command "Copy-Item 'README.md' -Destination '$(RELEASE_FOLDER)'"
@powershell -Command "if (Test-Path 'release\dll') { Copy-Item 'release\dll\*.dll' -Destination '$(RELEASE_FOLDER)' }"
@powershell -Command "Copy-Item -Path '$(TARGET_FILE).exe' -Destination '$(WIN_RELEASE_FILE_PS).exe'"
strip -s -R .comment -R .gnu.version "$(WIN_RELEASE_FILE).exe" --strip-unneeded
# Create folder
@$(MKDIR) "$(RELEASE_FOLDER)"
@powershell -Command "if (Test-Path '$(WINDOWS_RELEASE)') {Remove-Item '$(WINDOWS_RELEASE)'}"
@powershell -Command "Compress-Archive -Path '$(RELEASE_FOLDER)/*' -DestinationPath '$(WINDOWS_RELEASE)'"
@echo Release creado: $(WINDOWS_RELEASE)
# Copy resources
@cp resources.pack "$(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"
@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"
# 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
# ==============================================================================
# RELEASE — macOS (.dmg per Apple Silicon)
# ==============================================================================
_macos-release:
@echo "Creando release para macOS - Version: $(VERSION)"
# Package
@tar -czf "$(RPI_RELEASE)" -C "$(RELEASE_FOLDER)" .
@echo "✓ Raspberry Pi release created: $(RPI_RELEASE)"
# Verificar/instal·lar create-dmg si cal
@which create-dmg > /dev/null || (echo "Instalando create-dmg..." && brew install create-dmg)
# Cleanup
@$(RMDIR) "$(RELEASE_FOLDER)"
# Compila la versió Apple Silicon
@cmake -S . -B $(BUILDDIR)/arm $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
-DMACOS_BUNDLE=ON $(CMAKE_DEFS)
@cmake --build $(BUILDDIR)/arm -j$(JOBS)
# Windows Cross-compilation (from Linux/macOS)
.PHONY: windows_cross
windows_cross:
@echo "Cross-compiling for Windows from $(UNAME_S) - Version: $(VERSION)"
# Neteja artefactes anteriors
@$(MKDIR) "$(DIST_DIR)" 2>/dev/null || true
$(RMDIR) "$(RELEASE_FOLDER)" 2>/dev/null || true
$(RMFILE) "$(DIST_DIR)"/rw.* 2>/dev/null || true
$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"
# Check for cross-compiler
@command -v x86_64-w64-mingw32-g++ >/dev/null || (echo "Error: x86_64-w64-mingw32-g++ not found" && exit 1)
# Crea l'estructura del bundle .app
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
# Clean previous
@$(RMDIR) "$(RELEASE_FOLDER)"
@$(RMFILE) "$(WINDOWS_RELEASE)"
# Còpia de recursos i metadades del bundle
cp $(BUILDDIR)/arm/resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
cp -R release/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
cp release/icon.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
cp release/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents"
@[ -f LICENSE ] && cp LICENSE "$(RELEASE_FOLDER)" || true
cp README.md "$(RELEASE_FOLDER)"
# Create folder
@$(MKDIR) "$(RELEASE_FOLDER)"
# Recreate framework symlinks (Versions/Current i top-level)
@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
# Copy resources
@cp resources.pack "$(RELEASE_FOLDER)/"
@cp release/dll/SDL3.dll release/dll/libwinpthread-1.dll "$(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"
# Actualitza Info.plist amb VERSION i metadades
@echo "Actualizando Info.plist con versión $(VERSION)..."
@RAW_VERSION=$$(echo "$(VERSION)" | sed 's/^v//'); \
sed -i '' '/<key>CFBundleShortVersionString<\/key>/{n;s|<string>.*</string>|<string>'"$$RAW_VERSION"'</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
sed -i '' '/<key>CFBundleVersion<\/key>/{n;s|<string>.*</string>|<string>'"$$RAW_VERSION"'</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
sed -i '' '/<key>CFBundleExecutable<\/key>/{n;s|<string>.*</string>|<string>$(PROJECT)</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
sed -i '' '/<key>CFBundleName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
sed -i '' '/<key>CFBundleDisplayName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
# 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"
# Còpia del binari al bundle
cp "$(BUILDDIR)/arm/$(PROJECT)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(PROJECT)"
# 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
# Firma ad-hoc del bundle
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
# Package
@cd "$(RELEASE_FOLDER)" && zip -r ../$(WINDOWS_RELEASE) *
@echo "✓ Windows cross-compiled release created: $(WINDOWS_RELEASE)"
# Empaqueta el .dmg
@echo "Creando DMG Apple Silicon con iconos de 96x96..."
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 \
--icon "LICENSE" 441 102 \
--icon "README.md" 604 102 \
--app-drop-link 115 102 \
--hide-extension "$(APP_NAME).app" \
"$(MACOS_APPLE_SILICON_RELEASE)" \
"$(RELEASE_FOLDER)" || true
@echo "Release Apple Silicon creado: $(MACOS_APPLE_SILICON_RELEASE)"
# Cleanup
@$(RMDIR) "$(RELEASE_FOLDER)"
# Neteja temporals
$(RMDIR) "$(RELEASE_FOLDER)"
$(RMDIR) $(BUILDDIR)/arm
$(RMFILE) "$(DIST_DIR)"/rw.* 2>/dev/null || true
show-version:
@echo "$(PROJECT) $(VERSION) ($(GIT_HASH))"
# Clean build artifacts
clean:
ifeq ($(OS),Windows_NT)
@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) $(TARGET_FILE)_debug
@$(RMDIR) build $(RELEASE_FOLDER)
@$(RMFILE) *.dmg *.zip *.tar.gz 2>/dev/null || true
@$(RMFILE) resources.pack 2>/dev/null || true
@make -C tools/pack_resources clean 2>/dev/null || true
endif
@echo "Clean complete"
@rm -rf $(BUILDDIR) $(DIST_DIR)
# Backup to remote server
backup:
@echo "Backing up project to maverick:/home/sergio/git-backup/orni..."
rsync -a --delete \
--exclude='build/' \
--exclude='*.o' \
--exclude='*.exe' \
--exclude='orni' \
--exclude='orni_debug' \
--exclude='*_release/' \
$(DIR_ROOT) maverick:/home/sergio/git-backup/orni/
@echo "Backup completed successfully"
rebuild: clean all
# Help target
# Empaqueta data/ a $(BUILDDIR)/resources.pack. Força un rebuild del pack encara
# que res no hagi canviat dins data/. L'empaquetat també es fa automàticament a
# cada `make`/`make debug` via el target CMake `resource_pack`.
pack:
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) --target pack_resources
@./$(BUILDDIR)/pack_resources data $(BUILDDIR)/resources.pack
# ==============================================================================
# CODE QUALITY (delegats a cmake)
# ==============================================================================
format:
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) --target format
format-check:
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) --target format-check
tidy:
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) --target tidy
tidy-fix:
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) --target tidy-fix
cppcheck:
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
@cmake --build $(BUILDDIR) --target cppcheck
# ==============================================================================
# GIT HOOKS
# ==============================================================================
hooks-install:
@git config core.hooksPath .githooks
@echo "Git hooks activats: $(shell pwd)/.githooks"
# ==============================================================================
# AJUDA
# ==============================================================================
help:
@echo "Available targets:"
@echo "Makefile per a $(PROJECT)"
@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 " Compilació:"
@echo " make - Compilar amb cmake (Release)"
@echo " make debug - Compilar amb cmake (Debug)"
@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 " Execució:"
@echo " make run - Compilar (Release) i executar"
@echo " make run-debug - Compilar (Debug) i executar"
@echo ""
@echo "Other:"
@echo " backup - Backup project to remote server"
@echo " help - Show this help message"
@echo " Release:"
@echo " make release - Release + empaquetat (zip/dmg/tar.gz segons SO)"
@echo ""
@echo "Current configuration:"
@echo " Project: $(LONG_NAME)"
@echo " Target: $(TARGET_NAME)"
@echo " Version: $(VERSION)"
@echo " Platform: $(UNAME_S)"
@echo " Recursos:"
@echo " make pack - Empaquetar data/ a $(BUILDDIR)/resources.pack"
@echo ""
@echo " Qualitat de codi:"
@echo " make format - Formatar codi amb clang-format"
@echo " make format-check - Verificar format sense modificar"
@echo " make tidy - Anàlisi estàtic amb clang-tidy"
@echo " make tidy-fix - Anàlisi estàtic amb auto-fix"
@echo " make cppcheck - Anàlisi estàtic amb cppcheck"
@echo ""
@echo " Altres:"
@echo " make clean - Esborrar $(BUILDDIR)/ i $(DIST_DIR)/"
@echo " make rebuild - clean + all"
@echo " make show-version - Mostrar versió"
@echo " make hooks-install - Activar git hooks del projecte"
@echo ""
@echo " Versió actual: $(VERSION) ($(GIT_HASH))"