forked from eddmann/phpboy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
186 lines (160 loc) · 7.76 KB
/
Makefile
File metadata and controls
186 lines (160 loc) · 7.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
.PHONY: help setup install test lint shell run run-no-jit clean rebuild build-wasm serve-wasm check-sdl install-sdl run-sdl run-sdl-host
help: ## Show this help message
@echo 'Usage: make [target]'
@echo ''
@echo 'Available targets:'
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'
setup: ## Build Docker image with PHP 8.4
docker compose build
rebuild: ## Rebuild Docker image from scratch (no cache)
docker compose build --no-cache
install: ## Install PHP dependencies via Composer in Docker
docker compose run --rm phpboy composer install
test: ## Run PHPUnit tests in Docker
docker compose run --rm phpboy vendor/bin/phpunit
test-roms: ## Run test ROM suite (Blargg, Mooneye, etc.)
docker compose run --rm phpboy vendor/bin/phpunit --testsuite=Integration --no-coverage
lint: ## Run PHPStan static analysis in Docker
docker compose run --rm phpboy php -d memory_limit=512M vendor/bin/phpstan analyse
shell: ## Open bash shell in Docker container
docker compose run --rm phpboy bash
run: ## Run emulator with ROM in Docker with JIT enabled (usage: make run ROM=path/to/rom.gb)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make run ROM=path/to/rom.gb"; \
exit 1; \
fi
docker compose run --rm -it \
-e PHP_INI_SCAN_DIR=/usr/local/etc/php/conf.d:/app/docker/php-jit \
phpboy php -d opcache.jit_buffer_size=100M -d opcache.jit=tracing \
bin/phpboy.php $(ROM)
run-no-jit: ## Run emulator without JIT for baseline performance (usage: make run-no-jit ROM=path/to/rom.gb)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make run-no-jit ROM=path/to/rom.gb"; \
exit 1; \
fi
docker compose run --rm -it phpboy php bin/phpboy.php $(ROM)
debug: ## Run emulator in debug mode (usage: make debug ROM=path/to/rom.gb)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make debug ROM=path/to/rom.gb"; \
exit 1; \
fi
docker compose run --rm -it phpboy php bin/phpboy.php $(ROM) --debug
trace: ## Run emulator with CPU trace (usage: make trace ROM=path/to/rom.gb)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make trace ROM=path/to/rom.gb"; \
exit 1; \
fi
docker compose run --rm phpboy php bin/phpboy.php $(ROM) --trace --headless
clean: ## Remove vendor directory
rm -rf vendor
clean-docker: ## Remove Docker containers and images
docker compose down --rmi all --volumes
profile: ## Run emulator with Xdebug profiling (usage: make profile ROM=path/to/rom.gb FRAMES=1000)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make profile ROM=path/to/rom.gb FRAMES=1000"; \
exit 1; \
fi
@mkdir -p var/profiling
docker compose run --rm -it \
-e XDEBUG_MODE=profile \
-e XDEBUG_CONFIG="profiler_enable=1 profiler_output_dir=/app/var/profiling" \
phpboy php bin/phpboy.php $(ROM) --headless --frames=$(or $(FRAMES),1000)
@echo "Profile data saved to var/profiling/"
@echo "Open with: kcachegrind var/profiling/cachegrind.out.*"
benchmark: ## Run performance benchmark (usage: make benchmark ROM=path/to/rom.gb FRAMES=3600)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make benchmark ROM=path/to/rom.gb FRAMES=3600"; \
exit 1; \
fi
@echo "Running benchmark with $(or $(FRAMES),3600) frames..."
docker compose run --rm -it phpboy php bin/phpboy.php $(ROM) --headless --frames=$(or $(FRAMES),3600) --benchmark
benchmark-jit: ## Run benchmark with JIT enabled (usage: make benchmark-jit ROM=path/to/rom.gb FRAMES=3600)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make benchmark-jit ROM=path/to/rom.gb FRAMES=3600"; \
exit 1; \
fi
@echo "Running benchmark with JIT enabled ($(or $(FRAMES),3600) frames)..."
docker compose run --rm -it \
-e PHP_INI_SCAN_DIR=/usr/local/etc/php/conf.d:/app/docker/php-jit \
phpboy php -d opcache.jit_buffer_size=100M -d opcache.jit=tracing \
bin/phpboy.php $(ROM) --headless --frames=$(or $(FRAMES),3600) --benchmark
memory-profile: ## Run with memory profiling (usage: make memory-profile ROM=path/to/rom.gb FRAMES=1000)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make memory-profile ROM=path/to/rom.gb FRAMES=1000"; \
exit 1; \
fi
docker compose run --rm -it phpboy php -d memory_limit=512M bin/phpboy.php $(ROM) --headless --frames=$(or $(FRAMES),1000) --memory-profile
build-wasm: ## Build WASM distribution for browser
@echo "Building PHPBoy for WebAssembly..."
@if [ ! -d "vendor" ]; then \
echo "Error: vendor directory not found. Run 'make install' first."; \
exit 1; \
fi
@mkdir -p dist/php
@echo "Copying web files..."
@cp -r web/* dist/
@echo "Copying PHP source..."
@cp -r src dist/php/
@cp composer.json dist/php/
@echo "Copying vendor directory..."
@cp -r vendor dist/php/
@echo "Build complete! Output in dist/"
@echo ""
@echo "To serve locally:"
@echo " cd dist && python3 -m http.server 8080"
@echo " or"
@echo " npm install && npm run serve"
serve-wasm: ## Serve WASM build locally (requires Python 3)
@if [ ! -d "dist" ]; then \
echo "Error: dist directory not found. Run 'make build-wasm' first."; \
exit 1; \
fi
@echo "Starting HTTP server on http://localhost:8080"
@cd dist && python3 -m http.server 8080
# SDL2 Native Frontend Targets
check-sdl: ## Check if SDL2 extension is installed
@echo "Checking SDL2 extension..."
@php -m | grep -q sdl && echo "✓ SDL2 extension is installed" || (echo "✗ SDL2 extension not found. See docs/sdl2-setup.md for installation." && exit 1)
@echo "SDL2 version: $$(php -r 'echo SDL_GetVersion();')"
install-sdl: ## Install SDL2 PHP extension (requires sudo)
@echo "Installing SDL2 PHP extension..."
@echo "This requires SDL2 development libraries to be installed first."
@echo ""
@echo "Ubuntu/Debian:"
@echo " sudo apt-get install libsdl2-dev"
@echo ""
@echo "macOS:"
@echo " brew install sdl2"
@echo ""
@echo "After installing SDL2 libraries, run:"
@echo " sudo pecl install sdl-beta"
@echo ""
@echo "Then add 'extension=sdl.so' to your php.ini"
@echo ""
@echo "See docs/sdl2-setup.md for detailed instructions."
run-sdl: ## Run emulator with SDL2 native frontend in Docker (usage: make run-sdl ROM=path/to/rom.gb)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make run-sdl ROM=path/to/rom.gb"; \
exit 1; \
fi
@echo "Note: SDL2 GUI applications typically work better on host. Try: make run-sdl-host ROM=$(ROM)"
docker compose run --rm -it -e DISPLAY=$$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix phpboy php bin/phpboy.php $(ROM) --frontend=sdl
run-sdl-host: ## Run emulator with SDL2 on host (not in Docker) (usage: make run-sdl-host ROM=path/to/rom.gb)
@if [ -z "$(ROM)" ]; then \
echo "Error: ROM parameter is required. Usage: make run-sdl-host ROM=path/to/rom.gb"; \
exit 1; \
fi
@echo "Running SDL2 frontend on host..."
@php -m | grep -q sdl || (echo "Error: SDL2 extension not installed. Run 'make install-sdl' or see docs/sdl2-setup.md" && exit 1)
php bin/phpboy.php $(ROM) --frontend=sdl
test-sdl: ## Test SDL2 installation with simple window
@echo "Testing SDL2 installation..."
@php -m | grep -q sdl || (echo "Error: SDL2 extension not installed." && exit 1)
@php -r '\
if (!extension_loaded("sdl")) { die("SDL not loaded\n"); } \
SDL_Init(SDL_INIT_VIDEO); \
$$w = SDL_CreateWindow("SDL Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN); \
if ($$w) { echo "✓ SDL2 working! Window created.\n"; sleep(2); SDL_DestroyWindow($$w); } \
else { echo "✗ Failed: " . SDL_GetError() . "\n"; } \
SDL_Quit(); \
'