-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathMakefile
More file actions
321 lines (286 loc) · 13.9 KB
/
Copy pathMakefile
File metadata and controls
321 lines (286 loc) · 13.9 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
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
.PHONY: all clean test test-unit test-interpreter check-thread-test-sources check-thread-regex-test-sources test-threads test-threads-regex test-threads-release test-threads-ecosystem test-bundled-modules test-cpan-distroprefs test-exiftool test-all test-gradle test-gradle-unit test-gradle-all test-gradle-parallel test-maven-parallel build run wrapper check-java-gradle dev ci sbom sbom-java sbom-perl sbom-clean check-links
THREAD_DIST_DIRS := perl5/dist/threads/t perl5/dist/threads-shared/t perl5/dist/Thread-Queue/t perl5/dist/Thread-Semaphore/t
THREAD_PLATFORM_TESTS := \
perl5/dist/threads/t/end.t \
perl5/dist/threads/t/exit.t \
perl5/dist/threads/t/free.t \
perl5/dist/threads/t/free2.t \
perl5/dist/threads/t/join.t \
perl5/dist/threads/t/kill.t \
perl5/dist/threads/t/kill2.t \
perl5/dist/threads/t/kill3.t \
perl5/dist/threads/t/stack.t \
perl5/dist/threads/t/stack_env.t \
perl5/dist/threads/t/state.t \
perl5/dist/threads/t/zz_deadlock.t \
perl5/dist/threads-shared/t/cond.t \
perl5/dist/threads-shared/t/wait.t \
perl5/dist/threads-shared/t/waithires.t \
perl5/dist/Thread-Queue/t/09_ended.t \
perl5/dist/Thread-Queue/t/10_timed.t \
perl5/dist/Thread-Semaphore/t/04_nonblocking.t \
perl5/dist/Thread-Semaphore/t/06_timed.t
THREAD_REGEX_ANCHOR_TESTS := \
perl5_t/t/re/pat_psycho_thr.t \
perl5_t/t/re/pat_special_cc_thr.t \
perl5_t/t/re/reg_email_thr.t \
perl5_t/t/re/stclass_threads.t \
perl5_t/t/re/user_prop_race_thr.t
all: build
# CI build - optimized for CI/CD environments
ci: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat build --no-daemon --stacktrace
else
./gradlew build --no-daemon --stacktrace
endif
# Check Java/Gradle compatibility and fix if needed
# For Java 25+, we need Gradle 9.1.0+ (see https://docs.gradle.org/current/userguide/compatibility.html)
# Note: On Windows CI, Make uses Git Bash, so we use bash-compatible syntax throughout
# Note: We modify gradle-wrapper.properties directly because older gradle can't run on Java 25+
check-java-gradle:
@JAVA_MAJOR=$$(java -version 2>&1 | head -1 | sed -E 's/.*version "([0-9]+).*/\1/'); \
case "$$JAVA_MAJOR" in ''|*[!0-9]*) \
echo "ERROR: PerlOnJava requires Java 24 or later (found: $${JAVA_MAJOR:-unavailable})."; \
exit 1; \
esac; \
if [ "$$JAVA_MAJOR" -lt 24 ]; then \
echo "ERROR: PerlOnJava requires Java 24 or later (found: $${JAVA_MAJOR:-unavailable})."; \
exit 1; \
fi; \
if [ "$$JAVA_MAJOR" -ge 25 ] 2>/dev/null; then \
echo "Java $$JAVA_MAJOR detected - ensuring Gradle 9.1+ compatibility..."; \
rm -rf ~/.gradle/wrapper/dists/gradle-8.* ~/.gradle/wrapper/dists/gradle-9.0* 2>/dev/null || true; \
GRADLE_MAJOR=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-([0-9]+)\..*/\1/'); \
GRADLE_MINOR=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-[0-9]+\.([0-9]+).*/\1/'); \
if [ "$$GRADLE_MAJOR" -lt 9 ] 2>/dev/null || ([ "$$GRADLE_MAJOR" -eq 9 ] 2>/dev/null && [ "$$GRADLE_MINOR" -lt 1 ] 2>/dev/null); then \
echo "Updating gradle-wrapper.properties to use Gradle 9.1.0 (current: $$GRADLE_MAJOR.$$GRADLE_MINOR)..."; \
sed -i.bak 's|gradle-[0-9][0-9]*\.[0-9][0-9]*[^/]*-bin\.zip|gradle-9.1.0-bin.zip|' gradle/wrapper/gradle-wrapper.properties && rm -f gradle/wrapper/gradle-wrapper.properties.bak; \
fi; \
elif [ ! -f ./gradlew ]; then \
gradle wrapper || true; \
fi
wrapper: check-java-gradle
# Standard build - incremental compilation with parallel tests (5 JVMs; last shard isolates heavy tests)
build: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat classes testUnitParallel --parallel shadowJar
else
./gradlew classes testUnitParallel --parallel shadowJar
endif
# `make dev` is disabled on purpose.
#
# It used to be a "build without running tests" shortcut, but that is
# precisely what makes it dangerous: it lets changes land on a branch
# without having ever been exercised by the unit test suite. Agents
# (and humans in a hurry) reach for `make dev` to iterate faster and
# then forget to run `make` before pushing, so regressions sneak in.
#
# Use `make` (the default target) instead: it builds *and* runs the
# fast unit tests. If you really need a no-test build for a very
# specific reason, invoke Gradle directly (`./gradlew shadowJar`) and
# own the consequences.
dev:
@echo "ERROR: 'make dev' is disabled on purpose."
@echo ""
@echo " It skipped the unit tests, which caused regressions to slip"
@echo " into commits. Please use 'make' (which builds + tests) for"
@echo " everyday iteration."
@echo ""
@echo " If you truly need a no-test build, invoke Gradle directly:"
@echo " ./gradlew shadowJar installDist"
@exit 1
# Default test target - fast unit tests using perl_test_runner.pl
test: test-unit
# Fast unit tests only (from src/test/resources/unit/ directory)
# Uses Gradle's testUnitParallel (same as default make build)
test-unit: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat testUnitParallel --parallel
else
./gradlew testUnitParallel --parallel
endif
# Unit tests using bytecode interpreter backend (feature parity check)
test-interpreter:
@echo "Running unit tests with bytecode interpreter..."
JPERL_INTERPRETER=1 perl dev/tools/perl_test_runner.pl --jobs 8 --timeout 60 --output test_interpreter_results.json src/test/resources/unit
# Verify the unchanged upstream test distributions are available. GitHub CI
# sparse-checks them out at the compatibility-corpus commit recorded below;
# local developers normally use their adjacent/gitignored perl5 source tree.
check-thread-test-sources:
@for dir in $(THREAD_DIST_DIRS); do \
if [ ! -d "$$dir" ]; then \
echo "Error: $$dir is missing."; \
echo "Clone Perl commit de80c8ecd40c6d5b677847699e5482b44bc748c6 into ./perl5 before running the thread gates."; \
exit 1; \
fi; \
done
check-thread-regex-test-sources:
@for file in $(THREAD_REGEX_ANCHOR_TESTS); do \
if [ ! -f "$$file" ]; then \
echo "Error: $$file is missing."; \
echo "Import the pinned Perl core tests into ./perl5_t before running the regex-thread gate."; \
exit 1; \
fi; \
done
# Permanent Perl ithread compatibility gate used by Ubuntu pull-request CI.
# Full upstream distributions run on both backends with the default virtual
# carrier; lifecycle, stack, signal, wait, timeout, and deadlock coverage also
# runs on the platform carrier. Reports are retained under build/reports/threads.
test-threads: check-java-gradle check-thread-test-sources
@mkdir -p build/reports/threads
JPERL_THREAD_MODE=virtual perl dev/tools/perl_test_runner.pl --strict-exit --jobs 8 --timeout 300 --output build/reports/threads/jvm-virtual.json $(THREAD_DIST_DIRS)
JPERL_INTERPRETER=1 JPERL_THREAD_MODE=virtual perl dev/tools/perl_test_runner.pl --strict-exit --jobs 8 --timeout 300 --output build/reports/threads/interpreter-virtual.json $(THREAD_DIST_DIRS)
JPERL_THREAD_MODE=platform perl dev/tools/perl_test_runner.pl --strict-exit --jobs 8 --timeout 300 --output build/reports/threads/platform-focused.json $(THREAD_PLATFORM_TESTS)
# Post-Joni preservation anchors. These are unchanged Perl core tests whose
# direct regex semantics are complete and whose threaded variants prove lexical
# debug state, user-property coordination, recursive definitions, character
# classes, callbacks, and snapshot ownership on both execution backends.
test-threads-regex: check-java-gradle check-thread-regex-test-sources
@mkdir -p build/reports/threads
JPERL_THREAD_MODE=virtual perl dev/tools/perl_test_runner.pl --strict-exit --jobs 5 --timeout 600 --output build/reports/threads/regex-jvm-virtual.json $(THREAD_REGEX_ANCHOR_TESTS)
JPERL_INTERPRETER=1 JPERL_THREAD_MODE=virtual perl dev/tools/perl_test_runner.pl --strict-exit --jobs 5 --timeout 600 --output build/reports/threads/regex-interpreter-virtual.json $(THREAD_REGEX_ANCHOR_TESTS)
# Thread release gate: extend the PR gate to the complete platform-carrier
# distribution matrix. Together with test-threads this covers both backends on
# both carrier policies without making every pull request repeat all four runs.
test-threads-release: test-threads test-threads-regex
JPERL_THREAD_MODE=platform perl dev/tools/perl_test_runner.pl --strict-exit --jobs 8 --timeout 300 --output build/reports/threads/jvm-platform.json $(THREAD_DIST_DIRS)
JPERL_INTERPRETER=1 JPERL_THREAD_MODE=platform perl dev/tools/perl_test_runner.pl --strict-exit --jobs 8 --timeout 300 --output build/reports/threads/interpreter-platform.json $(THREAD_DIST_DIRS)
# Slow ecosystem release gate. Net::SSLeay exercises native callbacks and
# concurrent SSL context ownership; DBIx::Class exercises DBI handle rejection,
# cloned package graphs, closures, and a large real-world ORM suite. This target
# is intentionally separate from pull-request CI because jcpan needs network
# access and the complete DBIx::Class run can take about 40 minutes.
test-threads-ecosystem: check-java-gradle
JPERL_TEST_FILTER=61_threads-cb-crash $(MAKE) test-bundled-modules
JPERL_TEST_FILTER=62_threads-ctx_new-deadlock $(MAKE) test-bundled-modules
timeout 3600 ./jcpan --jobs 8 -t DBIx::Class
# Bundled CPAN module tests (XML::Parser, etc.)
# Tests live under src/test/resources/module/{ModuleName}/t/
test-bundled-modules: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat testModule --rerun-tasks
else
./gradlew testModule --rerun-tasks
endif
# Bundled CPAN distroprefs: run jcpan -t for each distribution that ships a
# pref under PerlOnJava/CpanDistroprefs/ (DBI, Moo, Moose, IO::Async, ...).
# Slow (network + upstream test suites); logs under build/reports/.
# XML::LibXML is skipped unless INCLUDE_XML_LIBXML_IN_DISTROPREF_SMOKE=1 (see design doc).
# See dev/design/patch-and-cpan-prefs-layout.md and dev/tools/test-cpan-distroprefs.sh.
test-cpan-distroprefs: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat shadowJar -q
bash dev/tools/test-cpan-distroprefs.sh
else
./gradlew shadowJar -q
bash dev/tools/test-cpan-distroprefs.sh
endif
# Image::ExifTool test suite (Image-ExifTool-13.44/t/ directory)
test-exiftool:
@echo "Running Image::ExifTool tests..."
@if [ -d Image-ExifTool-13.44/t ]; then \
perl dev/tools/run_exiftool_tests.pl --output test_exiftool_results.json; \
else \
echo "Error: Image-ExifTool-13.44/ directory not found."; \
exit 1; \
fi
# Perl 5 core test suite (perl5_t/t/ directory)
# Run 'perl dev/import-perl5/sync.pl' first to populate perl5_t/
test-perl5:
@echo "Running Perl 5 core test suite..."
@if [ -d perl5_t/t ]; then \
perl dev/tools/perl_test_runner.pl --jobs 8 --timeout 60 --output test_results.json perl5_t/t; \
else \
echo "Error: perl5_t/t/ directory not found. Run 'perl dev/import-perl5/sync.pl' first."; \
exit 1; \
fi
# Perl 5 module tests (auto-discovers all subdirectories in perl5_t/ except t/)
# Run 'perl dev/import-perl5/sync.pl' first to populate perl5_t/
test-modules:
@echo "Running Perl 5 module tests..."
@if [ -d perl5_t ]; then \
MODULE_DIRS=$$(find perl5_t -maxdepth 1 -type d ! -name perl5_t ! -name t -name '[A-Z]*' 2>/dev/null | sort); \
if [ -n "$$MODULE_DIRS" ]; then \
echo "Found module test directories: $$MODULE_DIRS"; \
perl dev/tools/perl_test_runner.pl --jobs 8 --timeout 60 --output test_modules_results.json $$MODULE_DIRS; \
else \
echo "Warning: No module test directories found in perl5_t/. Run 'perl dev/import-perl5/sync.pl' first."; \
fi \
else \
echo "Error: perl5_t/ directory not found. Run 'perl dev/import-perl5/sync.pl' first."; \
exit 1; \
fi
# Comprehensive tests - runs both Perl 5 core tests and module tests
test-all: test-perl5 test-modules
# Alternative: Run tests using JUnit/Gradle (for CI/CD integration)
# Uses parallel execution by default (4 JVMs)
test-gradle: test-gradle-parallel
# Fast unit tests via Gradle/JUnit
test-gradle-unit: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat testUnit --rerun-tasks
else
./gradlew testUnit --rerun-tasks
endif
# All tests via Gradle/JUnit
test-gradle-all: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat testAll --rerun-tasks
else
./gradlew testAll --rerun-tasks
endif
# Parallel unit tests via Gradle/JUnit (5 JVMs; last shard isolates heavy tests)
test-gradle-parallel: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat testUnitParallel --parallel --rerun-tasks
else
./gradlew testUnitParallel --parallel --rerun-tasks
endif
# Parallel unit tests via Maven (5 JVMs; last shard isolates heavy tests)
test-maven-parallel:
ifeq ($(OS),Windows_NT)
start /B mvn test -Pshard1 & start /B mvn test -Pshard2 & start /B mvn test -Pshard3 & start /B mvn test -Pshard4 & start /B mvn test -Pshard5
else
mvn test -Pshard1 & mvn test -Pshard2 & mvn test -Pshard3 & mvn test -Pshard4 & mvn test -Pshard5 & wait
endif
clean: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat clean
else
./gradlew clean
endif
deb: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat buildDeb
else
./gradlew buildDeb
endif
# SBOM (Software Bill of Materials) generation
# See dev/design/sbom.md for details
# Generate combined SBOM (Java dependencies + Perl modules merged)
sbom: sbom-java sbom-perl
@echo "Merging SBOMs..."
perl dev/tools/merge-sbom.pl build/reports/bom.json build/reports/perl-bom.json > build/reports/sbom.json
@echo "Combined SBOM generated: build/reports/sbom.json"
# Generate Java SBOM using CycloneDX Gradle plugin
sbom-java: check-java-gradle
ifeq ($(OS),Windows_NT)
gradlew.bat cyclonedxBom
else
./gradlew cyclonedxBom
endif
# Generate Perl modules SBOM
sbom-perl:
@mkdir -p build/reports
perl dev/tools/generate-perl-sbom.pl > build/reports/perl-bom.json
@echo "Perl SBOM generated: build/reports/perl-bom.json"
# Clean generated SBOMs
sbom-clean:
rm -f build/reports/bom.json build/reports/bom.xml build/reports/perl-bom.json build/reports/sbom.json
# Documentation link checker
# Requires: brew install lychee (or cargo install lychee)
check-links:
@command -v lychee >/dev/null 2>&1 || { echo "Error: lychee not found. Install with: brew install lychee"; exit 1; }
@echo "Checking documentation links..."
lychee --offline *.md docs/ dev/design/ dev/architecture/