# ============================================================================== # DIRECTORIES # ============================================================================== DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST))) DIR_SOURCES := $(addprefix $(DIR_ROOT), source/) DIR_BIN := $(DIR_ROOT) # ============================================================================== # TARGET NAMES # ============================================================================== ifeq ($(OS),Windows_NT) TARGET_NAME := $(shell powershell -Command "$$line = Get-Content CMakeLists.txt | Where-Object {$$_ -match '^project'}; if ($$line -match 'project\s*\x28(\w+)') { $$matches[1] }") LONG_NAME := $(shell powershell -Command "$$line = Get-Content CMakeLists.txt | Where-Object {$$_ -match 'PROJECT_LONG_NAME'}; if ($$line -match '\"(.+)\"') { $$matches[1] }") else TARGET_NAME := $(shell awk '/^project/ {gsub(/[)(]/, " "); print $$2}' CMakeLists.txt) LONG_NAME := $(shell grep 'PROJECT_LONG_NAME' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/') endif 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 # ============================================================================== ifeq ($(OS),Windows_NT) VERSION := v$(shell powershell -Command "$$line = Get-Content CMakeLists.txt | Where-Object {$$_ -match '^project'}; if ($$line -match 'VERSION\s+([0-9.]+)') { $$matches[1] }") else VERSION := v$(shell grep "^project" CMakeLists.txt | tr -cd 0-9.) endif # ============================================================================== # SOURCE FILES # ============================================================================== # Note: Source files are now auto-discovered by CMake using GLOB_RECURSE # No need to maintain this list manually anymore! # ============================================================================== # PLATFORM-SPECIFIC UTILITIES # ============================================================================== ifeq ($(OS),Windows_NT) RMFILE := del /Q RMDIR := rmdir /S /Q MKDIR := mkdir else RMFILE := rm -f RMDIR := rm -rf MKDIR := mkdir -p UNAME_S := $(shell uname -s) endif # ============================================================================== # PACKING TOOL # ============================================================================== PACK_TOOL := tools/pack_resources/pack_resources # ============================================================================== # DEFAULT GOAL # ============================================================================== .DEFAULT_GOAL := all .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 @$(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.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 # 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 \ --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: @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) $(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" # 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" # Help target help: @echo "Available targets:" @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)"