PROJECT := orni BUILDDIR := build # 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) 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 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 # 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") else VERSION = v$(shell grep '^project' CMakeLists.txt | sed -E 's/.*VERSION[[:space:]]+([0-9.]+).*/\1/') endif # 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 CMAKE_DEFS := -DGIT_HASH=$(GIT_HASH) # ============================================================================== # RELEASE — variables d'empaquetat per distribució # ============================================================================== APP_NAME := Orni Attack DIST_DIR := dist RELEASE_FOLDER := $(DIST_DIR)/_tmp TARGET_FILE := $(BUILDDIR)/$(PROJECT) RELEASE_FILE := $(RELEASE_FOLDER)/$(PROJECT) # 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) WIN_TARGET_FILE := $(BUILDDIR)/$(APP_NAME) WIN_RELEASE_FILE := $(RELEASE_FOLDER)/$(APP_NAME) WIN_RELEASE_FILE_PS := $(subst ','',$(WIN_RELEASE_FILE)) UNAME_S := else 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 controllerdb \ format format-check tidy tidy-fix cppcheck hooks-install help # Còpia del gamecontrollerdb.txt (si existeix) al directori de build, perquè # director.cpp el resolgui via resource_base = directori de l'executable. # Silenciós si el fitxer no existeix (l'usuari encara no ha fet `make controllerdb`). ifeq ($(OS),Windows_NT) CP_CONTROLLERDB = @powershell -Command "if (Test-Path 'gamecontrollerdb.txt') { Copy-Item 'gamecontrollerdb.txt' -Destination '$(BUILDDIR)' -Force }" else CP_CONTROLLERDB = @if [ -f gamecontrollerdb.txt ]; then cp gamecontrollerdb.txt $(BUILDDIR)/; fi endif # ============================================================================== # 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) $(CP_CONTROLLERDB) debug: @cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Debug $(CMAKE_DEFS) @cmake --build $(BUILDDIR) -j$(JOBS) $(CP_CONTROLLERDB) 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 # ============================================================================== # RELEASE — Linux (.tar.gz) # ============================================================================== _linux-release: @echo "Creando release para Linux - Version: $(VERSION)" # Compila Release (genera resources.pack i binari) @cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS) @cmake --build $(BUILDDIR) -j$(JOBS) # Recrea la carpeta temporal @$(MKDIR) "$(DIST_DIR)" 2>/dev/null || true @$(RMDIR) "$(RELEASE_FOLDER)" 2>/dev/null || true $(MKDIR) "$(RELEASE_FOLDER)" # Còpia de fitxers cp $(BUILDDIR)/resources.pack "$(RELEASE_FOLDER)" cp gamecontrollerdb.txt "$(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 # Empaqueta a .tar.gz $(RMFILE) "$(LINUX_RELEASE)" tar -czvf "$(LINUX_RELEASE)" -C "$(RELEASE_FOLDER)" . @echo "Release creado: $(LINUX_RELEASE)" # Neteja la carpeta temporal $(RMDIR) "$(RELEASE_FOLDER)" # ============================================================================== # RELEASE — Windows (.zip) # ============================================================================== _windows-release: @echo off @echo Creando release para Windows - Version: $(VERSION) @cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS) @cmake --build $(BUILDDIR) -j$(JOBS) @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}" @powershell -Command "Copy-Item -Path '$(BUILDDIR)/resources.pack' -Destination '$(RELEASE_FOLDER)'" @powershell -Command "Copy-Item 'gamecontrollerdb.txt' -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\windows\dll') { Copy-Item 'release\windows\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 @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) @powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}" # ============================================================================== # RELEASE — macOS (.dmg per Apple Silicon) # ============================================================================== _macos-release: @echo "Creando release para macOS - Version: $(VERSION)" # Verificar/instal·lar create-dmg si cal @which create-dmg > /dev/null || (echo "Instalando create-dmg..." && brew install create-dmg) # Compila la versió Apple Silicon @cmake -S . -B $(BUILDDIR)/arm $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=13.3 \ -DMACOS_BUNDLE=ON $(CMAKE_DEFS) @cmake --build $(BUILDDIR)/arm -j$(JOBS) # 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)" # 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" # Còpia de recursos i metadades del bundle cp $(BUILDDIR)/arm/resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources" cp gamecontrollerdb.txt "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources" cp -R release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks" cp release/icons/icon.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources" cp release/macos/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents" @[ -f LICENSE ] && cp LICENSE "$(RELEASE_FOLDER)" || true cp README.md "$(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 # Actualitza Info.plist amb VERSION i metadades @echo "Actualizando Info.plist con versión $(VERSION)..." @RAW_VERSION=$$(echo "$(VERSION)" | sed 's/^v//'); \ 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"; \ sed -i '' '/CFBundleExecutable<\/key>/{n;s|.*|$(PROJECT)|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \ sed -i '' '/CFBundleName<\/key>/{n;s|.*|$(APP_NAME)|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \ sed -i '' '/CFBundleDisplayName<\/key>/{n;s|.*|$(APP_NAME)|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist" # Còpia del binari al bundle cp "$(BUILDDIR)/arm/$(PROJECT)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(PROJECT)" # Firma ad-hoc del bundle codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app" # 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)" # Neteja temporals $(RMDIR) "$(RELEASE_FOLDER)" $(RMDIR) $(BUILDDIR)/arm $(RMFILE) "$(DIST_DIR)"/rw.* 2>/dev/null || true show-version: @echo "$(PROJECT) $(VERSION) ($(GIT_HASH))" clean: @rm -rf $(BUILDDIR) $(DIST_DIR) rebuild: clean all # 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 # ============================================================================== # DESCÀRREGA DE GAMECONTROLLERDB # ============================================================================== # Descarrega l'última versió de gamecontrollerdb.txt (mappings de gamepads # mantinguts per la comunitat) a l'arrel del projecte. SDL el carrega via # filesystem real (no dins resources.pack) i s'ha de copiar al costat del binari # en cada build (gestionat per CP_CONTROLLERDB a `all`/`debug` i pels release targets). controllerdb: @echo "Descargando gamecontrollerdb.txt..." curl -fsSL https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/master/gamecontrollerdb.txt \ -o gamecontrollerdb.txt @echo "gamecontrollerdb.txt actualizado" # ============================================================================== # 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 "Makefile per a $(PROJECT)" @echo "" @echo " Compilació:" @echo " make - Compilar amb cmake (Release)" @echo " make debug - Compilar amb cmake (Debug)" @echo "" @echo " Execució:" @echo " make run - Compilar (Release) i executar" @echo " make run-debug - Compilar (Debug) i executar" @echo "" @echo " Release:" @echo " make release - Release + empaquetat (zip/dmg/tar.gz segons SO)" @echo "" @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))"