-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathextension.mk
279 lines (231 loc) · 9.92 KB
/
extension.mk
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
# Path from current directory to top level ableC repository
ABLEC_BASE?=../../ableC
# Path from current directory to top level extensions directory
EXTS_BASE?=../../extensions
MAKEOVERRIDES=ABLEC_BASE=$(abspath $(ABLEC_BASE)) EXTS_BASE=$(abspath $(EXTS_BASE))
# Variables that should be defined by the extension Makefile
# The name of the extension, must be defined
EXT_NAME?=$(error EXT_NAME must be defined)
# The extension's base grammar name, must be defined
EXT_GRAMMAR?=$(error EXT_GRAMMAR must be defined)
# Other extensions this extension depends on, including transitive dependencies
EXT_DEPS?=
# Extra flags passed to silver
SVFLAGS?=
# The Silver compiler to use
ifdef USE_CUSTOM_SILVER
SILVER=silver-custom silver-compiler.jar
SV_COMPILER_JAR=silver-compiler.jar
else
SILVER=silver
SV_COMPILER_JAR=
endif
# The directory containing generated files
export SILVER_GEN=generated
# The extension artifact jar to build
ARTIFACT_JAR=$(EXT_NAME).jar
# All silver files in included grammars, to be included as dependencies
GRAMMAR_SOURCES=$(shell find grammars/ -name *.sv -print0 | xargs -0)
# The artifact for ableC
ABLEC_JAR=$(ABLEC_BASE)/ableC.jar
# All extension jars we depend on
EXT_DEP_JARS=$(foreach dep,$(EXT_DEPS),$(EXTS_BASE)/$(dep)/$(dep).jar)
# All jars we depend on
DEP_JARS=$(ABLEC_JAR) $(EXT_DEP_JARS)
# The grammar path containing local sources and dependency jars
export GRAMMAR_PATH=$(shell echo $(DEP_JARS) $(abspath grammars) | sed "s/ \+/:/g")
# All directories contining extension header files that may be included
XC_INCLUDE_DIRS=$(wildcard include $(addsuffix /include,$(addprefix $(EXTS_BASE)/,$(EXT_DEPS))))
# All header files that may be included, to be included as dependencies
XC_INCLUDE_SOURCES=$(foreach dir,$(XC_INCLUDE_DIRS),$(wildcard $(dir)/*.*h))
# Flags passed to the C preprocessor including the extension header directories
XC_INCLUDE_FLAGS=$(addprefix -I,$(XC_INCLUDE_DIRS))
# Flags passed to ableC including the appropriate directories
override XCFLAGS+=$(XC_INCLUDE_FLAGS)
# Flags passed to Java when invoking ableC
JAVAFLAGS?=-Xss6M -Xmx256M
# The extension library to build
LIB_NAME?=
# All library extended c files to compile
LIB_XC_FILES=$(wildcard src/*.xc)
# All C library source files to compile
LIB_C_FILES=$(wildcard src/*.c)
# All library C files that should be generated
LIB_C_GEN_FILES=$(LIB_XC_FILES:src/%.xc=generated/%.c)
# All library object files that should be generated
LIB_OBJECTS=$(LIB_C_FILES:src/%.c=generated/%.o) $(LIB_XC_FILES:src/%.xc=generated/%.o)
# The name of the shared library.
SHARED_LIBRARY=lib/lib$(LIB_NAME).so
# The name of the static library.
STATIC_LIBRARY=lib/lib$(LIB_NAME).a
# Flags passed to ableC including the appropriate directories when building libraries
override LIB_XCFLAGS+=$(XC_INCLUDE_FLAGS)
# Flags passed to the C preprocessor when building libraries
override LIB_CPPFLAGS+=$(XC_INCLUDE_FLAGS)
# Flags passed to the C compiler when building libraries, e.g. to enable various compiler extensions
override LIB_CFLAGS+=-fpic
# Flags passed to the linker when building the shared library
override LIB_LDFLAGS+=-shared
CONF?=opt
ifeq ($(CONF),opt)
override LIB_XCFLAGS+=-DNDEBUG
override LIB_CPPFLAGS+=-DNDEBUG
override LIB_CFLAGS+=-O3
override LIB_LDFLAGS+=-O3
else ifeq ($(CONF),dbg)
override LIB_CFLAGS+=-g -O0
override LIB_LDFLAGS+=-g
else
$(error "Unknown configuration $(CONF)")
endif
# All (static) library files we depend on in linking examples/tests
LIB_FILES=$(DEP_LIBS)
ifneq ($(LIB_NAME),)
override LIB_FILES+=$(STATIC_LIBRARY)
override LDFLAGS+=-Llib
# Specify this library is to be linked statically, everything else dynamically
override LDLIBS+=-Wl,-Bstatic -l${LIB_NAME} -Wl,-Bdynamic
endif
# Extended C files to test
EXAMPLE_XC_FILES=$(wildcard examples/*.xc)
TEST_XC_FILES=$(wildcard tests/*/*.xc)
TEST_TRANS_XC_FILES=$(wildcard tests/positive/*.xc tests/runtime_error/*.xc)
# C files that should be generated
EXAMPLE_C_FILES=$(EXAMPLE_XC_FILES:.xc=.c)
TEST_C_FILES=$(TEST_TRANS_XC_FILES:.xc=.c)
# Object files that should be generated
EXAMPLE_OBJECTS=$(EXAMPLE_XC_FILES:.xc=.o)
TEST_OBJECTS=$(TEST_TRANS_XC_FILES:.xc=.o)
# Executables that should be generated
EXAMPLE_EXECUTABLES=$(EXAMPLE_XC_FILES:.xc=.out)
TEST_EXECUTABLES=$(TEST_TRANS_XC_FILES:.xc=.out)
# Evaluation marker files that should be generated
EXAMPLE_TESTS=$(EXAMPLE_XC_FILES:.xc=.test)
TEST_TESTS=$(TEST_XC_FILES:.xc=.test)
# Flags passed to the C compiler, e.g. to enable various compiler extensions
override CFLAGS+=-g
# Flags passed to the linker
override LDFLAGS+=-g
all: build libraries examples analyses test
build: $(ARTIFACT_JAR) compiler.jar
ifeq ($(LIB_NAME),)
libraries:
else
libraries: $(LIB_C_GEN_FILES) $(LIB_OBJECTS) $(SHARED_LIBRARY) $(STATIC_LIBRARY)
endif
examples: $(EXAMPLE_C_FILES) $(EXAMPLE_OBJECTS) $(EXAMPLE_EXECUTABLES) $(EXAMPLE_TESTS)
test: $(TEST_C_FILES) $(TEST_OBJECTS) $(TEST_EXECUTABLES) $(TEST_TESTS)
check: test
analyses: mda mwda
mda: mda.test
mwda: mwda.test
# This file is generated below, containing dependency information for included extensions,
# and also setting variables to pass appropriate flags.
include depends.mk
generated lib:
mkdir -p $@
# Locking is used to ensure that multiple parallel make invocations in the same workspace
# don't lead to race conditions causing a dependency to be built more than once.
LOCK=flock $(dir $@)
$(ABLEC_JAR): $(shell find $(ABLEC_BASE)/grammars/ -name *.sv -print0 | xargs -0)
$(LOCK) $(MAKE) -C $(ABLEC_BASE) ableC.jar
$(EXTS_BASE)/%.jar:
$(LOCK) $(MAKE) -C $(dir $@) $(notdir $@)
ifdef USE_CUSTOM_SILVER
# Note that $(DEP_JARS) are order-only dependencies, to avoid expensive rebuilds.
# If dependency extension syntax changes, this may require `make depclean` to be reflected.
$(SV_COMPILER_JAR): $(wildcard grammars/*/artifacts/silver_compiler/*.sv) | $(DEP_JARS) generated
ifeq ($(MAKELEVEL),0)
$(LOCK) $(MAKE) $@
else
silver -o $@ $(SVFLAGS) $(EXT_GRAMMAR):artifacts:silver_compiler
endif
endif
$(ARTIFACT_JAR): $(GRAMMAR_SOURCES) $(DEP_JARS) $(SV_COMPILER_JAR) | generated
ifeq ($(MAKELEVEL),0)
$(LOCK) $(MAKE) $@
else
$(SILVER) -o $@ $(SVFLAGS) $(EXT_GRAMMAR)
endif
compiler.jar: $(ARTIFACT_JAR) $(GRAMMAR_SOURCES) $(DEP_JARS) $(SV_COMPILER_JAR) | generated
ifeq ($(MAKELEVEL),0)
$(LOCK) $(MAKE) $@
else
# TODO: Shouldn't need to use the extended Silver here?
$(SILVER) -o $@ -I $(ARTIFACT_JAR) $(SVFLAGS) $(EXT_GRAMMAR):artifacts:compiler
endif
mda.test: $(ARTIFACT_JAR) $(DEP_JARS) $(SV_COMPILER_JAR) | generated
# TODO: Shouldn't need to use the extended Silver here?
$(SILVER) --dont-translate --build-xml-location build_mda.xml -I $(ARTIFACT_JAR) $(SVFLAGS) $(EXT_GRAMMAR):artifacts:mda_test
touch $@
mwda.test: $(GRAMMAR_SOURCES) $(DEP_JARS) $(SV_COMPILER_JAR) | generated
$(SILVER) --dont-translate --mwda --clean --build-xml-location build_mwda.xml $(SVFLAGS) $(EXT_GRAMMAR)
touch $@
generated/%.c: src/%.xc $(XC_INCLUDE_SOURCES) compiler.jar | generated
java $(JAVAFLAGS) -jar compiler.jar $< $(LIB_XCFLAGS)
mv src/$*.c src/$*.i generated/
%.c: %.xc $(XC_INCLUDE_SOURCES) compiler.jar
java $(JAVAFLAGS) -jar compiler.jar $< $(XCFLAGS)
generated/%.o: src/%.c $(XC_INCLUDE_SOURCES) | generated
$(CC) -c $(LIB_CPPFLAGS) $(LIB_CFLAGS) $< -o $@
generated/%.o: generated/%.c | generated
$(CC) -c $(LIB_CFLAGS) $< -o $@
$(SHARED_LIBRARY): $(LIB_OBJECTS) | lib
$(CC) $(LIB_LDFLAGS) $^ -o $@
$(STATIC_LIBRARY): $(LIB_OBJECTS) | lib
$(AR) rcs $@ $^
$(DEP_LIBS):
$(MAKE) -C $(abspath $(dir $@)/..) lib/$(notdir $@)
%.out: %.o $(LIB_FILES)
$(CC) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -o $@
%.test: %.out
@echo "Running $<..."
@./$< || echo "(exit $$?)"
touch $@
tests/translate_error/%.test: tests/translate_error/%.xc $(XC_INCLUDE_SOURCES) compiler.jar
@echo "java $(JAVAFLAGS) -jar compiler.jar $< $(XCFLAGS)"
@if java $(JAVAFLAGS) -jar compiler.jar $< $(XCFLAGS); then echo "Failed to error"; exit 1; fi
touch $@
tests/runtime_error/%.test: tests/runtime_error/%.out
@echo "./$<"
@if ./$<; then echo "Failed to error"; exit 2; else echo "(exit $$?)"; fi
touch $@
tests/positive/%.test: tests/positive/%.out
./$<
touch $@
clean:
rm -rf generated/ lib/
rm -f depends.mk $(ARTIFACT_JAR) compiler.jar *.copperdump.html build*.xml *.test
cd examples && rm -f build*.xml *.jar *.test *.c *.i *.o *.out
cd tests && rm -f build*.xml *.jar */*.test */*.c */*.i */*.o */*.out
realclean: clean
rm -f $(SV_COMPILER_JAR)
depclean: clean
cd $(ABLEC_BASE) && ./deep-clean
for dep in $(EXT_DEPS); do $(MAKE) -C $(EXTS_BASE)/$$dep clean; done
deprealclean: realclean
cd $(ABLEC_BASE) && ./deep-clean
for dep in $(EXT_DEPS); do $(MAKE) -C $(EXTS_BASE)/$$dep realclean; done
# Normally MAKEOVERRIDES= up above makes sure that sub-make calls get the right
# ABLEC_BASE and EXTS_BASE if this extension isn't actually in EXTS_BASE (which
# is the case on Jenkins.) However when generating depends.mk, we want to use
# paths that are valid in *this* directory, so override MAKEOVERRIDES to ensure
# that the ABLEC_BASE and EXTS_BASE variables are inherited like normal.
depends.mk: override MAKEOVERRIDES=
depends.mk:
@for dep in $(EXT_DEPS); do $(MAKE) -C $(EXTS_BASE)/$$dep --no-print-directory print_depends; done > $@
# Path to this extension, from any other extension
THIS_EXT=$(EXTS_BASE)/$(EXT_NAME)
# Print the definitions that should be added to the Makefile of any extension depending on this one.
print_depends:
ifdef USE_CUSTOM_SILVER
@echo '$(THIS_EXT)/$(SV_COMPILER_JAR): | $(DEP_JARS)'
endif
@echo '$(THIS_EXT)/$(ARTIFACT_JAR): $(addprefix $(THIS_EXT)/,$(GRAMMAR_SOURCES) $(SV_COMPILER_JAR)) $(DEP_JARS)'
ifneq ($(LIB_NAME),)
@echo '$(THIS_EXT)/$(STATIC_LIBRARY): $(addprefix $(THIS_EXT)/,$(ARTIFACT_JAR) $(XC_INCLUDE_SOURCES) $(LIB_C_FILES) $(LIB_XC_FILES))'
@echo 'override DEP_LIBS+=$(THIS_EXT)/$(STATIC_LIBRARY)'
@echo 'override LDFLAGS+=-L$(THIS_EXT)/lib'
@echo 'override LDLIBS+=-Wl,-Bstatic -l${LIB_NAME} -Wl,-Bdynamic'
endif
.PHONY: build libraries examples test check analyses mda mwda clean realclean depclean deprealclean print_depends