blob: 098c17e99e3857a2c1219e166445d63e1baab510 [file] [log] [blame]
Nico Huber5e9b1b52016-10-08 22:09:33 +02001libhw-dir := $(dir $(lastword $(MAKEFILE_LIST)))
2
3DESTDIR ?= dest
4
5name ?= hw
6hw-install = Makefile Makefile.proof gnat.adc spark.adc
7
8top := $(CURDIR)
9cnf := .config
10obj := build
11
12binary := $(obj)/lib$(name).a
13$(binary):
14
15space :=
16space +=
17comma := ,
18
Nico Hubercf01ab62017-03-05 23:22:39 +010019strip_quotes = $(strip $(subst ",,$(1)))
20# fix syntax highlighting with an odd emoticon "))
Nico Huberf86fb182016-10-09 20:43:42 +020021
Nico Huber5e9b1b52016-10-08 22:09:33 +020022$(foreach dep,$($(name)-deplibs), \
23 $(eval -include $($(dep)-dir)/config))
24-include $(cnf)
25
26include $(libhw-dir)/Makefile.proof
27
28CC = $(CROSS_COMPILE)gcc
29GNATBIND = $(CROSS_COMPILE)gnatbind
30
Nico Hubere86fff92017-03-04 13:20:37 +010031CFLAGS += -Wuninitialized -Wall -Werror
32CFLAGS += -pipe -g
33CFLAGS += -Wstrict-aliasing -Wshadow
34CFLAGS += -fno-common -fomit-frame-pointer
35CFLAGS += -ffunction-sections -fdata-sections
36
Nico Huber9d5d0252017-03-05 13:37:48 +010037ADAFLAGS += $(CFLAGS) -gnatA -gnatec=$(libhw-dir)/gnat.adc -gnatp
Nico Huber5e9b1b52016-10-08 22:09:33 +020038# Ada warning options:
39#
40# a Activate most optional warnings.
41# .e Activate every optional warnings.
42# e Treat warnings and style checks as errors.
43#
44# D Suppress warnings on implicit dereferences:
45# As SPARK does not accept access types we have to map the
46# dynamically chosen register locations to a static SPARK
47# variable.
48#
49# .H Suppress warnings on holes/gaps in records:
50# We are modelling hardware here!
51#
52# H Suppress warnings on hiding:
53# It's too annoying, you run out of ideas for identifiers fast.
54#
55# T Suppress warnings for tracking of deleted conditional code:
56# We use static options to select code paths at compile time.
57#
58# U Suppress warnings on unused entities:
59# Would have lots of warnings for unused register definitions,
60# `withs` for debugging etc.
61#
62# .U Deactivate warnings on unordered enumeration types:
63# As SPARK doesn't support `pragma Ordered` by now, we don't
64# use that, yet.
65#
66# .W Suppress warnings on unnecessary Warnings Off pragmas:
67# Things get really messy when you use different compiler
68# versions, otherwise.
69# .Y Disable information messages for why package spec needs body:
70# Those messages are annoying. But don't forget to enable those,
71# if you need the information.
72ADAFLAGS += -gnatwa.eeD.HHTU.U.W.Y
73# Disable style checks for now
74ADAFLAGS += -gnatyN
75
76MAKEFLAGS += -rR
77
78# Make is silent per default, but 'make V=1' will show all compiler calls.
79ifneq ($(V),1)
80.SILENT:
81endif
82
83# must come rather early
84.SECONDEXPANSION:
85
86$(binary): $$($(name)-objs)
87 @printf " AR $(subst $(obj)/,,$@)\n"
88 ar cr $@ $^
89
90$(foreach dep,$($(name)-deplibs), \
91 $(eval $(name)-extra-objs += $($(dep)-dir)/lib) \
92 $(eval $(name)-extra-incs += $($(dep)-dir)/include))
93
94# Converts one or more source file paths to their corresponding build/ paths.
95# Only .ads and .adb get converted to .o, other files keep their names.
96# $1 file path (list)
97src-to-obj = \
98 $(addprefix $(obj)/,\
99 $(patsubst $(obj)/%,%, \
Nico Hubere86fff92017-03-04 13:20:37 +0100100 $(patsubst %.c,%.o,\
Nico Huber5e9b1b52016-10-08 22:09:33 +0200101 $(patsubst %.ads,%.o,\
102 $(patsubst %.adb,%.o,\
Nico Hubere86fff92017-03-04 13:20:37 +0100103 $(2))))))
Nico Huber5e9b1b52016-10-08 22:09:33 +0200104
105# Converts one or more source file paths to the corresponding build/ paths
106# of their Ada library information (.ali) files.
107# $1 file path (list)
108src-to-ali = \
109 $(addprefix $(obj)/,\
110 $(patsubst $(obj)/%,%, \
111 $(patsubst %.ads,%.ali,\
112 $(patsubst %.adb,%.ali,\
113 $(filter %.ads %.adb,$(2))))))
114
115# Clean -y variables, include Makefile.inc
116# Add paths to files in $(name)-y to $(name)-srcs
117# Add subdirs-y to subdirs
118# $1 dir to read Makefile.inc from
119includemakefile = \
120 $(eval $(name)-y :=) \
121 $(eval $(name)-gen-y :=) \
122 $(eval $(name)-proof-y :=) \
123 $(eval subdirs-y :=) \
124 $(eval include $(1)/Makefile.inc) \
125 $(eval $(name)-srcs += \
126 $(subst $(top)/,, \
Nico Huber868915f2017-02-13 15:28:58 +0100127 $(abspath $(patsubst $(1)//%,/%,$(addprefix $(1)/,$($(name)-y)))))) \
Nico Huber5e9b1b52016-10-08 22:09:33 +0200128 $(eval $(name)-gens += \
129 $(subst $(top)/,, \
130 $(abspath $($(name)-gen-y)))) \
131 $(eval $(name)-proof += \
132 $(subst $(top)/,, \
133 $(abspath $(addprefix $(1)/,$($(name)-proof-y))))) \
134 $(eval subdirs += \
135 $(subst $(top)/,, \
136 $(abspath $(addprefix $(1)/,$(subdirs-y))))) \
137
138# For each path in $(subdirs) call includemakefiles
139# Repeat until subdirs is empty
140evaluate_subdirs = \
141 $(eval cursubdirs := $(subdirs)) \
142 $(eval subdirs :=) \
143 $(foreach dir,$(cursubdirs), \
144 $(call includemakefile,$(dir))) \
145 $(if $(subdirs), \
146 $(call evaluate_subdirs))
147
148# collect all object files eligible for building
149subdirs := .
150$(call evaluate_subdirs)
151
152# Eliminate duplicate mentions of source files
153$(name)-srcs := $(sort $($(name)-srcs))
154$(name)-gens := $(sort $($(name)-gens))
155
156# For Ada includes
157$(name)-ada-dirs := $(sort $(dir $(filter %.ads %.adb,$($(name)-srcs) $($(name)-gens))))
158
159# To track dependencies, we need all Ada specification (.ads) files in
160# *-srcs. Extract / filter all specification files that have a matching
161# body (.adb) file here (specifications without a body are valid sources
162# in Ada).
163$(name)-extra-specs := \
164 $(filter \
165 $(addprefix %/,$(patsubst %.adb,%.ads,$(notdir $(filter %.adb,$($(name)-srcs))))), \
166 $(filter %.ads,$($(name)-srcs) $($(name)-gens)))
167$(name)-srcs := $(filter-out $($(name)-extra-specs),$($(name)-srcs))
168$(name)-gens := $(filter-out $($(name)-extra-specs),$($(name)-gens))
169
170$(name)-objs := $(call src-to-obj,,$($(name)-srcs) $($(name)-gens))
171$(name)-alis := $(call src-to-ali,,$($(name)-srcs) $($(name)-gens))
172
173# For gnatprove
174$(name)-proof-dirs := \
175 $(sort $(dir $($(name)-proof)) \
176 $(filter-out ada/% %/ada/%,$($(name)-ada-dirs)))
177
178# For mkdir
179alldirs := $(abspath $(dir $(sort $($(name)-objs))))
180
181# Reads dependencies from an Ada library information (.ali) file
182# Only basenames (with suffix) are preserved so we have to look the
183# paths up in $($(name)-srcs) $($(name)-gens).
184# $1 ali file
185create_ada_deps = \
186 $(if $(wildcard $(1)),\
187 $(filter \
188 $(addprefix %/,$(shell sed -ne's/^D \([^\t]\+\).*$$/\1/p' $(1) 2>/dev/null)), \
189 $($(name)-srcs) $($(name)-gens) $($(name)-extra-specs)), \
190 $($(name)-gens))
191
192# Adds dependency rules
193# $1 source file
194add_ada_deps = \
195 $(call src-to-obj,,$(1)): $(1) \
196 $(call create_ada_deps,$(call src-to-ali,,$(1)))
197
Nico Hubere86fff92017-03-04 13:20:37 +0100198# Writes a compilation rule for Ada sources
Nico Huber5e9b1b52016-10-08 22:09:33 +0200199# $1 source type (ads, adb)
200# $2 source files (including the colon)
201# $3 obj path prefix (including the trailing slash)
202define add_ada_rule
203$(2) $(3)%.o: %.$(1)
204 @printf " COMPILE $$(subst $(obj)/,,$$@)\n"
205 $(CC) \
206 $(ADAFLAGS) $(addprefix -I,$($(name)-ada-dirs) $($(name)-extra-incs)) \
207 -c -o $$@ $$<
208endef
209
210# For sources
211$(foreach type,ads adb, \
212 $(eval $(call add_ada_rule,$(type),$(call src-to-obj,,$(filter %.$(type),$($(name)-srcs))):,$(obj)/)))
213$(foreach file,$($(name)-srcs) $($(name)-gens), \
214 $(eval $(call add_ada_deps,$(file))))
215
216# For generated sources already in $(obj)/
217$(foreach type,ads adb, \
218 $(eval $(call add_ada_rule,$(type),$(call src-to-obj,,$(filter %.$(type),$($(name)-gens))):,)))
219
220# Ali files are generated along with the object file. They need an empty
221# recipe for correct updating.
222$($(name)-alis): %.ali: %.o ;
223
224# To support complex package initializations, we need to call the
225# emitted code explicitly. gnatbind gathers all the calls for us
226# and exports them as a procedure $(name)_adainit(). Every stage that
227# uses Ada code has to call it!
228$(obj)/b__lib$(name).adb: $($(name)-alis)
229 @printf " BIND $(subst $(obj)/,,$@)\n"
230 # We have to give gnatbind a simple filename (without leading
231 # path components) so just cd there.
232 cd $(dir $@) && \
233 $(GNATBIND) $(addprefix -aO,$(abspath $($(name)-extra-objs))) \
234 -a -n -L$(name)_ada -o $(notdir $@) \
Nico Huber868915f2017-02-13 15:28:58 +0100235 $(patsubst /%,%,$(subst $(dir $@),,$^))
Nico Huber5e9b1b52016-10-08 22:09:33 +0200236$(eval $(call add_ada_rule,adb,$(obj)/b__lib$(name).o:,))
237$(name)-objs += $(obj)/b__lib$(name).o
238
Nico Hubere86fff92017-03-04 13:20:37 +0100239# Compilation rule for C sources
240$(call src-to-obj,,$(filter %.c,$($(name)-srcs))): $(obj)/%.o: %.c
241 @printf " COMPILE $(subst $(obj)/,,$@)\n"
242 $(CC) $(CFLAGS) -c -o $@ $<
243
Nico Huber5e9b1b52016-10-08 22:09:33 +0200244$(shell mkdir -p $(alldirs))
245
246$(name)-install-srcs = $(sort \
247 $($(name)-extra-specs) $(filter %.ads,$($(name)-srcs)) \
248 $(foreach adb,$(filter %.adb,$($(name)-srcs)), \
249 $(shell grep -q '^U .*\<BN\>' $(call src-to-ali,,$(adb)) 2>/dev/null && echo $(adb))))
250
251$(name)-install-proof = \
252 $(filter $(addprefix %/,$(notdir $($(name)-install-srcs))),$($(name)-proof)) \
253 $(filter-out $(addprefix %/,$(notdir $($(name)-proof))),$($(name)-install-srcs))
254
255install: $(binary) $($(name)-alis) $(libgpr)
256 install -d $(DESTDIR)/lib $(DESTDIR)/include $(DESTDIR)/proof
257 printf " INSTALL $(subst $(obj)/,,$(binary))\n"
258 install $(binary) $(DESTDIR)/lib/
259 $(foreach file,$($(name)-install) $(libgpr), \
260 printf " INSTALL $(subst $(obj)/,,$(file))\n"; \
261 install $(file) $(DESTDIR);)
262 printf " INSTALL $(cnf)\n"
263 install $(cnf) $(DESTDIR)/config
264 printf " INSTALL %s\n" $(subst $(obj)/,,$($(name)-alis))
265 install $($(name)-alis) $(DESTDIR)/lib/
266 printf " INSTALL %s\n" $(subst $(obj)/,,$($(name)-install-srcs))
267 install $($(name)-install-srcs) $(DESTDIR)/include/
268 printf " INSTALL %s\n" $(subst $(obj)/,,$($(name)-install-proof))
269 install $($(name)-install-proof) $(DESTDIR)/proof/
270
271clean::
272 rm -rf $(obj) $(name).gpr
273
274distclean: clean
275 rm -rf dest
276
277.PHONY: install clean distclean