Makefile 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. # Standard of Iron - Makefile
  2. # Provides standard targets for building, running, and managing the project
  3. # Default target
  4. .DEFAULT_GOAL := help
  5. # Configuration
  6. BUILD_DIR := build
  7. BINARY_NAME := standard_of_iron
  8. MAP_EDITOR_BINARY := map_editor
  9. DEFAULT_LANG ?= en
  10. # Formatting config
  11. CLANG_FORMAT ?= clang-format
  12. # Try to find qmlformat in common Qt installation paths if not in PATH
  13. QMLFORMAT ?= $(shell command -v qmlformat 2>/dev/null || echo /usr/lib/qt5/bin/qmlformat)
  14. FMT_GLOBS := -name "*.cpp" -o -name "*.c" -o -name "*.h" -o -name "*.hpp"
  15. SHADER_GLOBS := -name "*.frag" -o -name "*.vert"
  16. QML_GLOBS := -name "*.qml"
  17. # Colors for output
  18. BOLD := \033[1m
  19. GREEN := \033[32m
  20. BLUE := \033[34m
  21. YELLOW := \033[33m
  22. RED := \033[31m
  23. RESET := \033[0m
  24. # Help target - shows available commands
  25. .PHONY: help
  26. help:
  27. @echo "$(BOLD)Standard of Iron - Build System$(RESET)"
  28. @echo ""
  29. @echo "$(BOLD)Available targets:$(RESET)"
  30. @echo " $(GREEN)install$(RESET) - Install all dependencies"
  31. @echo " $(GREEN)configure$(RESET) - Configure build with CMake"
  32. @echo " $(GREEN)build$(RESET) - Build the project"
  33. @echo " $(GREEN)run$(RESET) - Run the main application"
  34. @echo " $(GREEN)editor$(RESET) - Run the map editor"
  35. @echo " $(GREEN)clean$(RESET) - Clean build directory"
  36. @echo " $(GREEN)rebuild$(RESET) - Clean and build"
  37. @echo " $(GREEN)test$(RESET) - Run tests (if any)"
  38. @echo " $(GREEN)format$(RESET) - Format all code (C++, QML, shaders)"
  39. @echo " $(GREEN)format-check$(RESET) - Verify formatting (CI-friendly, no changes)"
  40. @echo " $(GREEN)check-deps$(RESET) - Check if dependencies are installed"
  41. @echo " $(GREEN)dev$(RESET) - Set up development environment (install + configure + build)"
  42. @echo " $(GREEN)all$(RESET) - Full build (configure + build)"
  43. @echo ""
  44. @echo "$(BOLD)Examples:$(RESET)"
  45. @echo " make install # Install dependencies"
  46. @echo " make dev # Complete development setup"
  47. @echo " make run # Build and run the game"
  48. @echo " DEFAULT_LANG=de make build # Build with German as default language"
  49. # Install dependencies
  50. .PHONY: install
  51. install:
  52. @echo "$(BOLD)$(BLUE)Installing dependencies...$(RESET)"
  53. @bash scripts/setup-deps.sh --yes
  54. @echo "$(GREEN)✓ Dependencies installed successfully$(RESET)"
  55. # Check if dependencies are installed
  56. .PHONY: check-deps
  57. check-deps:
  58. @echo "$(BOLD)$(BLUE)Checking dependencies...$(RESET)"
  59. @bash scripts/setup-deps.sh --dry-run
  60. # Create build directory
  61. build-dir:
  62. @mkdir -p $(BUILD_DIR)
  63. # Configure build with CMake
  64. .PHONY: configure
  65. configure: build-dir
  66. @echo "$(BOLD)$(BLUE)Configuring build with CMake...$(RESET)"
  67. @cd $(BUILD_DIR) && cmake -DDEFAULT_LANG=$(DEFAULT_LANG) ..
  68. @echo "$(GREEN)✓ Configuration complete$(RESET)"
  69. # Build the project
  70. .PHONY: build
  71. build: configure
  72. @echo "$(BOLD)$(BLUE)Building project...$(RESET)"
  73. @cd $(BUILD_DIR) && make -j$$(nproc)
  74. @echo "$(GREEN)✓ Build complete$(RESET)"
  75. # Build everything (alias for build)
  76. .PHONY: all
  77. all: build
  78. # Run the main application
  79. .PHONY: run
  80. run: build
  81. @echo "$(BOLD)$(BLUE)Running Standard of Iron...$(RESET)"
  82. @cd $(BUILD_DIR) && \
  83. if [ -n "$$DISPLAY" ]; then \
  84. ./$(BINARY_NAME); \
  85. else \
  86. echo "$(YELLOW)No DISPLAY detected; running with QT_QPA_PLATFORM=offscreen$(RESET)"; \
  87. QT_QPA_PLATFORM=offscreen ./$(BINARY_NAME); \
  88. fi
  89. # Run with xvfb for headless environments (software rasterization)
  90. .PHONY: run-headless
  91. run-headless: build
  92. @echo "$(BOLD)$(BLUE)Running Standard of Iron under xvfb...$(RESET)"
  93. @if ! command -v xvfb-run >/dev/null 2>&1; then \
  94. echo "$(YELLOW)xvfb-run not found. Installing...$(RESET)"; \
  95. sudo apt-get update -y >/dev/null 2>&1 && sudo apt-get install -y xvfb >/dev/null 2>&1; \
  96. fi
  97. @cd $(BUILD_DIR) && xvfb-run -s "-screen 0 1280x720x24" ./$(BINARY_NAME)
  98. # Run the map editor
  99. .PHONY: editor
  100. editor: build
  101. @echo "$(BOLD)$(BLUE)Running Map Editor...$(RESET)"
  102. @cd $(BUILD_DIR) && ./tools/map_editor/$(MAP_EDITOR_BINARY)
  103. # Clean build directory
  104. .PHONY: clean
  105. clean:
  106. @echo "$(BOLD)$(YELLOW)Cleaning build directory...$(RESET)"
  107. @rm -rf $(BUILD_DIR)
  108. @echo "$(GREEN)✓ Clean complete$(RESET)"
  109. # Rebuild (clean + build)
  110. .PHONY: rebuild
  111. rebuild: clean build
  112. # Development setup (install + configure + build)
  113. .PHONY: dev
  114. dev: install build
  115. @echo "$(GREEN)✓ Development environment ready!$(RESET)"
  116. @echo "$(BOLD)You can now run:$(RESET)"
  117. @echo " make run # Run the game"
  118. @echo " make editor # Run the map editor"
  119. # Run tests (placeholder for future test implementation)
  120. .PHONY: test
  121. test: build
  122. @echo "$(BOLD)$(BLUE)Running tests...$(RESET)"
  123. @if [ -f "$(BUILD_DIR)/tests" ]; then \
  124. cd $(BUILD_DIR) && ./tests; \
  125. else \
  126. echo "$(YELLOW)No tests found. Test suite not yet implemented.$(RESET)"; \
  127. fi
  128. # ---- Formatting: strip comments first, then format (strict) ----
  129. .PHONY: format format-check
  130. format:
  131. @echo "$(BOLD)$(BLUE)Stripping comments in app/... game/... render/... tools/... ui/...$(RESET)"
  132. @if [ -x scripts/remove-comments.sh ]; then \
  133. ./scripts/remove-comments.sh app/ game/ render/ tools/ ui/; \
  134. elif [ -f scripts/remove-comments.sh ]; then \
  135. bash scripts/remove-comments.sh app/ game/ render/ tools/ ui/; \
  136. else \
  137. echo "$(RED)scripts/remove-comments.sh not found$(RESET)"; exit 1; \
  138. fi
  139. @echo "$(BOLD)$(BLUE)Formatting C/C++ files with clang-format...$(RESET)"
  140. @if command -v $(CLANG_FORMAT) >/dev/null 2>&1; then \
  141. find . -type f \( $(FMT_GLOBS) \) -not -path "./$(BUILD_DIR)/*" -print0 \
  142. | xargs -0 -r $(CLANG_FORMAT) -i --style=file; \
  143. echo "$(GREEN)✓ C/C++ formatting complete$(RESET)"; \
  144. else \
  145. echo "$(RED)clang-format not found. Please install it.$(RESET)"; exit 1; \
  146. fi
  147. @echo "$(BOLD)$(BLUE)Formatting QML files...$(RESET)"
  148. @if command -v $(QMLFORMAT) >/dev/null 2>&1 || [ -x "$(QMLFORMAT)" ]; then \
  149. find . -type f \( $(QML_GLOBS) \) -not -path "./$(BUILD_DIR)/*" -print0 \
  150. | xargs -0 -r $(QMLFORMAT) -i; \
  151. echo "$(GREEN)✓ QML formatting complete$(RESET)"; \
  152. else \
  153. echo "$(YELLOW)⚠ qmlformat not found. Skipping QML formatting.$(RESET)"; \
  154. echo "$(YELLOW) Install qmlformat (from Qt dev tools) to format QML files.$(RESET)"; \
  155. fi
  156. @echo "$(BOLD)$(BLUE)Formatting shader files (.frag, .vert)...$(RESET)"
  157. @if command -v $(CLANG_FORMAT) >/dev/null 2>&1; then \
  158. find . -type f \( $(SHADER_GLOBS) \) -not -path "./$(BUILD_DIR)/*" -print0 \
  159. | xargs -0 -r $(CLANG_FORMAT) -i --style=file; \
  160. echo "$(GREEN)✓ Shader formatting complete$(RESET)"; \
  161. else \
  162. echo "$(YELLOW)⚠ clang-format not found. Shader files not formatted.$(RESET)"; \
  163. fi
  164. @echo "$(GREEN)✓ All formatting complete$(RESET)"
  165. # CI/verification: fail if anything would be reformatted
  166. format-check:
  167. @echo "$(BOLD)$(BLUE)Checking formatting compliance...$(RESET)"
  168. @FAILED=0; \
  169. if command -v $(CLANG_FORMAT) >/dev/null 2>&1; then \
  170. echo "$(BLUE)Checking C/C++ files...$(RESET)"; \
  171. find . -type f \( $(FMT_GLOBS) \) -not -path "./$(BUILD_DIR)/*" -print0 \
  172. | xargs -0 -r $(CLANG_FORMAT) --dry-run -Werror --style=file || FAILED=1; \
  173. echo "$(BLUE)Checking shader files...$(RESET)"; \
  174. find . -type f \( $(SHADER_GLOBS) \) -not -path "./$(BUILD_DIR)/*" -print0 \
  175. | xargs -0 -r $(CLANG_FORMAT) --dry-run -Werror --style=file || FAILED=1; \
  176. else \
  177. echo "$(RED)clang-format not found. Please install it.$(RESET)"; exit 1; \
  178. fi; \
  179. if command -v $(QMLFORMAT) >/dev/null 2>&1 || [ -x "$(QMLFORMAT)" ]; then \
  180. echo "$(BLUE)Checking QML files...$(RESET)"; \
  181. for file in $$(find . -type f \( $(QML_GLOBS) \) -not -path "./$(BUILD_DIR)/*"); do \
  182. $(QMLFORMAT) "$$file" > /tmp/qmlformat_check.tmp 2>/dev/null; \
  183. if ! diff -q "$$file" /tmp/qmlformat_check.tmp >/dev/null 2>&1; then \
  184. echo "$(RED)QML file needs formatting: $$file$(RESET)"; \
  185. FAILED=1; \
  186. fi; \
  187. done; \
  188. rm -f /tmp/qmlformat_check.tmp; \
  189. else \
  190. echo "$(YELLOW)⚠ qmlformat not found. Skipping QML format check.$(RESET)"; \
  191. fi; \
  192. if [ $$FAILED -eq 0 ]; then \
  193. echo "$(GREEN)✓ All formatting checks passed$(RESET)"; \
  194. else \
  195. echo "$(RED)✗ Formatting check failed. Run 'make format' to fix.$(RESET)"; \
  196. exit 1; \
  197. fi
  198. # Debug build
  199. .PHONY: debug
  200. debug: build-dir
  201. @echo "$(BOLD)$(BLUE)Configuring debug build...$(RESET)"
  202. @cd $(BUILD_DIR) && cmake -DCMAKE_BUILD_TYPE=Debug ..
  203. @cd $(BUILD_DIR) && make -j$$(nproc)
  204. @echo "$(GREEN)✓ Debug build complete$(RESET)"
  205. # Release build
  206. .PHONY: release
  207. release: build-dir
  208. @echo "$(BOLD)$(BLUE)Configuring release build...$(RESET)"
  209. @cd $(BUILD_DIR) && cmake -DCMAKE_BUILD_TYPE=Release ..
  210. @cd $(BUILD_DIR) && make -j$$(nproc)
  211. @echo "$(GREEN)✓ Release build complete$(RESET)"
  212. # Show build info
  213. .PHONY: info
  214. info:
  215. @echo "$(BOLD)Project Information:$(RESET)"
  216. @echo " Build directory: $(BUILD_DIR)"
  217. @echo " Binary name: $(BINARY_NAME)"
  218. @echo " Map editor: $(MAP_EDITOR_BINARY)"
  219. @echo " CMake version: $$(cmake --version | head -1)"
  220. @echo " GCC version: $$(gcc --version | head -1)"
  221. @if [ -f "$(BUILD_DIR)/$(BINARY_NAME)" ]; then \
  222. echo " Binary built: $(GREEN)✓$(RESET)"; \
  223. else \
  224. echo " Binary built: $(RED)✗$(RESET)"; \
  225. fi
  226. # Quick start for new developers
  227. .PHONY: quickstart
  228. quickstart:
  229. @echo "$(BOLD)$(GREEN)Quick Start Guide:$(RESET)"
  230. @echo "1. Install dependencies: $(BLUE)make install$(RESET)"
  231. @echo "2. Build the project: $(BLUE)make build$(RESET)"
  232. @echo "3. Run the game: $(BLUE)make run$(RESET)"
  233. @echo ""
  234. @echo "Or use the shortcut: $(BLUE)make dev$(RESET)"