Makefile 6.77 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
16
top_builddir ?= build
host         ?= unknown-host
variant      ?= debug

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

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

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

# Variants
33
34
35
36
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
37
LINKFLAGS_debug    =
38
LINKFLAGS_profile  = -pg
39
LINKFLAGS_coverage = --coverage
Matthias Braun's avatar
Matthias Braun committed
40
41

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

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

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

# libFirm
55
56
57
58
59
60
61
62
63
64
65
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
66
67

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

# backends
backends = amd64 arm ia32 sparc TEMPLATE

73
74
75
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
76

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

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

83
$$(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
84
	@echo GEN $$@
85
86
87
	$(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
88

89
$$(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
90
	@echo GEN $$@
91
92
93
	$(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
94

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

100
$$(srcdir)/ir/be/$(1)/$(1)_new_nodes.c: $$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.c.inl
Matthias Braun's avatar
Matthias Braun committed
101
102

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

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

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

# generators
113
IR_SPEC_GENERATED_INCLUDES := \
114
115
116
117
118
119
120
121
122
123
124
125
	$(gendir)/include/libfirm/nodes.h \
	$(gendir)/ir/ir/gen_irdump.c.inl  \
	$(gendir)/ir/ir/gen_irnode.h
IR_SPEC_GENERATOR := $(srcdir)/scripts/gen_ir.py
IR_SPEC_GENERATOR_DEPS := $(IR_SPEC_GENERATOR) $(srcdir)/scripts/spec_util.py $(srcdir)/scripts/filters.py
IR_SPEC := $(srcdir)/scripts/ir_spec.py
libfirm_BUILDDIRS += $(gendir)/include/libfirm

libfirm_GEN_SOURCES += ir/ir/gen_irnode.c
$(builddir)/ir/ir/gen_irnode.o: $(gendir)/ir/ir/gen_irnode.c

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

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

133
libfirm_GEN_DIRS += ir/ir include/libfirm
Matthias Braun's avatar
Matthias Braun committed
134

135
ir/ir/irio.c : $(gendir)/ir/ir/gen_irio.c.inl
Matthias Braun's avatar
Matthias Braun committed
136
137
138

$(libfirm_a): $(libfirm_OBJECTS)
	@echo AR $@
139
	$(Q)$(AR) -crsu $@ $^
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
147
QUICKCHECK_DEFAULT := $(shell which cparser-beta || echo true) -fsyntax-only
QUICKCHECK ?= $(QUICKCHECK_DEFAULT)
Matthias Braun's avatar
Matthias Braun committed
148
QUICKCHECK_FLAGS ?= -Wno-shadow -Wno-shadow-local
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) $(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
DOCU_GENERATOR = $(srcdir)/scripts/gen_docu.py
DOCU_GENERATOR_DEPS = $(srcdir)/scripts/spec_util.py $(srcdir)/scripts/style.css
$(docdir)/html/nodes.html: $(docdir)/libfirm.tag $(DOCU_GENERATOR) $(DOCU_GENERATOR_DEPS) $(IR_SPEC)
Matthias Braun's avatar
Matthias Braun committed
162
	@echo gen_docu.py $@
Matthias Braun's avatar
Matthias Braun committed
163
	$(Q)$(DOCU_GENERATOR) $(IR_SPEC) $(docdir)/libfirm.tag "" $@
164
	$(Q)cp $(srcdir)/scripts/style.css $(docdir)/html
165

Matthias Braun's avatar
Matthias Braun committed
166
167
.PHONY: doc
doc: $(docdir)/libfirm.tag $(docdir)/html/nodes.html
168

Matthias Braun's avatar
Matthias Braun committed
169
170
171
.PHONY: clean
clean:
	@echo CLEAN
172
	$(Q)rm -fr $(builddir) $(gendir) $(docdir)
Matthias Braun's avatar
Matthias Braun committed
173

174
175
176
177
178
179
180
181
182
183
184
185
# 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
186
187
188
189
190
191
192

# Unit tests
UNITTESTS_SOURCES = $(subst $(srcdir)/unittests/,,$(wildcard $(srcdir)/unittests/*.c))
UNITTESTS         = $(UNITTESTS_SOURCES:%.c=$(builddir)/%.exe)

$(builddir)/%.exe: $(srcdir)/unittests/%.c $(libfirm_a)
	@echo TEST $<
Matthias Braun's avatar
Matthias Braun committed
193
	$(Q)$(LINK) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) "$<" $(libfirm_a) -lm -o "$@"
Matthias Braun's avatar
Matthias Braun committed
194
195
196
197
	$(Q)$@

.PHONY: test
test: $(UNITTESTS)
198
199

-include $(libfirm_DEPS)