174cb4994SMatthias Braun# libfirm Makefile
274cb4994SMatthias Braun#
374cb4994SMatthias Braun# This is currently experimental and not fully supported, but we plan to replace
474cb4994SMatthias Braun# the jambuild with this at some point in the future.
574cb4994SMatthias Braun#
674cb4994SMatthias Braun# Most variable names are similar to the names used by autoconf...
774cb4994SMatthias Braun-include config.mak
874cb4994SMatthias Braun
974cb4994SMatthias Braun# Some build configuration defaults
10e1c7cd54SMatthias Brauntop_srcdir   ?= .
1174cb4994SMatthias Brauntop_builddir ?= build
1274cb4994SMatthias Braunvariant      ?= debug
1374cb4994SMatthias Braun
1474cb4994SMatthias Braunsrcdir       ?= $(top_srcdir)
1574cb4994SMatthias Braunbuilddir     ?= $(top_builddir)/$(variant)
16e1c7cd54SMatthias Braungendir       ?= $(top_builddir)/gen
17c29f6008SMatthias Braundocdir       ?= $(top_builddir)/doc
1874cb4994SMatthias Braun
19b4cf7f2cSMatthias Braun# This hides the noisy commandline outputs. Show them with "make V=1"
20b4cf7f2cSMatthias Braunifneq ($(V),1)
2174cb4994SMatthias BraunQ ?= @
22b4cf7f2cSMatthias Braunendif
2374cb4994SMatthias Braun
24e1c7cd54SMatthias Braun# Tools
2574cb4994SMatthias BraunCC ?= cc
26ea177aefSMatthias BraunDOXYGEN ?= doxygen
2774cb4994SMatthias BraunLINK ?= $(CC)
28566f5c18SChristoph MallonAR ?= ar
29845e655dSMatthias Braunifeq ("$(shell uname)", "Darwin")
30845e655dSMatthias BraunDLLEXT ?= .dylib
31845e655dSMatthias BraunLINKDLLFLAGS = -dynamiclib -install_name $(abspath $@)
32845e655dSMatthias Braunelse
33b6497b15SMatthias BraunDLLEXT ?= .so
34845e655dSMatthias BraunLINKDLLFLAGS = -shared
35845e655dSMatthias Braunendif
3674cb4994SMatthias Braun
3774cb4994SMatthias Braun# Variants
38e1c7cd54SMatthias BraunCFLAGS_debug       = -O0 -g3 -DDEBUG_libfirm
39e1c7cd54SMatthias BraunCFLAGS_profile     = -O3 -pg -DNDEBUG -fno-inline
40e1c7cd54SMatthias BraunCFLAGS_coverage    = -O0 --coverage -DDEBUG_libfirm
41e1c7cd54SMatthias BraunCFLAGS_optimize    = -O3 -fomit-frame-pointer -DNDEBUG
42fd395c41SAndreas ZwinkauLINKFLAGS_debug    =
433acb7cd6SMatthias BraunLINKFLAGS_profile  = -pg
443db684b4SMatthias BraunLINKFLAGS_coverage = --coverage
4574cb4994SMatthias Braun
4674cb4994SMatthias Braun# General flags
47fd395c41SAndreas ZwinkauCPPFLAGS  ?=
48e1c7cd54SMatthias BraunCFLAGS    += $(CFLAGS_$(variant)) -std=c99 -fPIC -DHAVE_FIRM_REVISION_H
4974cb4994SMatthias BraunCFLAGS    += -Wall -W -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings
50a276562eSMatthias BraunLINKFLAGS += $(LINKFLAGS_$(variant)) -lm
51e1c7cd54SMatthias BraunVPATH = $(srcdir) $(gendir)
522e9fdf88SAndreas Zwinkau
5374cb4994SMatthias Braunall: firm
543db684b4SMatthias Braun.PHONY: all
553db684b4SMatthias Braun
563db684b4SMatthias Braun# disable make builtin suffix rules
573db684b4SMatthias Braun.SUFFIXES:
5874cb4994SMatthias Braun
5974cb4994SMatthias Braun# libFirm
60e1c7cd54SMatthias Braunlibfirm_SOURCES     = $(subst $(srcdir)/,,$(wildcard $(srcdir)/ir/*/*.c))
61e1c7cd54SMatthias Braunlibfirm_GEN_SOURCES =
62e1c7cd54SMatthias Braunlibfirm_DIRS        = $(sort $(dir $(libfirm_SOURCES))) include/libfirm include/libfirm/adt
63e1c7cd54SMatthias Braunlibfirm_GEN_DIRS    = $(sort $(dir $(libfirm_GEN_SOURCES)))
64e1c7cd54SMatthias Braunlibfirm_INCLUDEDIRS = $(addprefix $(srcdir)/, $(libfirm_DIRS)) $(addprefix $(gendir)/, $(libfirm_GEN_DIRS))
65e1c7cd54SMatthias Braunlibfirm_a           = $(builddir)/libfirm.a
66e1c7cd54SMatthias Braunlibfirm_dll         = $(builddir)/libfirm$(DLLEXT)
67e1c7cd54SMatthias Braunlibfirm_CPPFLAGS    = $(foreach dir,$(libfirm_INCLUDEDIRS),-I$(dir))
68e1c7cd54SMatthias Braunlibfirm_OBJECTS     = $(libfirm_SOURCES:%.c=$(builddir)/%.o) $(libfirm_GEN_SOURCES:%.c=$(builddir)/%.o)
69e1c7cd54SMatthias Braunlibfirm_DEPS        = $(libfirm_OBJECTS:%.o=%.d)
70e1c7cd54SMatthias Braunlibfirm_BUILDDIRS   = $(sort $(dir $(libfirm_OBJECTS))) $(addprefix $(gendir)/, $(libfirm_GEN_DIRS))
7174cb4994SMatthias Braun
7274cb4994SMatthias Braun.PHONY: firm
73820f6aeeSMatthias Braunfirm: $(libfirm_dll) $(libfirm_a)
7474cb4994SMatthias Braun
7574cb4994SMatthias Braun# backends
76ddff058aSChristoph Mallonbackends = amd64 arm ia32 mips sparc TEMPLATE
7774cb4994SMatthias Braun
78e1c7cd54SMatthias BraunEMITTER_GENERATOR = $(srcdir)/ir/be/scripts/generate_emitter.pl
79e1c7cd54SMatthias BraunREGALLOC_IF_GENERATOR = $(srcdir)/ir/be/scripts/generate_regalloc_if.pl
80e1c7cd54SMatthias BraunOPCODES_GENERATOR = $(srcdir)/ir/be/scripts/generate_new_opcodes.pl
815d1afe77SMatthias Braun
8274cb4994SMatthias Braundefine backend_template
83e1c7cd54SMatthias Braun$(1)_SOURCES = $$(subst $$(srcdir)/,,$$(wildcard $$(srcdir)/ir/be/$(1)/*.c))
8474cb4994SMatthias Braun$(1)_GEN_HEADERS =
8574cb4994SMatthias Braun
8674cb4994SMatthias Braun$(1)_SPEC = ir/be/$(1)/$(1)_spec.pl
8774cb4994SMatthias Braun
88e1c7cd54SMatthias Braun$$(gendir)/ir/be/$(1)/gen_$(1)_emitter.h $$(gendir)/ir/be/$(1)/gen_$(1)_emitter.c: $$($(1)_SPEC) $$(EMITTER_GENERATOR)
8974cb4994SMatthias Braun	@echo GEN $$@
90e1c7cd54SMatthias Braun	$(Q)$$(EMITTER_GENERATOR) $$< $$(gendir)/ir/be/$(1)
91e1c7cd54SMatthias Braun$(1)_GEN_SOURCES += ir/be/$(1)/gen_$(1)_emitter.c
92e1c7cd54SMatthias Braun$(1)_GEN_HEADERS += $$(gendir)/ir/be/$(1)/gen_$(1)_emitter.h
9374cb4994SMatthias Braun
94e1c7cd54SMatthias Braun$$(gendir)/ir/be/$(1)/gen_$(1)_regalloc_if.h $$(gendir)/ir/be/$(1)/gen_$(1)_regalloc_if.c: $$($(1)_SPEC) $$(REGALLOC_IF_GENERATOR)
9574cb4994SMatthias Braun	@echo GEN $$@
96e1c7cd54SMatthias Braun	$(Q)$$(REGALLOC_IF_GENERATOR) $$< $$(gendir)/ir/be/$(1)
97e1c7cd54SMatthias Braun$(1)_GEN_SOURCES += ir/be/$(1)/gen_$(1)_regalloc_if.c
98e1c7cd54SMatthias Braun$(1)_GEN_HEADERS += $$(gendir)/ir/be/$(1)/gen_$(1)_regalloc_if.h
9974cb4994SMatthias Braun
10004580e62SMatthias Braun$$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.h $$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.c: $$($(1)_SPEC) $$(OPCODES_GENERATOR)
10174cb4994SMatthias Braun	@echo GEN $$@
102e1c7cd54SMatthias Braun	$(Q)$$(OPCODES_GENERATOR) $$< $$(gendir)/ir/be/$(1)
10304580e62SMatthias Braun$(1)_GEN_SOURCES += ir/be/$(1)/gen_$(1)_new_nodes.c
104e1c7cd54SMatthias Braun$(1)_GEN_HEADERS += $$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.h
10574cb4994SMatthias Braun
10674cb4994SMatthias Braun# We need to inform make of the headers it doesn't know yet...
107e1c7cd54SMatthias Braun$(1)_OBJECTS = $$($(1)_SOURCES:%.c=$$(builddir)/%.o) $$($(1)_GEN_SOURCES:%.c=$$(builddir)/%.o)
10874cb4994SMatthias Braun$$($(1)_OBJECTS): $$($(1)_GEN_HEADERS)
10974cb4994SMatthias Braun
110e1c7cd54SMatthias Braunlibfirm_GEN_SOURCES += $$($(1)_GEN_SOURCES)
111e1c7cd54SMatthias Braunlibfirm_SOURCES += $$($1_SOURCES)
11274cb4994SMatthias Braunendef
11374cb4994SMatthias Braun
11474cb4994SMatthias Braun$(foreach backend,$(backends),$(eval $(call backend_template,$(backend))))
11574cb4994SMatthias Braun
11674cb4994SMatthias Braun# generators
1175d1afe77SMatthias BraunIR_SPEC_GENERATED_INCLUDES := \
118e1c7cd54SMatthias Braun	$(gendir)/include/libfirm/nodes.h \
119d139b0b0SMatthias Braun	$(gendir)/ir/ir/gen_proj_names.h  \
120e1c7cd54SMatthias Braun	$(gendir)/ir/ir/gen_irnode.h
121e1c7cd54SMatthias BraunIR_SPEC_GENERATOR := $(srcdir)/scripts/gen_ir.py
122ce4907eaSMatthias BraunIR_SPEC_GENERATOR_DEPS := $(IR_SPEC_GENERATOR) $(srcdir)/scripts/jinjautil.py $(srcdir)/scripts/irops.py $(srcdir)/scripts/filters.py
123e1c7cd54SMatthias BraunIR_SPEC := $(srcdir)/scripts/ir_spec.py
124e1c7cd54SMatthias Braunlibfirm_BUILDDIRS += $(gendir)/include/libfirm
125e1c7cd54SMatthias Braun
126ca1a30a4SMatthias Braunlibfirm_GEN_SOURCES += \
127ca1a30a4SMatthias Braun	ir/ir/gen_irnode.c \
128ca1a30a4SMatthias Braun	ir/ir/gen_irio.c
129e1c7cd54SMatthias Braun$(builddir)/ir/ir/gen_irnode.o: $(gendir)/ir/ir/gen_irnode.c
130ca1a30a4SMatthias Braun$(builddir)/ir/ir/gen_irio.o: $(gendir)/ir/ir/gen_irio.c
131e1c7cd54SMatthias Braun
132e1c7cd54SMatthias Braun$(gendir)/ir/ir/% : scripts/templates/% $(IR_SPEC_GENERATOR_DEPS) $(IR_SPEC)
133b4dbd5b7SMatthias Braun	@echo GEN $@
134e1c7cd54SMatthias Braun	$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) "$<" > "$@"
135b4dbd5b7SMatthias Braun
136e1c7cd54SMatthias Braun$(gendir)/include/libfirm/% : scripts/templates/% $(IR_SPEC_GENERATOR_DEPS) $(IR_SPEC)
13774cb4994SMatthias Braun	@echo GEN $@
138e1c7cd54SMatthias Braun	$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) "$<" > "$@"
13974cb4994SMatthias Braun
140e1c7cd54SMatthias Braunlibfirm_GEN_DIRS += ir/ir include/libfirm
14174cb4994SMatthias Braun
14274cb4994SMatthias Braun$(libfirm_a): $(libfirm_OBJECTS)
14374cb4994SMatthias Braun	@echo AR $@
144c2c5318fSMatthias Braun	$(Q)rm -f $@
145bdd950d1SSebastian Buchwald	$(Q)$(AR) -crs $@ $^
14674cb4994SMatthias Braun
147b6497b15SMatthias Braun$(libfirm_dll): $(libfirm_OBJECTS)
14874cb4994SMatthias Braun	@echo LINK $@
149845e655dSMatthias Braun	$(Q)$(LINK) $(LINKDLLFLAGS) $^ -o $@ $(LINKFLAGS)
15074cb4994SMatthias Braun
151a2646117SMatthias Braun# Determine if we can use cparser-beta for quickcheck
152670c690eSChristoph MallonQUICKCHECK_DEFAULT := $(shell which cparser-beta 2> /dev/null || echo true) -fsyntax-only
153cf3d7fb8SLuca BarbatoQUICKCHECK ?= $(QUICKCHECK_DEFAULT)
1542440a415SMatthias BraunQUICKCHECK_FLAGS ?= -m32 -Wno-compat-option -Wno-shadow -Wno-shadow-local -Wunreachable-code
155a2646117SMatthias Braun
1565d1afe77SMatthias Braun$(builddir)/%.o: %.c $(IR_SPEC_GENERATED_INCLUDES)
15774cb4994SMatthias Braun	@echo CC $@
158a0d0b399SMatthias Braun	$(Q)$(QUICKCHECK) $(QUICKCHECK_FLAGS) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) $(QUICKCHECK_FLAGS) $<
159d9292f4dSMatthias Braun	$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) -MP -MMD -c -o $@ $<
16074cb4994SMatthias Braun
16158f24091SMatthias Braun$(docdir)/libfirm.tag: doc/Doxyfile doc/logo.png $(IR_SPEC_GENERATED_INCLUDES) $(wildcard include/libfirm/*.h) $(wildcard include/libfirm/adt/*.h)
162c29f6008SMatthias Braun	@echo Doxygen $@
163e1c7cd54SMatthias Braun	$(Q)$(DOXYGEN) $<
164ea177aefSMatthias Braun
165c29f6008SMatthias Braun.PHONY: doc
1665988c8efSMatthias Braundoc: $(docdir)/libfirm.tag
167ea177aefSMatthias Braun
16874cb4994SMatthias Braun.PHONY: clean
16974cb4994SMatthias Braunclean:
17074cb4994SMatthias Braun	@echo CLEAN
171e1c7cd54SMatthias Braun	$(Q)rm -fr $(builddir) $(gendir) $(docdir)
172b4dbd5b7SMatthias Braun
17334052d2cSMatthias Braun.PHONY: install
17434052d2cSMatthias BraunPREFIX ?= /usr/local
17534052d2cSMatthias BraunINSTALL ?= install
176de252364SMatthias BraunINSTALLPREFIX = $(DESTDIR)$(PREFIX)
177bda1b5e3SZ. Gilboainstall: $(libfirm_a) $(libfirm_dll)
17839870ddeSMatthias Braun	$(INSTALL) -d "$(INSTALLPREFIX)/include/libfirm"
17939870ddeSMatthias Braun	$(INSTALL) -m0644 include/libfirm/*.h "$(INSTALLPREFIX)/include/libfirm"
18039870ddeSMatthias Braun	$(INSTALL) -m0644 "$(gendir)"/include/libfirm/*.h "$(INSTALLPREFIX)/include/libfirm"
18139870ddeSMatthias Braun	$(INSTALL) -d "$(INSTALLPREFIX)/include/libfirm/adt"
18239870ddeSMatthias Braun	$(INSTALL) -m0644 include/libfirm/adt/*.h "$(INSTALLPREFIX)/include/libfirm/adt"
18339870ddeSMatthias Braun	$(INSTALL) -d "$(INSTALLPREFIX)/lib"
184bda1b5e3SZ. Gilboa	$(INSTALL) -m0644 $^ "$(INSTALLPREFIX)/lib"
18534052d2cSMatthias Braun
186e1c7cd54SMatthias Braun# Ensure all output directories are created
187e1c7cd54SMatthias BraunUNUSED1 := $(shell mkdir -p $(libfirm_BUILDDIRS))
188e1c7cd54SMatthias Braun
189e1c7cd54SMatthias BraunREVISION ?= $(shell git --git-dir $(top_srcdir)/.git describe --abbrev=40 --always --dirty --match '')
190e1c7cd54SMatthias Braun
191e1c7cd54SMatthias Braun# Update revision.h if necessary
192e1c7cd54SMatthias BraunREVISIONH = $(gendir)/firm_revision.h
193e1c7cd54SMatthias Braunlibfirm_INCLUDEDIRS += $(gendir)
194e1c7cd54SMatthias BraunUNUSED2 := $(shell \
195e1c7cd54SMatthias Braun	REV="\#define libfirm_VERSION_REVISION \"$(REVISION)\""; \
196e1c7cd54SMatthias Braun	echo "$$REV" | cmp -s - "$(REVISIONH)" 2> /dev/null || echo "$$REV" > "$(REVISIONH)" \
197e1c7cd54SMatthias Braun)
198b29f3440SMatthias Braun
199b29f3440SMatthias Braun# Unit tests
200b29f3440SMatthias BraunUNITTESTS_SOURCES = $(subst $(srcdir)/unittests/,,$(wildcard $(srcdir)/unittests/*.c))
201b29f3440SMatthias BraunUNITTESTS         = $(UNITTESTS_SOURCES:%.c=$(builddir)/%.exe)
2026ae5546cSMatthias BraunUNITTESTS_OK      = $(UNITTESTS_SOURCES:%.c=$(builddir)/%.ok)
203b29f3440SMatthias Braun
204b29f3440SMatthias Braun$(builddir)/%.exe: $(srcdir)/unittests/%.c $(libfirm_a)
2056ae5546cSMatthias Braun	@echo LINK $<
20619cef902SMatthias Braun	$(Q)$(LINK) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) "$<" $(libfirm_a) -lm -o "$@"
207b29f3440SMatthias Braun
2086ae5546cSMatthias Braun$(builddir)/%.ok: $(builddir)/%.exe
2096ae5546cSMatthias Braun	@echo EXEC $<
2106ae5546cSMatthias Braun	$(Q)$< && touch "$@"
2116ae5546cSMatthias Braun
2126ae5546cSMatthias Braun.PRECIOUS: $(UNITTESTS)
213b29f3440SMatthias Braun.PHONY: test
2146ae5546cSMatthias Brauntest: $(UNITTESTS_OK)
2153a38a7f3SMatthias Braun
2160f57a8fcSZ. Gilboa.PHONY: gen
2170f57a8fcSZ. Gilboagen: $(IR_SPEC_GENERATED_INCLUDES) $(libfirm_GEN_SOURCES)
2180f57a8fcSZ. Gilboa
2193a38a7f3SMatthias Braun-include $(libfirm_DEPS)
220