blob: 8876ca03f73c22c3537c3bda98be10a9140d1a41 [file] [log] [blame]
Nico Huber5e9b1b52016-10-08 22:09:33 +02001PROOF_MODE ?= all
2
3jobs ?= 4
4
5$(foreach dep,$($(name)-deplibs), \
6 $(eval SPARKFLAGS += -aP=$($(dep)-dir)))
7
8SPARKFLAGS += -j$(jobs)
9SPARKFLAGS += -k
10SPARKFLAGS += -m
11SPARKFLAGS += --mode=$(PROOF_MODE)
12SPARKFLAGS += --report=fail
13SPARKFLAGS += --warnings=error
Nico Huber65821412018-06-04 23:13:21 +020014SPARKFLAGS += --no-inlining
Nico Huber5bd7c112026-04-11 22:36:50 +000015SPARKFLAGS += --prover=z3 --steps=500 --timeout=2 # FIXME: timeout used because steps seems broken
Nico Huber5e9b1b52016-10-08 22:09:33 +020016
17quote-list = $(subst $(space),$(comma),$(patsubst %,"%",$(1)))
18
19$(name)-exclude-srcs = \
20 $(filter-out \
Nico Huberbd0ed912018-06-17 17:58:57 +020021 $(sort $(notdir $($(name)-proof) \
22 $($(name)-srcs) $($(name)-gens) $($(name)-extra-specs) $($(name)-extra-gens))), \
Nico Huber5e9b1b52016-10-08 22:09:33 +020023 $(sort $(notdir \
24 $(wildcard $(addsuffix *.ad[sb],$($(name)-proof-dirs))))))
25
26# Has to reside in the working directory. gnatprove takes paths relative
27# to the directory wher it's placed and reports internal errors if used
28# with absolute paths.
29gpr := $(name).gpr
30gpr-name = $(subst -,_,$(subst .,_,$(basename $(notdir $@))))
31
32# Will be installed for inclusion
33libgpr := $(obj)/lib$(name).gpr
34
35.SECONDEXPANSION:
36
37$(gpr):
38 @printf " GENERATE $(subst $(obj)/,,$@)\n"
39 printf '$(if $($(name)-deplibs),with "%s";\n)' $($(name)-deplibs) >$@
40 echo 'library project $(gpr-name) is' >>$@
41 echo ' for Library_Name use "$(name)";' >>$@
42 echo ' for Library_Dir use "$(obj)/adalib";' >>$@
43 echo ' for Source_Dirs use' \
44 '($(call quote-list,$($(name)-proof-dirs)));' >>$@
45 echo ' for Object_Dir use "$(obj)";' >>$@
46 echo ' package Builder is' >>$@
47 echo ' for Global_Configuration_Pragmas use' \
48 '"$(abspath $(libhw-dir)/spark.adc)";' >>$@
49 echo ' end Builder;' >>$@
50 echo ' for Excluded_Source_Files use' \
51 '($(call quote-list,$($(name)-exclude-srcs)));' >>$@
52 echo 'end $(gpr-name);' >>$@
53
54.INTERMEDIATE: $(gpr)
55
56$(libgpr): $$(MAKEFILE_LIST)
57 @printf " GENERATE $(subst $(obj)/,,$@)\n"
58 printf '$(if $($(name)-deplibs),with "%s";\n)' $($(name)-deplibs) >$@
59 echo 'library project lib$(name) is' >>$@
60 echo ' for Library_Name use "$(name)";' >>$@
61 echo ' for Library_Dir use "lib";' >>$@
62 echo ' for Library_ALI_Dir use "lib";' >>$@
63 echo ' for Source_Dirs use ("proof");' >>$@
64 echo ' for Object_Dir use external ("obj", "build");' >>$@
65 echo 'end lib$(name);' >>$@
66
Nico Huber0498e102026-04-11 10:47:06 +000067# We want to filter gnatprove's command-line output through `sed`,
68# and *also* capture its return value. Not that easy, we'll pipe the
69# return code through file descriptor #3.
70#
71# 1: command w/ return value
72# 2: filter command, ignore return value
73#
74filter-output = { { { { $(1); } 2>&1; echo $$? >&3; } | $(2) >&2; } 3>&1 | { read ret; exit $${ret}; }; } 2>&1
75
Nico Huberbd0ed912018-06-17 17:58:57 +020076$(obj)/gnatprove/gnatprove.out: $$($(name)-srcs) $$($(name)-gens)
77$(obj)/gnatprove/gnatprove.out: $$($(name)-extra-specs) $$($(name)-extra-gens)
78$(obj)/gnatprove/gnatprove.out: $(gpr) $(obj)/proofmode
Nico Huber0498e102026-04-11 10:47:06 +000079 $(call filter-output, \
Nico Huber50345492026-04-11 10:59:43 +000080 $(MAKE) -j$(jobs) && gnatprove -P$< $(SPARKFLAGS) -Xobj=$(abspath $(obj)), \
Nico Huber0498e102026-04-11 10:47:06 +000081 sed $(foreach file,$^,-e 's|$(notdir $(file)):[0-9]\+:[0-9]\+:|$(dir $(file))&|'))
Nico Huber5e9b1b52016-10-08 22:09:33 +020082proof:
83 if [ "$(PROOF_MODE)" != "$$(cat $(obj)/proofmode 2>/dev/null)" ]; then \
84 echo "$(PROOF_MODE)" >$(obj)/proofmode; \
85 fi
86 $(MAKE) $(obj)/gnatprove/gnatprove.out
87
88check: export override PROOF_MODE=check
89check: proof
90
91flow: export override PROOF_MODE=flow
92flow: proof
93
94full: export override PROOF_MODE=all
95full: proof
96
97allconfigs = $(wildcard configs/*)
98allconfigs-targets = $(addprefix allconfigs-,$(notdir $(allconfigs)))
99
Nico Huber35ca5cc2026-04-11 11:08:35 +0000100$(allconfigs-targets): jobs=1
Nico Huber5e9b1b52016-10-08 22:09:33 +0200101$(allconfigs-targets): allconfigs-%: configs/%
102 rm -rf proof-allconfigs/$* $(name)_$*.gpr
103 mkdir -p proof-allconfigs/$*
104 echo "$(PROOF_MODE)" >proof-allconfigs/$*/proofmode
Nico Huber0498e102026-04-11 10:47:06 +0000105 $(call filter-output, \
Nico Huber35ca5cc2026-04-11 11:08:35 +0000106 $(MAKE) obj=proof-allconfigs/$* cnf=configs/$* gpr=$(name)_$*.gpr jobs=$(jobs) \
Nico Huber0498e102026-04-11 10:47:06 +0000107 proof-allconfigs/$*/gnatprove/gnatprove.out, \
108 sed 's/^[^[:space:]]\+:[0-9]\+:[0-9]\+:/$*::&/')
Nico Huber5e9b1b52016-10-08 22:09:33 +0200109
110proof-allconfigs: $(allconfigs-targets)
111
112clean::
113 rm -rf proof-allconfigs/
114
115.PHONY: proof check flow full $(allconfigs-targets) proof-allconfigs