-
Notifications
You must be signed in to change notification settings - Fork 5
/
Makefile
258 lines (209 loc) · 8.91 KB
/
Makefile
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
# Makefile for the JBOL project
project := jbol
########################################################################
# Prerequisites
########################################################################
# We are using some of the newest GNU Make features... so require GNU
# Make version >= 3.82
version_test := $(filter 3.82,$(firstword $(sort $(MAKE_VERSION) 3.82)))
ifndef version_test
$(error GNU Make version $(MAKE_VERSION); version >= 3.82 is needed)
endif
########################################################################
# Parameters (redefine as you like)
########################################################################
# jq binary used to run tests and examples.
JQ ?= /usr/local/bin/jq
# Used when (un)installing.
prefix ?= /usr/local
datadir ?= $(prefix)/share
bindir ?= $(prefix)/bin
########################################################################
# Paranoia
########################################################################
ifeq (,$(filter install uninstall,$(MAKECMDGOALS)))
ifeq (0,$(shell id --user))
$(error Root only can make "(un)install" targets)
endif
else
ifneq (0,$(shell id --user))
$(error Only root can make "(un)install" targets)
endif
endif
########################################################################
# Configuration
########################################################################
# Disable builtins.
MAKEFLAGS += --no-builtin-rules
MAKEFLAGS += --no-builtin-variables
# Warn when an undefined variable is referenced.
MAKEFLAGS += --warn-undefined-variables
# Make will not print the recipe used to remake files.
.SILENT:
# Eliminate use of the built-in implicit rules. Also clear out the
# default list of suffixes for suffix rules.
.SUFFIXES:
# Sets the default goal to be used if no targets were specified on the
# command line.
.DEFAULT_GOAL := all
# When it is time to consider phony targets, make will run its recipe
# unconditionally, regardless of whether a file with that name exists or
# what its last-modification time is.
.PHONY: all
# Default shell: if we require GNU Make, why not require Bash?
SHELL := /bin/bash
# The argument(s) passed to the shell are taken from the variable
# .SHELLFLAGS.
.SHELLFLAGS := -o errexit -o pipefail -o nounset -c
# Make will delete the target of a rule if it has changed and its recipe
# exits with a nonzero exit status.
.DELETE_ON_ERROR:
########################################################################
# Targets and files
########################################################################
# Tests to check
Tests := $(wildcard tests/*.test)
# Sentinel targets simulating the tests are done
LogDir := .logs
Logs := $(subst tests/,$(LogDir)/,$(Tests:.test=.log))
# Packages
LIB=fadado.github.io
ARRAY=$(LIB)/array
JSON=$(LIB)/json
MATH=$(LIB)/math
MUSIC=$(LIB)/music
OBJECT=$(LIB)/object
STRING=$(LIB)/string
WORD=$(LIB)/word
########################################################################
# Rules
########################################################################
# Default target
all: $(Logs)
# Hidden directory for logs
$(Logs): | $(LogDir)
$(LogDir): ; mkdir --parents $@
# Tests output is saved in a log file
$(LogDir)/%.log: tests/%.test
echo '>>>' $< '<<<' | tee $@
$(JQ) -L./fadado.github.io --run-tests $< \
| tee --append $@ \
| grep --invert-match '^Testing'
grep --quiet '^\*\*\*' $@ && touch $< || true
# Common tests
$(LogDir)/prelude.log: $(LIB)/prelude.jq
$(LogDir)/types.log: $(LIB)/types.jq
$(LogDir)/stream.log: $(LIB)/stream.jq
# JSON tests
$(LogDir)/json.log: $(JSON)/json.jq $(LIB)/prelude.jq $(LIB)/types.jq $(STRING)/ascii.jq $(STRING)/regexp.jq
$(LogDir)/json_schema.log: $(JSON)/schema.jq $(LIB)/prelude.jq $(LIB)/types.jq $(STRING)/url.jq $(STRING)/regexp.jq $(LIB)/stream.jq
# Math tests
$(LogDir)/math.log: $(MATH)/math.jq $(LIB)/types.jq
$(LogDir)/math_chance.log: $(MATH)/chance.jq $(LIB)/prelude.jq
$(LogDir)/math_sequence.log: $(MATH)/sequence.jq $(LIB)/prelude.jq
$(LogDir)/math_bitwise.log: $(MATH)/bitwise.jq
# Arrays tests
$(LogDir)/array.log: $(ARRAY)/array.jq
$(LogDir)/array_choice.log: $(ARRAY)/choice.jq $(LIB)/prelude.jq $(MATH)/chance.jq
$(LogDir)/array_set.log: $(ARRAY)/set.jq
$(LogDir)/array_kleene.log: $(ARRAY)/kleene.jq
$(LogDir)/array_tuple.log: $(ARRAY)/tuple.jq
# Object tests
$(LogDir)/object.log: $(OBJECT)/object.jq
$(LogDir)/object_set.log: $(OBJECT)/set.jq $(LIB)/prelude.jq $(LIB)/types.jq
# Word tests
$(LogDir)/word.log: $(WORD)/word.jq $(LIB)/types.jq
$(LogDir)/word_scanner.log: $(WORD)/scanner.jq
$(LogDir)/word_factor.log: $(WORD)/factor.jq
$(LogDir)/word_alphabet.log: $(WORD)/alphabet.jq $(ARRAY)/kleene.jq $(LIB)/prelude.jq $(LIB)/types.jq
$(LogDir)/word_language.log: $(WORD)/language.jq $(ARRAY)/kleene.jq $(LIB)/prelude.jq
# String tests
$(LogDir)/string.log: $(STRING)/string.jq $(LIB)/prelude.jq
$(LogDir)/string_table.log: $(STRING)/table.jq $(LIB)/prelude.jq $(STRING)/string.jq $(STRING)/ascii.jq $(STRING)/ascii.json $(OBJECT)/set.jq
$(LogDir)/string_ascii.log: $(STRING)/ascii.jq $(STRING)/ascii.json $(LIB)/prelude.jq
$(LogDir)/string_latin1.log: $(STRING)/latin1.jq $(STRING)/latin1.json $(LIB)/prelude.jq
$(LogDir)/string_regexp.log: $(STRING)/regexp.jq $(LIB)/prelude.jq $(STRING)/string.jq $(LIB)/types.jq
$(LogDir)/string_roman.log: $(STRING)/roman.jq $(LIB)/prelude.jq
$(LogDir)/string_snobol.log: $(STRING)/snobol.jq $(LIB)/prelude.jq $(STRING)/string.jq $(LIB)/types.jq
$(LogDir)/string_url.log: $(STRING)/url.jq $(MATH)/math.jq
# Music tests
$(LogDir)/music_pitch.log: $(MUSIC)/pitch.jq $(LIB)/prelude.jq $(STRING)/regexp.jq $(LIB)/types.jq
$(LogDir)/music_pitch-class.log: $(MUSIC)/pitch-class.jq $(MUSIC)/pitch.jq $(LIB)/prelude.jq $(ARRAY)/set.jq $(MATH)/math.jq $(LIB)/types.jq
$(LogDir)/music_pitch-class-set.log: $(MUSIC)/pitch-class-set.jq $(MUSIC)/pitch-class.jq $(LIB)/prelude.jq $(ARRAY)/set.jq $(MATH)/math.jq $(LIB)/types.jq
$(LogDir)/music_interval-class-vector.log: $(MUSIC)/interval-class-vector.jq $(MUSIC)/pitch-class.jq $(ARRAY)/array.jq $(MATH)/math.jq $(LIB)/prelude.jq
$(LogDir)/music_interval-pattern.log: $(MUSIC)/interval-pattern.jq $(MUSIC)/pitch-class.jq $(LIB)/prelude.jq
$(LogDir)/music_interval-table.log: $(MUSIC)/interval-table.jq $(MUSIC)/pitch-class.jq $(ARRAY)/array.jq $(LIB)/prelude.jq
########################################################################
# Utilities
########################################################################
.PHONY: clean distclean check list install uninstall #prototypes
clean:
rm --force -- $(LogDir)/*.log
distclean: clean
test -d $(LogDir) && rmdir --parents $(LogDir) || true
clober: distclean
check: clean all
install:
test -d $(datadir)/$(project) || mkdir -v --parents $(datadir)/$(project)
test -d $(bindir) || mkdir -v --parents $(bindir)
cp -v -u -r fadado.github.io/ $(datadir)/$(project)
cp -v -u -r schemata/ $(datadir)/$(project)
install --verbose --compare --mode 555 bin/{jgen,jval,jxml} $(bindir)
install --verbose --compare --mode 644 bin/{jgen,jval,jxml}.jq $(bindir)
uninstall:
test -d $(datadir)/$(project) \
&& rm --verbose --force --recursive $(datadir)/$(project) \
|| true
rm -f $(bindir)/{jgen,jval,jxml}*
# Show targets
list:
echo 'Targets:'; \
$(MAKE) --print-data-base --just-print 2>&1 \
| grep -v '^[mM]akefile' \
| awk '/^[^ \t.%][-A-Za-z0-9_]*:/ { print $$1 }' \
| sort --unique \
| sed 's/:\+$$//' \
| pr --omit-pagination --indent=4 --width=80 --columns=4
echo 'Default parameters:'; \
echo ' prefix = $(prefix)'; \
echo ' bindir = $(bindir)'; \
echo ' datadir = $(datadir)'; \
# Generate type declarations
define make_prototypes
find fadado.github.io -name '*.jq' -print | while read m; do \
M=$${m##*/}; \
P=$${M%.jq}; \
X=$${m#*fadado.github.io/}; \
X=$${X%/$$M}_; \
[[ $$X == *.jq_ ]] && X=''; \
<$$m grep '^def *[^_].*\#::' \
| sed -e 's/^def *//' -e 's/: *\#/ /' \
| sort >|/tmp/$${X}$${P}.txt ; \
done
endef
prototypes:
$(call make_prototypes)
########################################################################
# Examples
########################################################################
.PHONY: bogussort cross cut dice newton nondet nqbrute nqsmart octcode \
script seconds sendmoremoney series shuffle nqsbrute triple \
prolog closure
bogussort: ; $(JQ) -cnRrf examples/[email protected]
closure: ; $(JQ) -cnRrf examples/[email protected]
cross: ; $(JQ) -nRrf examples/[email protected]
cut: ; $(JQ) -cnRrf examples/[email protected]
dice: ; $(JQ) -cnRrf examples/[email protected]
newton: ; $(JQ) -cnRrf examples/[email protected]
nqbrute: ; $(JQ) -cnRrf examples/[email protected]
nqsmart: ; $(JQ) -cnRrf examples/[email protected]
octcode: ; $(JQ) -cnRrf examples/[email protected]
prolog: ; $(JQ) -cnRrf examples/[email protected]
script: ; $(JQ) -cnrf examples/[email protected]
seconds: ; $(JQ) -nRrf examples/[email protected]
sendmoremoney: ; $(JQ) -cnRrf examples/[email protected]
series: ; $(JQ) -cnRrf examples/[email protected]
shuffle: ; $(JQ) -cnRrf examples/[email protected]
nqsbrute: ; $(JQ) -cnRrf examples/[email protected]
triple: ; $(JQ) -cnrf examples/[email protected]
# vim:ai:sw=8:ts=8:noet:syntax=make