-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
272 lines (247 loc) · 9.05 KB
/
Makefile
File metadata and controls
272 lines (247 loc) · 9.05 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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# lessui-cores - Build libretro cores for ARM devices
# Architecture-based builds for optimal performance
.PHONY: all help docker-build build-% build-all core-% package-% package-all list-cores clean-% clean shell release test update-recipes-% update-recipes-all update-core-%
# Docker configuration
DOCKER_IMAGE := lessui-cores-builder
# Platform: Set PLATFORM=amd64 to force x86_64 (for testing GitHub Actions environment)
# Default: uses native architecture (ARM64 on Apple Silicon, x86_64 elsewhere)
ifdef PLATFORM
DOCKER_PLATFORM := --platform linux/$(PLATFORM)
else
DOCKER_PLATFORM :=
endif
DOCKER_RUN := docker run --rm $(DOCKER_PLATFORM) -v $(PWD):/workspace -w /workspace $(DOCKER_IMAGE)
# CPU families to build (architecture-based variants)
# Building 2 architectures:
# - arm32: ARMv7VE with NEON-VFPv4 (All ARM32 devices)
# - arm64: ARMv8-A with NEON (All ARM64 devices)
CPU_FAMILIES := arm32 arm64
# Build parallelism (default to 8 jobs for optimal build speed)
JOBS ?= 8
# CI mode: Skip docker-build if image already exists (set SKIP_DOCKER_BUILD=1)
SKIP_DOCKER_BUILD ?= 0
# Default target: build and package everything
all: build-all package-all
@echo ""
@echo "=== All Done ==="
@echo "Packages ready in output/dist/"
help:
@echo "lessui-cores - ARM libretro core builder"
@echo ""
@echo "Quick Start:"
@echo " make all Build and package everything"
@echo " make build-arm64 Build cores for one architecture"
@echo ""
@echo "Architectures:"
@echo " make build-arm32 ARMv7VE + NEON-VFPv4 (All ARM32 devices)"
@echo " make build-arm64 ARMv8-A + NEON (All ARM64 devices)"
@echo " make build-all Build both architectures"
@echo ""
@echo "Device Compatibility:"
@echo " ARM32 devices → arm32 (Miyoo Mini/Plus/A30, RG35XX, Trimui Smart)"
@echo " ARM64 devices → arm64 (RG28xx/40xx, CubeXX, Trimui)"
@echo ""
@echo "Single Core Build (for testing/debugging):"
@echo " make core-arm64-gambatte Build just gambatte for arm64"
@echo " make core-arm32-flycast Build just flycast for arm32"
@echo ""
@echo "Packaging:"
@echo " make package-arm64 Create arm64.zip"
@echo " make package-all Create all packages"
@echo ""
@echo "Utilities:"
@echo " make test Run RSpec test suite"
@echo " make list-cores List available cores"
@echo " make clean Clean all build outputs"
@echo " make clean-arm64 Clean specific architecture"
@echo " make clean-cores Delete all cores source directories"
@echo " make clean-cache Delete download cache"
@echo " make shell Open shell in build container"
@echo " make release Create git flow release and trigger build"
@echo " make release FORCE=1 Force recreate today's release"
@echo ""
@echo "Testing GitHub Actions Environment:"
@echo " make docker-build PLATFORM=amd64 Build x86_64 Docker image"
@echo " make build-arm32 PLATFORM=amd64 Test ARM32 cross-compile"
@echo ""
@echo "Recipe Management:"
@echo " make update-recipes-arm64 Update arm64 core commits"
@echo " make update-recipes-arm64 DRY=1 Check for updates (dry-run)"
@echo " make update-core-arm64-gambatte Update specific core"
@echo " make update-core-arm64-gambatte DRY=1 Check specific core (dry-run)"
@echo " make update-recipes-all Update all architectures"
# Build Docker image
docker-build:
@echo "=== Building Docker image ==="
@if [ -n "$(DOCKER_PLATFORM)" ]; then \
echo "Using platform: $(DOCKER_PLATFORM)"; \
fi
docker build $(DOCKER_PLATFORM) -t $(DOCKER_IMAGE) .
@echo "✓ Docker image ready"
# Note: Recipes are now manually maintained YAML files in recipes/linux/
# No automatic generation - edit recipes/*.yml directly to add/update cores
# Generic build target for any CPU family
.PHONY: build-%
build-%:
ifeq ($(SKIP_DOCKER_BUILD),0)
@$(MAKE) docker-build
endif
@echo "=== Building cores for $* ==="
@if [ ! -f recipes/linux/$*.yml ]; then \
echo "ERROR: Recipe not found: recipes/linux/$*.yml"; \
echo "Available recipes: $(CPU_FAMILIES)"; \
exit 1; \
fi
@CORE_COUNT=$$(grep -c "^ [a-z]" recipes/linux/$*.yml | head -1); \
echo "Building cores for $*"
@echo "This will take 1-3 hours..."
@mkdir -p output/$* output/cores-$* output/cache output/logs
$(DOCKER_RUN) ruby scripts/build-all $* -j $(JOBS) -l output/logs/$*-build.log
@echo ""
@echo "✓ Build complete for $*"
@echo " Cores built: $$(ls output/$*/*.so 2>/dev/null | wc -l)"
@du -sh output/$* 2>/dev/null || true
# Build all CPU families
.PHONY: build-all
build-all: $(addprefix build-,$(CPU_FAMILIES))
@echo ""
@echo "=== Build Summary ==="
@for family in $(CPU_FAMILIES); do \
echo " $$family: $$(ls output/$$family/*.so 2>/dev/null | wc -l) cores"; \
done
@echo ""
@echo "Total size:"
@du -sh output/* 2>/dev/null || true
# Build a single core (for testing/debugging)
# Usage: make core-arm64-gambatte
.PHONY: core-%
core-%:
ifeq ($(SKIP_DOCKER_BUILD),0)
@$(MAKE) docker-build
endif
@# Parse pattern: core-<family>-<corename>
@# Handle family names (arm32, arm64)
@FAMILY=$$(echo "$*" | sed -E 's/^(arm[0-9]+)-(.+)$$/\1/'); \
CORE=$$(echo "$*" | sed -E 's/^(arm[0-9]+)-(.+)$$/\2/'); \
echo "=== Building single core: $$CORE for $$FAMILY ==="; \
if [ ! -f recipes/linux/$$FAMILY.yml ]; then \
echo "ERROR: Recipe not found: recipes/linux/$$FAMILY.yml"; \
echo "Available recipes: $(CPU_FAMILIES)"; \
exit 1; \
fi; \
mkdir -p output/$$FAMILY output/cores-$$FAMILY output/cache output/logs; \
$(DOCKER_RUN) ruby scripts/build-one $$FAMILY $$CORE -j $(JOBS)
# Generic package target
.PHONY: package-%
package-%:
@if [ ! -d output/$* ] || [ -z "$$(ls output/$*/*.so 2>/dev/null)" ]; then \
echo "ERROR: No cores built for $*. Run: make build-$*"; \
exit 1; \
fi
@echo "=== Packaging $* cores ==="
@mkdir -p output/dist
@cd output/$* && zip -q ../dist/linux-$*.zip *.so
@echo "✓ Created output/dist/linux-$*.zip ($$(ls -lh output/dist/linux-$*.zip | awk '{print $$5}'))"
# Package all families
.PHONY: package-all
package-all: $(addprefix package-,$(CPU_FAMILIES))
@echo ""
@echo "=== Packaging Summary ==="
@ls -lh output/dist/*.zip 2>/dev/null | awk '{print " " $$9 " - " $$5}'
# List cores in recipes
list-cores:
@echo "=== arm32 cores ==="
@grep -E "^ [a-z]" recipes/linux/arm32.yml | sed 's/://' | awk '{printf " - %s\n", $$1}'
@echo ""
@echo "=== arm64 cores ==="
@grep -E "^ [a-z]" recipes/linux/arm64.yml | sed 's/://' | awk '{printf " - %s\n", $$1}'
@echo ""
@echo "Total: arm32=$$(grep -cE "^ [a-z]" recipes/linux/arm32.yml) cores, arm64=$$(grep -cE "^ [a-z]" recipes/linux/arm64.yml) cores"
# Clean specific CPU family
.PHONY: clean-%
clean-%:
@echo "=== Cleaning $* ==="
rm -rf output/$*
rm -rf output/cores-$*
rm -f output/dist/linux-$*.zip
@echo "✓ Cleaned $* (built cores and source files)"
# Clean downloaded core sources for all CPU families
.PHONY: clean-cores
clean-cores:
@echo "=== Cleaning all CPU-specific core source directories ==="
-rm -rf output/cores-*
@echo "✓ Removed all cores-* directories"
@echo "Note: Core sources will be re-downloaded on next build"
# Clean download cache
.PHONY: clean-cache
clean-cache:
@echo "=== Cleaning download cache ==="
-rm -rf output/cache
@echo "✓ Removed cache directory"
@echo "Note: Tarballs will be re-downloaded on next build"
# Clean everything
clean:
@echo "=== Cleaning all ==="
-rm -rf output
@echo "✓ Cleaned"
# Open interactive shell in build container
shell:
ifeq ($(SKIP_DOCKER_BUILD),0)
@$(MAKE) docker-build
endif
@echo "=== Opening shell in build container ==="
@echo "Debian Buster (GCC 8.3.0, glibc 2.28)"
@echo "Type 'exit' to return"
@echo ""
docker run --rm -it -v $(PWD):/output -w /output $(DOCKER_IMAGE) /bin/bash
# Run tests
.PHONY: test
test:
@echo "=== Running RSpec Tests ==="
@if ! command -v bundle >/dev/null 2>&1; then \
echo "ERROR: bundler not found. Install with: gem install bundler"; \
exit 1; \
fi
@bundle check >/dev/null 2>&1 || bundle install
@bundle exec rspec
# Create a git flow release
.PHONY: release
release:
@if [ "$(FORCE)" = "1" ]; then \
./scripts/release --force; \
else \
./scripts/release; \
fi
# Update recipe commit hashes to latest versions
.PHONY: update-recipes-%
update-recipes-%:
@echo "=== Updating recipes: $* ==="
@if [ "$(DRY)" = "1" ]; then \
./scripts/update-recipes $* --dry-run; \
else \
./scripts/update-recipes $*; \
fi
# Update all recipe families
.PHONY: update-recipes-all
update-recipes-all:
@echo "=== Updating all CPU families ==="
@for family in $(CPU_FAMILIES); do \
echo ""; \
echo "--- $$family ---"; \
if [ "$(DRY)" = "1" ]; then \
./scripts/update-recipes $$family --dry-run; \
else \
./scripts/update-recipes $$family; \
fi; \
done
# Update specific core for specific architecture
.PHONY: update-core-%
update-core-%:
@arch=$$(echo $* | cut -d- -f1); \
core=$$(echo $* | cut -d- -f2-); \
echo "=== Updating: $$arch / $$core ==="; \
if [ "$(DRY)" = "1" ]; then \
./scripts/update-recipes $$arch --core=$$core --dry-run; \
else \
./scripts/update-recipes $$arch --core=$$core; \
fi