Commit e1c7cd54 authored by Matthias Braun's avatar Matthias Braun
Browse files

put generated files into builddir, fix out-of-tree builds

This is a major Makefile refactoring:
differentiate between:
- source files in $(srcdir)
- generated files in $(top_builddir)/gen
- object files in $(top_builddir)/$(variant)/ aka $(builddir)
- documentation in $(top_builddir)/doc
parent 9ddf1370
......@@ -128,7 +128,7 @@ FULL_PATH_NAMES = YES
# If left blank the directory from which doxygen is run is used as the
# path to strip.
STRIP_FROM_PATH = include
STRIP_FROM_PATH = include build/gen
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
# the path mentioned in the documentation of a class, which tells
......@@ -655,7 +655,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = include
INPUT = include build/gen
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
......
......@@ -7,18 +7,20 @@
-include config.mak
# Some build configuration defaults
top_srcdir ?=
top_srcdir ?= .
top_builddir ?= build
host ?= unknown-host
variant ?= debug
srcdir ?= $(top_srcdir)
builddir ?= $(top_builddir)/$(variant)
gendir ?= $(top_builddir)/gen
docdir ?= $(top_builddir)/doc
# This hides the noisy commandline outputs. You can see them with "make Q="
# This hides the noisy commandline outputs. Show them with "make Q="
Q ?= @
# Tools
CC ?= cc
DOXYGEN ?= doxygen
LINK ?= $(CC)
......@@ -26,29 +28,20 @@ AR ?= ar
DLLEXT ?= .so
# Variants
CFLAGS_all = -std=c99 -fPIC -DHAVE_FIRM_REVISION_H
CFLAGS_debug = $(CFLAGS_all) -O0 -g3 -DDEBUG_libfirm
CFLAGS_profile = $(CFLAGS_all) -O3 -pg -DNDEBUG -fno-inline
CFLAGS_coverage = $(CFLAGS_all) -O0 --coverage -DDEBUG_libfirm
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
LINKFLAGS_debug =
LINKFLAGS_profile = -pg
LINKFLAGS_coverage = --coverage
CFLAGS_optimize = $(CFLAGS_all) -O3 -fomit-frame-pointer -DNDEBUG
# General flags
CPPFLAGS ?=
CFLAGS += $(CFLAGS_$(variant))
CFLAGS += $(CFLAGS_$(variant)) -std=c99 -fPIC -DHAVE_FIRM_REVISION_H
CFLAGS += -Wall -W -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings
LINKFLAGS += $(LINKFLAGS_$(variant)) -lm
VPATH = $(srcdir)
REVISION ?= $(shell git describe --abbrev=40 --always --dirty --match '')
# Update revision.h if necessary
UNUSED := $(shell \
REV="\#define libfirm_VERSION_REVISION \"$(REVISION)\""; \
echo "$$REV" | cmp -s - firm_revision.h 2> /dev/null || echo "$$REV" > firm_revision.h \
)
VPATH = $(srcdir) $(gendir)
all: firm
.PHONY: all
......@@ -57,11 +50,18 @@ all: firm
.SUFFIXES:
# libFirm
libfirm_SOURCES = $(wildcard ir/*/*.c)
libfirm_DIRS = $(sort $(dir $(libfirm_SOURCES)))
libfirm_a = $(builddir)/libfirm.a
libfirm_dll = $(builddir)/libfirm$(DLLEXT)
libfirm_CPPFLAGS = -Iinclude/libfirm -Iinclude/libfirm/adt -I. $(foreach dir,$(libfirm_DIRS),-I$(dir))
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))
-include $(libfirm_DEPS)
.PHONY: firm
firm: $(libfirm_dll)
......@@ -69,88 +69,76 @@ firm: $(libfirm_dll)
# backends
backends = amd64 arm ia32 sparc TEMPLATE
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
GENERATED_FILES =
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
define backend_template
$(1)_SOURCES = $$(wildcard ir/be/$(1)/*.c)
$(1)_SOURCES := $$(filter-out ir/be/$(1)/gen_%.c, $$($(1)_SOURCES))
$(1)_SOURCES = $$(subst $$(srcdir)/,,$$(wildcard $$(srcdir)/ir/be/$(1)/*.c))
$(1)_GEN_HEADERS =
$(1)_SPEC = ir/be/$(1)/$(1)_spec.pl
$$(srcdir)ir/be/$(1)/gen_$(1)_emitter.h $$(srcdir)ir/be/$(1)/gen_$(1)_emitter.c: $$($(1)_SPEC) $$(EMITTER_GENERATOR)
$$(gendir)/ir/be/$(1)/gen_$(1)_emitter.h $$(gendir)/ir/be/$(1)/gen_$(1)_emitter.c: $$($(1)_SPEC) $$(EMITTER_GENERATOR)
@echo GEN $$@
$(Q)$$(EMITTER_GENERATOR) $$($(1)_SPEC) $$(srcdir)ir/be/$(1)
$(1)_SOURCES += ir/be/$(1)/gen_$(1)_emitter.c
$(1)_GEN_HEADERS += ir/be/$(1)/gen_$(1)_emitter.h
GENERATED_FILES += ir/be/$(1)/gen_$(1)_emitter.c ir/be/$(1)/gen_$(1)_emitter.h
$(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
$$(srcdir)ir/be/$(1)/gen_$(1)_regalloc_if.h $$(srcdir)ir/be/$(1)/gen_$(1)_regalloc_if.c: $$($(1)_SPEC) $$(REGALLOC_IF_GENERATOR)
$$(gendir)/ir/be/$(1)/gen_$(1)_regalloc_if.h $$(gendir)/ir/be/$(1)/gen_$(1)_regalloc_if.c: $$($(1)_SPEC) $$(REGALLOC_IF_GENERATOR)
@echo GEN $$@
$(Q)$$(REGALLOC_IF_GENERATOR) $$($(1)_SPEC) $$(srcdir)ir/be/$(1)
$(1)_SOURCES += ir/be/$(1)/gen_$(1)_regalloc_if.c
$(1)_GEN_HEADERS += ir/be/$(1)/gen_$(1)_regalloc_if.h
GENERATED_FILES += ir/be/$(1)/gen_$(1)_regalloc_if.c ir/be/$(1)/gen_$(1)_regalloc_if.h
$(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
$$(srcdir)ir/be/$(1)/gen_$(1)_new_nodes.h $$(srcdir)ir/be/$(1)/gen_$(1)_new_nodes.c.inl: $$($(1)_SPEC) $$(OPCODES_GENERATOR)
$$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.h $$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.c.inl: $$($(1)_SPEC) $$(OPCODES_GENERATOR)
@echo GEN $$@
$(Q)$$(OPCODES_GENERATOR) $$($(1)_SPEC) $$(srcdir)ir/be/$(1)
$(1)_GEN_HEADERS += ir/be/$(1)/gen_$(1)_new_nodes.h
GENERATED_FILES += ir/be/$(1)/gen_$(1)_new_nodes.h ir/be/$(1)/gen_$(1)_new_nodes.c.inl
$(Q)$$(OPCODES_GENERATOR) $$< $$(gendir)/ir/be/$(1)
$(1)_GEN_HEADERS += $$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.h
ir/be/$(1)/$(1)_new_nodes.c: ir/be/$(1)/gen_$(1)_new_nodes.c.inl
$$(srcdir)/ir/be/$(1)/$(1)_new_nodes.c: $$(gendir)/ir/be/$(1)/gen_$(1)_new_nodes.c.inl
# We need to inform make of the headers it doesn't know yet...
$(1)_OBJECTS = $$($(1)_SOURCES:%.c=$$(builddir)/%.o)
$(1)_OBJECTS = $$($(1)_SOURCES:%.c=$$(builddir)/%.o) $$($(1)_GEN_SOURCES:%.c=$$(builddir)/%.o)
$$($(1)_OBJECTS): $$($(1)_GEN_HEADERS)
libfirm_SOURCES += $$($(1)_SOURCES)
libfirm_DIRS += ir/be/$(1)
libfirm_GEN_SOURCES += $$($(1)_GEN_SOURCES)
libfirm_SOURCES += $$($1_SOURCES)
endef
$(foreach backend,$(backends),$(eval $(call backend_template,$(backend))))
# generators
IR_SPEC_GENERATED_INCLUDES := \
include/libfirm/nodes.h \
ir/ir/gen_irdump.c.inl \
ir/ir/gen_irnode.h
GENERATED_FILES += $(IR_SPEC_GENERATED_INCLUDES)
IR_SPEC_GENERATOR := scripts/gen_ir.py
IR_SPEC_GENERATOR_DEPS := $(IR_SPEC_GENERATOR) scripts/spec_util.py scripts/filters.py
IR_SPEC := scripts/ir_spec.py
libfirm_SOURCES := $(filter-out ir/ir/gen_%.c, $(libfirm_SOURCES))
libfirm_SOURCES := $(libfirm_SOURCES) ir/ir/gen_irnode.c
GENERATED_FILES += ir/ir/gen_irnode.c
ir/ir/% : scripts/templates/% $(IR_SPEC_GENERATOR_DEPS) $(IR_SPEC)
$(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)
@echo GEN $@
$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) $< > $@
$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) "$<" > "$@"
include/libfirm/% : scripts/templates/% $(IR_SPEC_GENERATOR_DEPS) $(IR_SPEC)
$(gendir)/include/libfirm/% : scripts/templates/% $(IR_SPEC_GENERATOR_DEPS) $(IR_SPEC)
@echo GEN $@
$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) $< > $@
$(Q)$(IR_SPEC_GENERATOR) $(IR_SPEC) "$<" > "$@"
IR_IO_GENERATED_FILES := ir/ir/gen_irio.c.inl
IR_IO_GENERATOR := scripts/gen_ir_io.py
IR_IO_GENERATOR_DEPS := $(IR_IO_GENERATOR) scripts/spec_util.py scripts/filters.py
GENERATED_FILES += $(IR_IO_GENERATED_FILES)
IR_IO_GENERATOR := $(srcdir)/scripts/gen_ir_io.py
IR_IO_GENERATOR_DEPS := $(IR_IO_GENERATOR) $(srcdir)/scripts/spec_util.py $(srcdir)/scripts/filters.py
libfirm_GEN_DIRS += ir/ir include/libfirm
ir/ir/irio.c : ir/ir/gen_irio.c.inl
ir/ir/irio.c : $(gendir)/ir/ir/gen_irio.c.inl
ir/ir/% : scripts/templates_io/% $(IR_IO_GENERATOR_DEPS) $(IR_SPEC)
@echo GEN $@
$(Q)$(IR_IO_GENERATOR) $(IR_SPEC) $< > $@
libfirm_OBJECTS = $(libfirm_SOURCES:%.c=$(builddir)/%.o)
libfirm_DEPS = $(libfirm_OBJECTS:%.o=%.d)
-include $(libfirm_DEPS)
$(gendir)/ir/ir/% : scripts/templates_io/% $(IR_IO_GENERATOR_DEPS) $(IR_SPEC)
@echo GEN $@
$(Q)$(IR_IO_GENERATOR) $(IR_SPEC) "$<" > "$@"
$(libfirm_a): $(libfirm_OBJECTS)
@echo AR $@
......@@ -160,8 +148,6 @@ $(libfirm_dll): $(libfirm_OBJECTS)
@echo LINK $@
$(Q)$(LINK) -shared $(LINKFLAGS) -o $@ $^
# Generic rules
UNUSED := $(shell mkdir -p $(libfirm_DIRS:%=$(builddir)/%))
# Determine if we can use cparser-beta for quickcheck
QUICKCHECK_DEFAULT := $(shell which cparser-beta || echo true) -fsyntax-only
QUICKCHECK ?= $(QUICKCHECK_DEFAULT)
......@@ -172,15 +158,16 @@ $(builddir)/%.o: %.c $(IR_SPEC_GENERATED_INCLUDES)
$(Q)$(QUICKCHECK) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) $(QUICKCHECK_FLAGS) $<
$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(libfirm_CPPFLAGS) -MMD -c -o $@ $<
$(docdir)/libfirm.tag: $(IR_SPEC_GENERATED_INCLUDES) Doxyfile $(wildcard include/libfirm/*.h) $(wildcard include/libfirm/adt/*.h)
$(docdir)/libfirm.tag: Doxyfile $(IR_SPEC_GENERATED_INCLUDES) $(wildcard include/libfirm/*.h) $(wildcard include/libfirm/adt/*.h)
@echo Doxygen $@
$(Q)$(DOXYGEN)
$(Q)$(DOXYGEN) $<
DOCU_GENERATOR := scripts/gen_docu.py
$(docdir)/html/nodes.html: $(docdir)/libfirm.tag $(DOCU_GENERATOR) $(IR_SPEC) scripts/spec_util.py scripts/style.css
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)
@echo gen_docu.py $@
$(Q)$(DOCU_GENERATOR) $(IR_SPEC) $(docdir)/libfirm.tag "" $@
$(Q)cp scripts/style.css $(docdir)/html
$(Q)cp $(srcdir)/scripts/style.css $(docdir)/html
.PHONY: doc
doc: $(docdir)/libfirm.tag $(docdir)/html/nodes.html
......@@ -188,9 +175,22 @@ doc: $(docdir)/libfirm.tag $(docdir)/html/nodes.html
.PHONY: clean
clean:
@echo CLEAN
$(Q)rm -fr $(builddir) $(GENERATED_FILES)
$(Q)rm -fr $(builddir) $(gendir) $(docdir)
# This rule is necessary so that make does not abort if headers get deleted
# (the deleted header might still be referenced in a .d file)
%.h:
@:
# 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)" \
)
......@@ -153,7 +153,7 @@ def format_escape_keywords(word):
def format_parameters(string):
return format_arguments(string, voidwhenempty = True)
env = Environment(loader=FileSystemLoader("."))
env = Environment(loader=FileSystemLoader([".", "/"]))
env.filters['a_an'] = format_a_an
env.filters['parameterlist'] = format_parameterlist
env.filters['nodearguments'] = format_nodearguments
......
......@@ -26,7 +26,7 @@ def format_block(node):
else:
return "block"
env = Environment(loader=FileSystemLoader("."))
env = Environment(loader=FileSystemLoader([".", "/"]))
env.filters['args'] = format_args
env.filters['block'] = format_block
env.filters['arguments'] = format_arguments
......
{{warning}}
#ifndef FIRM_{{spec.name|upper}}_NODES_H
#define FIRM_{{spec.name|upper}}_NODES_H
{% if spec.external -%}
{% set FIRM_API="" %}
{%- else -%}
#include "firm_types.h"
#include "begin.h"
{%- set FIRM_API="FIRM_API "-%}
{%- endif -%}
......@@ -154,9 +149,3 @@ ir_node **get_{{node.name}}_{{node.input_name}}_arr(ir_node *node);
{% endfor -%}
/** @} */
{% if not spec.external %}
#include "end.h"
{% endif %}
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment