add coverage build variant to Makefile
[libfirm] / Makefile
1 # libfirm Makefile
2 #
3 # This is currently experimental and not fully supported, but we plan to replace
4 # the jambuild with this at some point in the future.
5 #
6 # Most variable names are similar to the names used by autoconf...
7 -include config.mak
8
9 # Some build configuration defaults
10 top_srcdir   ?=
11 top_builddir ?= build
12 host         ?= unknown-host
13 variant      ?= debug
14
15 srcdir       ?= $(top_srcdir)
16 builddir     ?= $(top_builddir)/$(variant)
17 docdir       ?= $(top_builddir)/doc
18
19 # This hides the noisy commandline outputs. You can see them with "make Q="
20 Q ?= @
21
22 CC ?= cc
23 DOXYGEN ?= doxygen
24 LINK ?= $(CC)
25 AR ?= ar
26 DLLEXT ?= .so
27
28 # Variants
29 CFLAGS_all        = -std=c99 -fPIC -DHAVE_FIRM_REVISION_H
30 CFLAGS_debug      = $(CFLAGS_all) -O0 -g3 -DDEBUG_libfirm
31 CFLAGS_profile    = $(CFLAGS_all) -O3 -pg -DNDEBUG -fno-inline
32 CFLAGS_coverage   = $(CFLAGS_all) -O0 -fprofile-arcs -ftest-coverage -DDEBUG_libfirm
33 LINKFLAGS_profile  = -pg
34 LINKFLAGS_coverage = -fprofile-arcs -ftest-coverage
35 CFLAGS_optimize   = $(CFLAGS_all) -O3 -DNDEBUG
36
37 # General flags
38 CFLAGS    += $(CFLAGS_$(variant))
39 CFLAGS    += -Wall -W -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings
40 LINKFLAGS += $(LINKFLAGS_$(variant)) -lm
41 VPATH = $(srcdir)
42
43 REVISION ?= $(shell git describe --abbrev=40 --always --dirty --match '')
44
45 # Update revision.h if necessary
46 UNUSED := $(shell \
47         REV="\#define libfirm_VERSION_REVISION \"$(REVISION)\""; \
48         echo "$$REV" | cmp -s - firm_revision.h 2> /dev/null || echo "$$REV" > firm_revision.h \
49 )
50
51 .PHONY: all
52 all: firm
53
54 # This rule is necessary so that make does not abort if headers get deleted
55 # (the deleted header might still be referenced in a .d file)
56 %.h:
57         @:
58
59 # A very naive way to create a config.h if it is missing
60 $(srcdir)config.h:
61         @echo MakeConfig $@
62         $(Q)rm -f $@
63         $(Q)echo "#define libfirm_VERSION_MAJOR 1" >> $@
64         $(Q)echo "#define libfirm_VERSION_MICRO 0" >> $@
65         $(Q)echo "#define libfirm_VERSION_MINOR 20" >> $@
66
67 # libFirm
68 libfirm_DIRS := \
69         ir         \
70         ir/adt     \
71         ir/ana     \
72         ir/arch    \
73         ir/common  \
74         ir/debug   \
75         ir/obstack \
76         ir/ident   \
77         ir/net     \
78         ir/ir      \
79         ir/lower   \
80         ir/libcore \
81         ir/lpp     \
82         ir/opt     \
83         ir/st      \
84         ir/stat    \
85         ir/tr      \
86         ir/tv      \
87         ir/kaps    \
88         ir/be
89 libfirm_SOURCES  = $(foreach dir,$(libfirm_DIRS),$(wildcard $(dir)/*.c))
90 libfirm_a        = $(builddir)/libfirm.a
91 libfirm_dll      = $(builddir)/libfirm$(DLLEXT)
92 libfirm_CPPFLAGS = -Iinclude/libfirm -Iinclude/libfirm/adt -I. $(foreach dir,$(libfirm_DIRS),-I$(dir))
93
94 .PHONY: firm
95 firm: $(libfirm_dll)
96
97 # backends
98 backends = amd64 arm ia32 sparc TEMPLATE
99
100 EMITTER_GENERATOR = $(srcdir)ir/be/scripts/generate_emitter.pl
101 EMITTER_GENERATOR2 = $(srcdir)ir/be/scripts/generate_emitter_new.pl
102 REGALLOC_IF_GENERATOR = $(srcdir)ir/be/scripts/generate_regalloc_if.pl
103 OPCODES_GENERATOR = $(srcdir)ir/be/scripts/generate_new_opcodes.pl
104
105 define backend_template
106 $(1)_SOURCES = $$(wildcard ir/be/$(1)/*.c)
107 $(1)_SOURCES := $$(filter-out ir/be/$(1)/gen_%.c, $$($(1)_SOURCES))
108 $(1)_GEN_HEADERS =
109
110 $(1)_SPEC = ir/be/$(1)/$(1)_spec.pl
111
112 $$(srcdir)ir/be/$(1)/gen_$(1)_emitter.h $$(srcdir)ir/be/$(1)/gen_$(1)_emitter.c: $$($(1)_SPEC) $$(EMITTER_GENERATOR) $(EMITTER_GENERATOR2)
113         @echo GEN $$@
114         $(Q)$$(EMITTER_GENERATOR) $$($(1)_SPEC) $$(srcdir)ir/be/$(1)
115 $(1)_SOURCES += ir/be/$(1)/gen_$(1)_emitter.c
116 $(1)_GEN_HEADERS += ir/be/$(1)/gen_$(1)_emitter.h
117
118 $$(srcdir)ir/be/$(1)/gen_$(1)_regalloc_if.h $$(srcdir)ir/be/$(1)/gen_$(1)_regalloc_if.c: $$($(1)_SPEC) $$(REGALLOC_IF_GENERATOR)
119         @echo GEN $$@
120         $(Q)$$(REGALLOC_IF_GENERATOR) $$($(1)_SPEC) $$(srcdir)ir/be/$(1)
121 $(1)_SOURCES += ir/be/$(1)/gen_$(1)_regalloc_if.c
122 $(1)_GEN_HEADERS += ir/be/$(1)/gen_$(1)_regalloc_if.h
123
124 $$(srcdir)ir/be/$(1)/gen_$(1)_new_nodes.h $$(srcdir)ir/be/$(1)/gen_$(1)_new_nodes.c.inl: $$($(1)_SPEC) $$(OPCODES_GENERATOR)
125         @echo GEN $$@
126         $(Q)$$(OPCODES_GENERATOR) $$($(1)_SPEC) $$(srcdir)ir/be/$(1)
127 $(1)_GEN_HEADERS += ir/be/$(1)/gen_$(1)_new_nodes.h
128
129 ir/be/$(1)/$(1)_new_nodes.c: ir/be/$(1)/gen_$(1)_new_nodes.c.inl
130
131 # We need to inform make of the headers it doesn't know yet...
132 $(1)_OBJECTS = $$($(1)_SOURCES:%.c=$$(builddir)/%.o)
133 $$($(1)_OBJECTS): $$($(1)_GEN_HEADERS)
134
135 libfirm_SOURCES += $$($(1)_SOURCES)
136 libfirm_DIRS += ir/be/$(1)
137 endef
138
139 $(foreach backend,$(backends),$(eval $(call backend_template,$(backend))))
140
141 # generators
142 IR_SPEC_GENERATED_FILES := \
143         include/libfirm/nodeops.h \
144         include/libfirm/opcodes.h \
145         ir/ir/gen_ir_cons.c.inl   \
146         ir/ir/gen_irop.c.inl      \
147         ir/ir/gen_irnode.c.inl    \
148         ir/ir/gen_irnode.h
149 IR_SPEC_GENERATOR := scripts/gen_ir.py
150 IR_SPEC := scripts/ir_spec.py
151
152 $(IR_SPEC_GENERATED_FILES): $(IR_SPEC_GENERATOR) $(IR_SPEC) scripts/spec_util.py
153         @echo GEN $@
154         $(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) ir/ir
155
156 IR_IO_GENERATOR := scripts/gen_ir_io.py
157 IR_IO_GENERATED_FILES := ir/ir/gen_irio.inl
158
159 $(IR_IO_GENERATED_FILES): $(IR_IO_GENERATOR) $(IR_SPEC) scripts/spec_util.py
160         @echo GEN $@
161         $(Q)$(IR_IO_GENERATOR) $(IR_SPEC) ir/ir
162
163 ir/ir/irio.c: $(IR_IO_GENERATED_FILES)
164
165 libfirm_OBJECTS = $(libfirm_SOURCES:%.c=$(builddir)/%.o)
166 libfirm_DEPS    = $(libfirm_OBJECTS:%.o=%.d)
167 -include $(libfirm_DEPS)
168
169 $(libfirm_a): $(libfirm_OBJECTS)
170         @echo AR $@
171         $(Q)$(AR) -cru $@ $^
172
173 $(libfirm_dll): $(libfirm_OBJECTS)
174         @echo LINK $@
175         $(Q)$(LINK) -shared $(LINKFLAGS) -o $@ $^
176
177 # Generic rules
178 UNUSED := $(shell mkdir -p $(libfirm_DIRS:%=$(builddir)/%))
179 $(builddir)/%.o: %.c $(IR_SPEC_GENERATED_FILES) config.h
180         @echo CC $@
181         $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) -MMD -c -o $@ $<
182
183 $(docdir)/libfirm.tag: $(IR_SPEC_GENERATED_FILES) Doxyfile $(wildcard include/libfirm/*.h) $(wildcard include/libfirm/adt/*.h)
184         @echo Doxygen $@
185         $(Q)$(DOXYGEN)
186
187 DOCU_GENERATOR := scripts/gen_docu.py
188 $(docdir)/html/nodes.html: $(docdir)/libfirm.tag $(DOCU_GENERATOR) $(IR_SPEC) scripts/spec_util.py scripts/style.css
189         @echo gen_docu.py $@
190         $(Q)$(DOCU_GENERATOR) $(IR_SPEC) $(docdir)/libfirm.tag "" $@
191         $(Q)cp scripts/style.css $(docdir)/html
192
193 .PHONY: doc
194 doc: $(docdir)/libfirm.tag $(docdir)/html/nodes.html
195
196 .PHONY: clean
197 clean:
198         @echo CLEAN
199         $(Q)rm -f $(libfirm_OBJECTS)
200         $(Q)rm -f $(libfirm_TARGET)
201         $(Q)rm -f $(shell find ir/ -name "gen_*.[ch]")