Makefile 7.96 KB
Newer Older
Matthias Braun's avatar
Matthias Braun committed
1
2
3
4
5
6
7
8
9
# libfirm Makefile
#
# This is currently experimental and not fully supported, but we plan to replace
# the jambuild with this at some point in the future.
#
# Most variable names are similar to the names used by autoconf...
-include config.mak

# Some build configuration defaults
10
top_srcdir   ?= .
Matthias Braun's avatar
Matthias Braun committed
11
12
13
14
15
top_builddir ?= build
variant      ?= debug

srcdir       ?= $(top_srcdir)
builddir     ?= $(top_builddir)/$(variant)
16
gendir       ?= $(top_builddir)/gen
Matthias Braun's avatar
Matthias Braun committed
17
docdir       ?= $(top_builddir)/doc
Matthias Braun's avatar
Matthias Braun committed
18

19
20
# This hides the noisy commandline outputs. Show them with "make V=1"
ifneq ($(V),1)
Matthias Braun's avatar
Matthias Braun committed
21
Q ?= @
22
endif
Matthias Braun's avatar
Matthias Braun committed
23

24
# Tools
Matthias Braun's avatar
Matthias Braun committed
25
CC ?= cc
26
DOXYGEN ?= doxygen
Matthias Braun's avatar
Matthias Braun committed
27
LINK ?= $(CC)
28
AR ?= ar
29
DLLEXT ?= .so
Matthias Braun's avatar
Matthias Braun committed
30
31

# Variants
32
33
34
35
CFLAGS_debug       = -O0 -g3 -DDEBUG_libfirm
CFLAGS_profile     = -O3 -pg -DNDEBUG -fno-inline
CFLAGS_coverage    = -O0 --coverage -DDEBUG_libfirm
CFLAGS_optimize    = -O3 -fomit-frame-pointer -DNDEBUG
Andreas Zwinkau's avatar
Andreas Zwinkau committed
36
LINKFLAGS_debug    =
37
LINKFLAGS_profile  = -pg
38
LINKFLAGS_coverage = --coverage
Matthias Braun's avatar
Matthias Braun committed
39
40

# General flags
Andreas Zwinkau's avatar
Andreas Zwinkau committed
41
CPPFLAGS  ?=
42
CFLAGS    += $(CFLAGS_$(variant)) -std=c99 -fPIC -DHAVE_FIRM_REVISION_H
Matthias Braun's avatar
Matthias Braun committed
43
CFLAGS    += -Wall -W -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings
Matthias Braun's avatar
Matthias Braun committed
44
LINKFLAGS += $(LINKFLAGS_$(variant)) -lm
45
VPATH = $(srcdir) $(gendir)
46

Matthias Braun's avatar
Matthias Braun committed
47
all: firm
48
49
50
51
.PHONY: all

# disable make builtin suffix rules
.SUFFIXES:
Matthias Braun's avatar
Matthias Braun committed
52
53

# libFirm
54
55
56
57
58
59
60
61
62
63
64
libfirm_SOURCES     = $(subst $(srcdir)/,,$(wildcard $(srcdir)/ir/*/*.c))
libfirm_GEN_SOURCES =
libfirm_DIRS        = $(sort $(dir $(libfirm_SOURCES))) include/libfirm include/libfirm/adt
libfirm_GEN_DIRS    = $(sort $(dir $(libfirm_GEN_SOURCES)))
libfirm_INCLUDEDIRS = $(addprefix $(srcdir)/, $(libfirm_DIRS)) $(addprefix $(gendir)/, $(libfirm_GEN_DIRS))
libfirm_a           = $(builddir)/libfirm.a
libfirm_dll         = $(builddir)/libfirm$(DLLEXT)
libfirm_CPPFLAGS    = $(foreach dir,$(libfirm_INCLUDEDIRS),-I$(dir))
libfirm_OBJECTS     = $(libfirm_SOURCES:%.c=$(builddir)/%.o) $(libfirm_GEN_SOURCES:%.c=$(builddir)/%.o)
libfirm_DEPS        = $(libfirm_OBJECTS:%.o=%.d)
libfirm_BUILDDIRS   = $(sort $(dir $(libfirm_OBJECTS))) $(addprefix $(gendir)/, $(libfirm_GEN_DIRS))
Matthias Braun's avatar
Matthias Braun committed
65
66

.PHONY: firm
67
firm: $(libfirm_dll) $(libfirm_a)
Matthias Braun's avatar
Matthias Braun committed
68
69
70
71

# backends
backends = amd64 arm ia32 sparc TEMPLATE

72
73
74
EMITTER_GENERATOR = $(srcdir)/ir/be/scripts/generate_emitter.pl
REGALLOC_IF_GENERATOR = $(srcdir)/ir/be/scripts/generate_regalloc_if.pl
OPCODES_GENERATOR = $(srcdir)/ir/be/scripts/generate_new_opcodes.pl
75

Matthias Braun's avatar
Matthias Braun committed
76
define backend_template
77
$(1)_SOURCES = $$(subst $$(srcdir)/,,$$(wildcard $$(srcdir)/ir/be/$(1)/*.c))
Matthias Braun's avatar
Matthias Braun committed
78
79
80
81
$(1)_GEN_HEADERS =

$(1)_SPEC = ir/be/$(1)/$(1)_spec.pl

82
$$(gendir)/ir/be/$(1)/gen_$(1)_emitter.h $$(gendir)/ir/be/$(1)/gen_$(1)_emitter.c: $$($(1)_SPEC) $$(EMITTER_GENERATOR)
Matthias Braun's avatar
Matthias Braun committed
83
	@echo GEN $$@
84
85
86
	$(Q)$$(EMITTER_GENERATOR) $$< $$(gendir)/ir/be/$(1)
$(1)_GEN_SOURCES += ir/be/$(1)/gen_$(1)_emitter.c
$(1)_GEN_HEADERS += $$(gendir)/ir/be/$(1)/gen_$(1)_emitter.h
Matthias Braun's avatar
Matthias Braun committed
87

88
$$(gendir)/ir/be/$(1)/gen_$(1)_regalloc_if.h $$(gendir)/ir/be/$(1)/gen_$(1)_regalloc_if.c: $$($(1)_SPEC) $$(REGALLOC_IF_GENERATOR)
Matthias Braun's avatar
Matthias Braun committed
89
	@echo GEN $$@
90
91
92
	$(Q)$$(REGALLOC_IF_GENERATOR) $$< $$(gendir)/ir/be/$(1)
$(1)_GEN_SOURCES += ir/be/$(1)/gen_$(1)_regalloc_if.c
$(1)_GEN_HEADERS += $$(gendir)/ir/be/$(1)/gen_$(1)_regalloc_if.h
Matthias Braun's avatar
Matthias Braun committed
93

94
$$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.h $$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.c: $$($(1)_SPEC) $$(OPCODES_GENERATOR)
Matthias Braun's avatar
Matthias Braun committed
95
	@echo GEN $$@
96
	$(Q)$$(OPCODES_GENERATOR) $$< $$(gendir)/ir/be/$(1)
97
$(1)_GEN_SOURCES += ir/be/$(1)/gen_$(1)_new_nodes.c
98
$(1)_GEN_HEADERS += $$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.h
Matthias Braun's avatar
Matthias Braun committed
99
100

# We need to inform make of the headers it doesn't know yet...
101
$(1)_OBJECTS = $$($(1)_SOURCES:%.c=$$(builddir)/%.o) $$($(1)_GEN_SOURCES:%.c=$$(builddir)/%.o)
Matthias Braun's avatar
Matthias Braun committed
102
103
$$($(1)_OBJECTS): $$($(1)_GEN_HEADERS)

104
105
libfirm_GEN_SOURCES += $$($(1)_GEN_SOURCES)
libfirm_SOURCES += $$($1_SOURCES)
Matthias Braun's avatar
Matthias Braun committed
106
107
108
109
110
endef

$(foreach backend,$(backends),$(eval $(call backend_template,$(backend))))

# generators
111
IR_SPEC_GENERATED_INCLUDES := \
112
	$(gendir)/include/libfirm/nodes.h \
113
	$(gendir)/ir/ir/gen_proj_names.h  \
114
115
	$(gendir)/ir/ir/gen_irnode.h
IR_SPEC_GENERATOR := $(srcdir)/scripts/gen_ir.py
116
IR_SPEC_GENERATOR_DEPS := $(IR_SPEC_GENERATOR) $(srcdir)/scripts/jinjautil.py $(srcdir)/scripts/irops.py $(srcdir)/scripts/filters.py
117
118
119
IR_SPEC := $(srcdir)/scripts/ir_spec.py
libfirm_BUILDDIRS += $(gendir)/include/libfirm

120
121
122
libfirm_GEN_SOURCES += \
	ir/ir/gen_irnode.c \
	ir/ir/gen_irio.c
123
$(builddir)/ir/ir/gen_irnode.o: $(gendir)/ir/ir/gen_irnode.c
124
$(builddir)/ir/ir/gen_irio.o: $(gendir)/ir/ir/gen_irio.c
125
126

$(gendir)/ir/ir/% : scripts/templates/% $(IR_SPEC_GENERATOR_DEPS) $(IR_SPEC)
Matthias Braun's avatar
Matthias Braun committed
127
	@echo GEN $@
128
	$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) "$<" > "$@"
Matthias Braun's avatar
Matthias Braun committed
129

130
$(gendir)/include/libfirm/% : scripts/templates/% $(IR_SPEC_GENERATOR_DEPS) $(IR_SPEC)
Matthias Braun's avatar
Matthias Braun committed
131
	@echo GEN $@
132
	$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) "$<" > "$@"
Matthias Braun's avatar
Matthias Braun committed
133

134
libfirm_GEN_DIRS += ir/ir include/libfirm
Matthias Braun's avatar
Matthias Braun committed
135
136
137

$(libfirm_a): $(libfirm_OBJECTS)
	@echo AR $@
Matthias Braun's avatar
Matthias Braun committed
138
	$(Q)rm -f $@
139
	$(Q)$(AR) -crs $@ $^
Matthias Braun's avatar
Matthias Braun committed
140

141
$(libfirm_dll): $(libfirm_OBJECTS)
Matthias Braun's avatar
Matthias Braun committed
142
	@echo LINK $@
143
	$(Q)$(LINK) -shared $^ -o $@ $(LINKFLAGS)
Matthias Braun's avatar
Matthias Braun committed
144

145
# Determine if we can use cparser-beta for quickcheck
146
QUICKCHECK_DEFAULT := $(shell which cparser-beta 2> /dev/null || echo true) -fsyntax-only
147
QUICKCHECK ?= $(QUICKCHECK_DEFAULT)
148
QUICKCHECK_FLAGS ?= -m32 -Wno-compat-option -Wno-shadow -Wno-shadow-local -Wunreachable-code
149

150
$(builddir)/%.o: %.c $(IR_SPEC_GENERATED_INCLUDES)
Matthias Braun's avatar
Matthias Braun committed
151
	@echo CC $@
Matthias Braun's avatar
Matthias Braun committed
152
	$(Q)$(QUICKCHECK) $(QUICKCHECK_FLAGS) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) $(QUICKCHECK_FLAGS) $<
153
	$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) -MP -MMD -c -o $@ $<
Matthias Braun's avatar
Matthias Braun committed
154

155
$(docdir)/libfirm.tag: doc/Doxyfile doc/logo.png $(IR_SPEC_GENERATED_INCLUDES) $(wildcard include/libfirm/*.h) $(wildcard include/libfirm/adt/*.h)
Matthias Braun's avatar
Matthias Braun committed
156
	@echo Doxygen $@
157
	$(Q)$(DOXYGEN) $<
158

159
160
161
162
163
DOCU_TEMPLATE = $(srcdir)/scripts/templates/nodes.html
DOCU_TEMPLATE_DEPS = $(srcdir)/scripts/templates/style.css
$(docdir)/html/nodes.html: $(docdir)/libfirm.tag $(IR_SPEC_GENERATOR) $(IR_SPEC_GENERATOR_DEPS) $(IR_SPEC) $(DOCU_TEMPLATE) $(DOCU_TEMPLATE_DEPS)
	@echo GEN $@
	$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) $(DOCU_TEMPLATE) --tagfile $(docdir)/libfirm.tag > $@
164
165
166
	$(Q)cp $(DOCU_TEMPLATE_DEPS) $(docdir)/html

NODES_TEMPLATE = firm-homepage/nodes_templates/Nodes
167
168
169
$(docdir)/Nodes: $(docdir)/libfirm.tag $(IR_SPEC_GENERATOR) $(IR_SPEC_GENERATOR_DEPS) $(IR_SPEC) $(NODES_TEMPLATE)
	@echo GEN $@
	$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) $(NODES_TEMPLATE) --tagfile $(docdir)/libfirm.tag -I $(dir $(NODES_TEMPLATE)) > $@
170

Matthias Braun's avatar
Matthias Braun committed
171
172
.PHONY: doc
doc: $(docdir)/libfirm.tag $(docdir)/html/nodes.html
173

Matthias Braun's avatar
Matthias Braun committed
174
175
176
.PHONY: clean
clean:
	@echo CLEAN
177
	$(Q)rm -fr $(builddir) $(gendir) $(docdir)
Matthias Braun's avatar
Matthias Braun committed
178

179
180
181
.PHONY: install
PREFIX ?= /usr/local
INSTALL ?= install
182
INSTALLPREFIX = $(DESTDIR)$(PREFIX)
183
install: $(libfirm_a) $(libfirm_dll)
184
185
186
187
188
189
	$(INSTALL) -d "$(INSTALLPREFIX)/include/libfirm"
	$(INSTALL) -m0644 include/libfirm/*.h "$(INSTALLPREFIX)/include/libfirm"
	$(INSTALL) -m0644 "$(gendir)"/include/libfirm/*.h "$(INSTALLPREFIX)/include/libfirm"
	$(INSTALL) -d "$(INSTALLPREFIX)/include/libfirm/adt"
	$(INSTALL) -m0644 include/libfirm/adt/*.h "$(INSTALLPREFIX)/include/libfirm/adt"
	$(INSTALL) -d "$(INSTALLPREFIX)/lib"
190
	$(INSTALL) -m0644 $^ "$(INSTALLPREFIX)/lib"
191

192
193
194
195
196
197
198
199
200
201
202
203
# Ensure all output directories are created
UNUSED1 := $(shell mkdir -p $(libfirm_BUILDDIRS))

REVISION ?= $(shell git --git-dir $(top_srcdir)/.git describe --abbrev=40 --always --dirty --match '')

# Update revision.h if necessary
REVISIONH = $(gendir)/firm_revision.h
libfirm_INCLUDEDIRS += $(gendir)
UNUSED2 := $(shell \
	REV="\#define libfirm_VERSION_REVISION \"$(REVISION)\""; \
	echo "$$REV" | cmp -s - "$(REVISIONH)" 2> /dev/null || echo "$$REV" > "$(REVISIONH)" \
)
Matthias Braun's avatar
Matthias Braun committed
204
205
206
207

# Unit tests
UNITTESTS_SOURCES = $(subst $(srcdir)/unittests/,,$(wildcard $(srcdir)/unittests/*.c))
UNITTESTS         = $(UNITTESTS_SOURCES:%.c=$(builddir)/%.exe)
208
UNITTESTS_OK      = $(UNITTESTS_SOURCES:%.c=$(builddir)/%.ok)
Matthias Braun's avatar
Matthias Braun committed
209
210

$(builddir)/%.exe: $(srcdir)/unittests/%.c $(libfirm_a)
211
	@echo LINK $<
Matthias Braun's avatar
Matthias Braun committed
212
	$(Q)$(LINK) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) "$<" $(libfirm_a) -lm -o "$@"
Matthias Braun's avatar
Matthias Braun committed
213

214
215
216
217
218
$(builddir)/%.ok: $(builddir)/%.exe
	@echo EXEC $<
	$(Q)$< && touch "$@"

.PRECIOUS: $(UNITTESTS)
Matthias Braun's avatar
Matthias Braun committed
219
.PHONY: test
220
test: $(UNITTESTS_OK)
221

222
223
224
.PHONY: gen
gen: $(IR_SPEC_GENERATED_INCLUDES) $(libfirm_GEN_SOURCES)

225
-include $(libfirm_DEPS)