11.PHONY : deps deps-linux deps-macos compile-programs-asm compile-programs-rust compile-bench \
2- compile-programs clean-asm clean-rust clean-bench clean-shared clean test test-asm \
2+ compile-programs compile-recursion-elfs clean-asm clean-rust clean-bench clean-shared \
3+ clean-recursion-elfs clean test test-asm \
34test-rust test-executor test-flamegraph flamegraph-prover \
45test-fast test-prover test-prover-all test-disk-spill test-math-cuda test-cuda-integration test-cuda-fallback \
56test-prover-cuda test-prover-comprehensive-cuda \
@@ -47,6 +48,13 @@ BENCH_PROGRAM_DIRS := $(dir $(wildcard $(BENCH_PROGRAMS_DIR)/*/Cargo.toml))
4748BENCH_PROGRAMS := $(notdir $(basename $(BENCH_PROGRAM_DIRS:%/=% ) ) )
4849BENCH_ARTIFACTS := $(addprefix $(BENCH_ARTIFACTS_DIR ) /, $(addsuffix .elf, $(BENCH_PROGRAMS ) ) )
4950
51+ # Recursion smoke-test guests, in bench_vs/lambda/ (shared with bench_vs/run.sh)
52+ # rather than executor/programs/. The recursion guest is the in-VM STARK verifier.
53+ RECURSION_GUESTS_DIR =./bench_vs/lambda
54+ RECURSION_ARTIFACTS_DIR =./executor/program_artifacts/recursion
55+ RECURSION_GUESTS := empty fibonacci recursion
56+ RECURSION_ARTIFACTS := $(addprefix $(RECURSION_ARTIFACTS_DIR ) /, $(addsuffix .elf, $(RECURSION_GUESTS ) ) )
57+
5058# Override with: make ... SYSROOT_DIR=$HOME/.lambda-vm-sysroot
5159# to install the sysroot in a user-writable location and avoid sudo.
5260SYSROOT_DIR ?= /opt/lambda-vm-sysroot
@@ -134,7 +142,16 @@ compile-programs-rust: prepare-sysroot $(RUST_ARTIFACTS)
134142
135143compile-bench : prepare-sysroot $(BENCH_ARTIFACTS )
136144
137- compile-programs : compile-programs-asm compile-programs-rust compile-bench
145+ # NOTE: the recursion smoke tests are #[ignore]d (not run by `make test` /
146+ # `test-executor`) because they're too slow for CI today; only `test-prover-all`
147+ # runs them. We still compile their guest ELFs on every build so they keep
148+ # compiling until the tests are fast enough to run in CI.
149+ compile-programs : compile-programs-asm compile-programs-rust compile-bench compile-recursion-elfs
150+
151+ compile-recursion-elfs : prepare-sysroot $(RECURSION_ARTIFACTS )
152+
153+ $(RECURSION_ARTIFACTS_DIR ) :
154+ mkdir -p $@
138155
139156
140157$(RUST_ARTIFACTS_DIR ) :
@@ -143,34 +160,49 @@ $(RUST_ARTIFACTS_DIR):
143160$(BENCH_ARTIFACTS_DIR ) :
144161 mkdir -p $@
145162
163+ # The guest .elf rules depend on FORCE so their recipe always runs: cargo already
164+ # tracks the full dependency graph, so we let it decide what to rebuild (a fast
165+ # no-op when nothing changed) rather than re-encode that in Make prereqs.
166+ .PHONY : FORCE
167+ FORCE :
168+
169+ # The guest .elf rules all share one canned recipe: the cargo build invocation is
170+ # identical across the rust, bench, and recursion guests. They differ only in the
171+ # source directory ($(1)) and the built-binary name suffix ($(2): empty when the
172+ # binary == crate name, `-bench` for the recursion suite, whose crates are named
173+ # <name>-bench). cargo owns the dep graph (see FORCE above), so the recipe always
174+ # runs and lets cargo decide what to actually rebuild.
175+ define build_guest_elf
176+ cd $(1 ) /$* && \
177+ CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR ) ) \
178+ CFLAGS_riscv64im_lambda_vm_elf="$(SYSROOT_CFLAGS ) " \
179+ rustup run nightly-2026-02-01 cargo build --release \
180+ --target $(RV64_TARGET_SPEC ) \
181+ -Z build-std=core,alloc,std,compiler_builtins,panic_abort \
182+ -Z build-std-features=compiler-builtins-mem \
183+ -Z json-target-spec
184+ cp $(SHARED_TARGET_DIR ) /riscv64im-lambda-vm-elf/release/$* $(2 ) $@
185+ endef
186+
146187# Compile rust (64-bit)
147188# Order-only `| prepare-sysroot` so a direct `make .../foo.elf` provisions the sysroot
148189# first (the aggregate compile-programs-rust/compile-bench targets already do, but a
149190# bare pattern-rule invocation like `make -B .../ethrex.elf` would otherwise skip it
150191# and fail to compile guest C dependencies). Order-only because prepare-sysroot is
151192# .PHONY — a normal prereq would force a rebuild every time; its recipe is idempotent.
152- $(RUST_ARTIFACTS_DIR ) /% .elf : $(RUST_PROGRAMS_DIR ) /% /Cargo.toml | prepare-sysroot $(RUST_ARTIFACTS_DIR )
153- cd $(RUST_PROGRAMS_DIR ) /$* && \
154- CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR ) ) \
155- CFLAGS_riscv64im_lambda_vm_elf=" $( SYSROOT_CFLAGS) " \
156- rustup run nightly-2026-02-01 cargo build --release \
157- --target $(RV64_TARGET_SPEC ) \
158- -Z build-std=core,alloc,std,compiler_builtins,panic_abort \
159- -Z build-std-features=compiler-builtins-mem \
160- -Z json-target-spec
161- cp $(SHARED_TARGET_DIR ) /riscv64im-lambda-vm-elf/release/$* $@
193+ $(RUST_ARTIFACTS_DIR ) /% .elf : FORCE | prepare-sysroot $(RUST_ARTIFACTS_DIR )
194+ $(call build_guest_elf,$(RUST_PROGRAMS_DIR ) ,)
162195
163196# Compile rust benches (64-bit)
164- $(BENCH_ARTIFACTS_DIR ) /% .elf : $(BENCH_PROGRAMS_DIR ) /% /Cargo.toml | prepare-sysroot $(BENCH_ARTIFACTS_DIR )
165- cd $(BENCH_PROGRAMS_DIR ) /$* && \
166- CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR ) ) \
167- CFLAGS_riscv64im_lambda_vm_elf=" $( SYSROOT_CFLAGS) " \
168- rustup run nightly-2026-02-01 cargo build --release \
169- --target $(RV64_TARGET_SPEC ) \
170- -Z build-std=core,alloc,std,compiler_builtins,panic_abort \
171- -Z build-std-features=compiler-builtins-mem \
172- -Z json-target-spec
173- cp $(SHARED_TARGET_DIR ) /riscv64im-lambda-vm-elf/release/$* $@
197+ $(BENCH_ARTIFACTS_DIR ) /% .elf : FORCE | prepare-sysroot $(BENCH_ARTIFACTS_DIR )
198+ $(call build_guest_elf,$(BENCH_PROGRAMS_DIR ) ,)
199+
200+ # Recursion-suite guests (bench_vs/lambda/): the crate's binary is <name>-bench, so
201+ # copy <name>-bench -> <name>.elf. std-inclusive build-std covers both the no_std
202+ # inner guests and the std recursion verifier. Prover tests read these prebuilt
203+ # artifacts like every other program (see prover/src/tests/recursion_smoke_test.rs).
204+ $(RECURSION_ARTIFACTS_DIR ) /% .elf : FORCE | prepare-sysroot $(RECURSION_ARTIFACTS_DIR )
205+ $(call build_guest_elf,$(RECURSION_GUESTS_DIR ) ,-bench)
174206
175207clean-asm :
176208 -rm -rf $(ASM_ARTIFACTS_DIR )
@@ -184,7 +216,10 @@ clean-bench:
184216clean-shared :
185217 -rm -rf $(SHARED_TARGET_DIR )
186218
187- clean : clean-asm clean-rust clean-bench clean-shared
219+ clean-recursion-elfs :
220+ -rm -rf $(RECURSION_ARTIFACTS_DIR )
221+
222+ clean : clean-asm clean-rust clean-bench clean-shared clean-recursion-elfs
188223
189224test-executor : compile-programs
190225 cargo test -p executor
@@ -226,8 +261,9 @@ test-fast:
226261test-prover :
227262 cargo test -p lambda-vm-prover
228263
229- # Prover tests including slow ones
230- test-prover-all :
264+ # Prover tests including slow ones. The recursion smoke tests (#[ignore]d) read
265+ # prebuilt guest ELFs from executor/program_artifacts/recursion/, so build them first.
266+ test-prover-all : compile-recursion-elfs
231267 cargo test -p lambda-vm-prover -- --include-ignored
232268
233269# Prover tests with debug-checks (shows bus balance report)
0 commit comments