summaryrefslogtreecommitdiffstats
path: root/make/include
diff options
context:
space:
mode:
Diffstat (limited to 'make/include')
-rw-r--r--make/include/base.defs50
-rw-r--r--make/include/contrib.defs276
-rw-r--r--make/include/function.defs19
-rw-r--r--make/include/gcc.defs146
-rw-r--r--make/include/main.defs75
-rw-r--r--make/include/main.rules39
-rw-r--r--make/include/report.defs53
-rw-r--r--make/include/select.defs12
-rw-r--r--make/include/target.defs14
-rw-r--r--make/include/tool.defs10
10 files changed, 694 insertions, 0 deletions
diff --git a/make/include/base.defs b/make/include/base.defs
new file mode 100644
index 000000000..3b4e666f3
--- /dev/null
+++ b/make/include/base.defs
@@ -0,0 +1,50 @@
+## Define module metadata.
+## It is mandatory for every module to use this template.
+##
+## $(1) module name (uppercase)
+## $(2) module name (lowercase)
+## $(3) list of prerequisite modules (uppercase)
+##
+define import.MODULE.defs
+ ## indicates module is defined; useful for conditionals
+ $(1).enabled = 1
+
+ ## module name (lowercase)
+ $(1).name = $(2)
+
+ ## list of prerequisite modules (uppercase)
+ $(1).prerequisites = $(3)
+
+ ## add to global list of modules
+ MODULES.NAMES += $(1)
+ MODULES.names += $(2)
+endef
+
+##
+## $(1) module name (uppercase)
+##
+define import.MODULE.rules
+$($(1).name).report:
+ @$(MAKE) report.true REPORT=module REPORT.module=$(1)
+
+## aggregate
+report.modules:: $($(1).name).report
+
+endef
+
+.PHONY: report.main report.gcc report.modules
+
+report.modules::
+
+.PHONY: report.main
+report.main:
+ @$(MAKE) report.true REPORT=main
+
+.PHONY: report.gcc
+report.gcc:
+ @$(MAKE) report.true REPORT=gcc
+
+## needed for nested make (which drives each report)
+.PHONY: report.true
+report.true:
+ @true
diff --git a/make/include/contrib.defs b/make/include/contrib.defs
new file mode 100644
index 000000000..772258c37
--- /dev/null
+++ b/make/include/contrib.defs
@@ -0,0 +1,276 @@
+CONTRIB.build/ = $(BUILD/)contrib/
+CONTRIB.download/ = $(PROJECT/)download/
+CONTRIB.host = $(if $(filter 1,$(BUILD.cross)),$(BUILD.spec))
+
+###############################################################################
+
+##
+## $(1) = module name (uppercase)
+##
+define import.CONTRIB.defs
+ ##
+ ## import gcc/g++ support mainly so we can force contrib choice of
+ ## gcc executable, and debug/optimization flags.
+ ##
+ $$(eval $$(call import.GCC,$(1)))
+
+ ##
+ ## common values useful across targets
+ ##
+ $(1).src/ = $$(PROJECT/)contrib/$($(1).name)/
+ $(1).build/ = $$(CONTRIB.build/)$($(1).name)/
+ $(1).deps = $$(foreach n,$($(1).prerequisites),$$($$n.INSTALL.target))
+
+ ##
+ ## target: fetch
+ ##
+ $(1).FETCH.tar = $$(CONTRIB.download/)$$(notdir $$($(1).FETCH.url))
+ $(1).FETCH.url = FETCH_IS_UNDEFINED
+ $(1).FETCH.target = $$($(1).FETCH.tar)
+ define $(1).FETCH
+ $$(call FETCH,$$@,$$($(1).FETCH.url))
+ endef
+
+ ##
+ ## target: extract
+ ##
+ $(1).EXTRACT.tarbase = $$(patsubst %.tar.gz,%,$$(notdir $$($(1).FETCH.url)))
+ $(1).EXTRACT.target/ = $$($(1).build/)$$($(1).EXTRACT.tarbase)/
+ define $(1).EXTRACT
+ $$(TAR.exe) xfC $$($(1).FETCH.tar) $$($(1).build/)
+ endef
+
+ ##
+ ## target: patch
+ ##
+ $(1).PATCH.srcs = $$(wildcard \
+ $$($(1).src/)A??-*.patch \
+ $$($(1).src/)P??-$$(BUILD.system)*.patch )
+
+ # extra line feed is required
+ define $(1).PATCH.item
+ $$(PATCH.exe) -t -p1 -d $$(1) < $$(2)
+
+ endef
+
+ $(1).PATCH.target = $$($(1).build/).stamp.patch
+ define $(1).PATCH
+ $$(foreach p,$$($(1).PATCH.srcs),$$(call $(1).PATCH.item,$$($(1).EXTRACT.target/),$$(p)))
+ endef
+
+ ##
+ ## target: configure
+ ##
+ $(1).CONFIGURE.sete = set -e;
+ $(1).CONFIGURE.dir = $$($(1).EXTRACT.target/)
+ $(1).CONFIGURE.bootstrap =
+ $(1).CONFIGURE.exe = ./configure
+ $(1).CONFIGURE.host = $$(CONTRIB.host)
+ $(1).CONFIGURE.prefix = $$(call fn.ABSOLUTE,$$(CONTRIB.build/))
+ $(1).CONFIGURE.deps = --disable-dependency-tracking
+ $(1).CONFIGURE.shared = --disable-shared
+ $(1).CONFIGURE.static = --enable-static
+ $(1).CONFIGURE.extra =
+
+ $(1).CONFIGURE.args.dir = cd $$(1);
+ $(1).CONFIGURE.args.host = --host=$$(1)
+ $(1).CONFIGURE.args.prefix = --prefix=$$(1)
+
+ $(1).CONFIGURE.args = !sete @dir !bootstrap !env !exe @host @prefix !deps !shared !static !extra
+
+ $(1).CONFIGURE.env.CC = CC=$$($(1).GCC.gcc)
+ $(1).CONFIGURE.env.CFLAGS = CFLAGS="$$(call fn.ARGS,$(1).GCC,*archs)"
+ $(1).CONFIGURE.env.CXX = CXX=$$($(1).GCC.gxx)
+ $(1).CONFIGURE.env.CXXFLAGS = CXXFLAGS="$$(call fn.ARGS,$(1).GCC,*archs)"
+ $(1).CONFIGURE.env.CPPFLAGS = CPPFLAGS="$$(call fn.ARGS,$(1).GCC,*archs)"
+ $(1).CONFIGURE.env.LDFLAGS = LDFLAGS="$$(call fn.ARGS,$(1).GCC,*archs)"
+
+ $(1).CONFIGURE.env.args = !CC !CFLAGS !CXX !CXXFLAGS !CPPFLAGS !LDFLAGS
+ $(1).CONFIGURE.env = $$(call fn.ARGS,$(1).CONFIGURE.env,$$($(1).CONFIGURE.env.args))
+
+ $(1).CONFIGURE.target = $$($(1).build/).stamp.configure
+ define $(1).CONFIGURE
+ $$(call fn.ARGS,$(1).CONFIGURE,$$($(1).CONFIGURE.args))
+ endef
+
+ ##
+ ## target: build
+ ##
+ $(1).BUILD.make = $$(MAKE)
+ $(1).BUILD.dir = $$($(1).EXTRACT.target/)
+ $(1).BUILD.extra =
+ $(1).BUILD.ntargets =
+
+ $(1).BUILD.args = !make @dir !extra !ntargets
+ $(1).BUILD.args.dir = -C $$(1)
+
+ $(1).BUILD.target = $$($(1).build/).stamp.build
+ define $(1).BUILD
+ $$(call fn.ARGS,$(1).BUILD,$$($(1).BUILD.args))
+ endef
+
+ ##
+ ## target: install
+ ##
+
+ $(1).INSTALL.make = $$(MAKE)
+ $(1).INSTALL.dir = $$($(1).EXTRACT.target/)
+ $(1).INSTALL.extra =
+ $(1).INSTALL.ntargets =
+
+ $(1).INSTALL.args = !make @dir !extra !ntargets
+ $(1).INSTALL.args.dir = -C $$(1) install
+
+ $(1).INSTALL.target = $$($(1).build/).stamp.install
+ define $(1).INSTALL
+ $$(call fn.ARGS,$(1).INSTALL,$$($(1).INSTALL.args))
+ endef
+
+ ##
+ ## target: uninstall
+ ##
+ $(1).UNINSTALL.make = $$(MAKE)
+ $(1).UNINSTALL.dir = $$($(1).EXTRACT.target/)
+ $(1).UNINSTALL.extra =
+ $(1).UNINSTALL.ntargets = uninstall
+
+ $(1).UNINSTALL.args = !make @dir !extra !ntargets
+ $(1).UNINSTALL.args.dir = -C $$(1)
+
+ define $(1).UNINSTALL
+ $$(call fn.ARGS,$(1).UNINSTALL,$$($(1).UNINSTALL.args))
+ endef
+
+ ##
+ ## target: clean
+ ##
+ $(1).CLEAN.make = $$(MAKE)
+ $(1).CLEAN.dir = $$($(1).EXTRACT.target/)
+ $(1).CLEAN.extra =
+ $(1).CLEAN.ntargets = clean
+
+ $(1).CLEAN.args = !make @dir !extra !ntargets
+ $(1).CLEAN.args.dir = -C $$(1)
+
+ define $(1).CLEAN
+ $$(call fn.ARGS,$(1).CLEAN,$$($(1).CLEAN.args))
+ endef
+
+ ## other values used to aid prerequisite dirs and cleanup
+ ##
+ $(1).out += $$($(1).build/)
+ $(1).out += $$($(1).FETCH.target)
+ $(1).out += $$($(1).PATCH.target)
+ $(1).out += $$($(1).CONFIGURE.target)
+ $(1).out += $$($(1).ALL.target)
+ $(1).out += $$($(1).INSTALL.target)
+
+ BUILD.out += $$($(1).out)
+endef
+
+###############################################################################
+
+##
+## $(1) = module name
+##
+define import.CONTRIB.rules
+
+##
+## target: fetch
+##
+$($(1).name).fetch: $$($(1).FETCH.target)
+
+$$($(1).FETCH.target): | $$(dir $$($(1).FETCH.target))
+ $$($(1).FETCH)
+
+##
+## target: extract
+## must touch dir after extraction because old timestamp is restored via tar.
+##
+$($(1).name).extract: | $$($(1).EXTRACT.target/)
+
+$$($(1).EXTRACT.target/): | $$(dir $$($(1).build/))
+$$($(1).EXTRACT.target/): $$($(1).FETCH.target)
+ $$($(1).EXTRACT)
+ $$(TOUCH.exe) $$@
+
+##
+## target: patch
+##
+$($(1).name).patch: $$($(1).PATCH.target)
+
+$$($(1).PATCH.target): | $$(dir $$($(1).PATCH.target))
+$$($(1).PATCH.target): | $$($(1).EXTRACT.target/)
+ $$($(1).PATCH)
+ $$(TOUCH.exe) $$@
+
+##
+## target: configure
+##
+$($(1).name).configure: $$($(1).CONFIGURE.target)
+
+$$($(1).CONFIGURE.target): | $$(dir $$($(1).CONFIGURE.target))
+$$($(1).CONFIGURE.target): $$($(1).deps)
+$$($(1).CONFIGURE.target): $$($(1).PATCH.target)
+ $$($(1).CONFIGURE)
+ $$(TOUCH.exe) $$@
+
+##
+## target: build
+##
+$($(1).name).build: $$($(1).BUILD.target)
+
+$$($(1).BUILD.target): | $$(dir $$($(1).BUILD.target))
+$$($(1).BUILD.target): $$($(1).CONFIGURE.target)
+ +$$($(1).BUILD)
+ $$(TOUCH.exe) $$@
+
+##
+## target: install
+##
+$($(1).name).install: $$($(1).INSTALL.target)
+
+$$($(1).INSTALL.target): | $$(dir $$($(1).INSTALL.target))
+$$($(1).INSTALL.target): $$($(1).BUILD.target)
+ $$($(1).INSTALL)
+ $$(TOUCH.exe) $$@
+
+##
+## target: uninstall
+##
+$($(1).name).uninstall:
+ -$$($(1).UNINSTALL)
+ $$(RM.exe) -f $$($(1).INSTALL.target)
+
+##
+## target: clean
+##
+$($(1).name).clean:
+ -$$($(1).CLEAN)
+ $$(RM.exe) -f $$($(1).BUILD.target)
+
+##
+## target: xclean
+##
+$($(1).name).xclean: $($(1).name).uninstall
+ $$(RM.exe) -fr $$($(1).build/)
+
+##
+## alias: module name is same as build
+##
+$($(1).name): $($(1).name).build
+
+##
+## participate with global convenience targets
+##
+contrib.fetch: $($(1).name).fetch
+contrib.extract: $($(1).name).extract
+contrib.patch: $($(1).name).patch
+contrib.configure: $($(1).name).configure
+contrib.build: $($(1).name).build
+contrib.install: $($(1).name).install
+contrib.uninstall: $($(1).name).uninstall
+contrib.clean: $($(1).name).clean
+contrib.xclean: $($(1).name).xclean
+
+endef
diff --git a/make/include/function.defs b/make/include/function.defs
new file mode 100644
index 000000000..5bf5aaa89
--- /dev/null
+++ b/make/include/function.defs
@@ -0,0 +1,19 @@
+fn.ERROR1 = ERROR: $(1)
+fn.ERROR2 = ERROR: $(1): $(2)
+
+fn.HEADER = @echo "$(1): $(2)"
+fn.DIVIDER = @echo "======================================================================"
+
+fn.ABSOLUTE = $(if $(filter /%,$(1)),$(1),$(subst /./,/,$(CURDIR)/$(1)))
+
+fn.ARGS = $(strip $(foreach a,$(2), \
+ $($(1).$(patsubst !%,%,$(filter !%,$(a)))) \
+ $(foreach x,$(patsubst ?%,%,$(filter ?%,$(a))),$(if $(filter 1,$($(1).$(x))),$($(1).args.$(x)))) \
+ $(foreach x,$(patsubst .%,%,$(filter .%,$(a))),$($(1).args.$(x).$($(1).$(x)))) \
+ $(foreach x,$(patsubst @%,%,$(filter @%,$(a))),$(if $($(1).$(x)),$(call $(1).args.$(x),$($(1).$(x))))) \
+ $(foreach x,$(patsubst *%,%,$(filter *%,$(a))),$(foreach i,$($(1).$(x)),$(call $(1).args.$(x),$(i)))) \
+ ))
+
+fn.VARS = $(foreach v,$($(1).vars),$(v)="$($(1).vars.$(v))")
+
+fn.TARGET = $(TARGET.$(2).prefix)$(1)$(TARGET.$(2).suffix)$(TARGET.$(2).ext)
diff --git a/make/include/gcc.defs b/make/include/gcc.defs
new file mode 100644
index 000000000..4ed746392
--- /dev/null
+++ b/make/include/gcc.defs
@@ -0,0 +1,146 @@
+GCC.gcc = gcc
+GCC.gxx = $(dir $(GCC.gcc))$(subst gcc,g++,$(notdir $(GCC.gcc)))
+
+GCC.strip = $$(if $$(filter none,$$(GCC.g)),1)
+GCC.dylib = 1
+GCC.pipe = 1
+GCC.ML = 1
+GCC.H = 0
+GCC.W = all
+GCC.archs =
+GCC.vis = 0
+GCC.pic = 0
+GCC.g = none
+GCC.O = none
+GCC.D =
+GCC.I =
+GCC.muldefs = 0
+GCC.start = 0
+GCC.a =
+GCC.F =
+GCC.f =
+GCC.L =
+GCC.l =
+GCC.end = 0
+
+GCC.args.pipe = -pipe
+GCC.args.strip = -Wl,-S
+GCC.args.dylib = -dynamiclib
+GCC.args.ML = -fmessage-length=0
+GCC.args.H = -H
+GCC.args.W = -W$(1)
+GCC.args.archs = -arch $(1)
+GCC.args.vis = -fvisibility=hidden
+GCC.args.pic = -fPIC
+GCC.args.g.none = -g0
+GCC.args.g.min = -gdwarf-2 -g1
+GCC.args.g.std = -gdwarf-2
+GCC.args.g.max = -gdwarf-2 -g3
+GCC.args.O.none = -O0
+GCC.args.O.size = -Os
+GCC.args.O.speed = -O3
+GCC.args.D = -D$(1)
+GCC.args.I = -I$(1)
+GCC.args.muldefs = -Wl,--allow-multiple-definition
+GCC.args.start = -Wl,--start-group
+GCC.args.F = -F$(1)
+GCC.args.f = -framework $(1)
+GCC.args.L = -L$(1)
+GCC.args.l = -l$(1)
+GCC.args.end = -Wl,--end-group
+
+###############################################################################
+
+define import.GCC
+ $(1).GCC.gcc = $$(GCC.gcc)
+ $(1).GCC.gxx = $$(dir $$($(1).GCC.gcc))$$(subst gcc,g++,$$(notdir $$($(1).GCC.gcc)))
+
+ $(1).GCC.pipe = $$(GCC.pipe)
+ $(1).GCC.strip = $$(if $$(filter none,$$($(1).GCC.g)),1)
+ $(1).GCC.dylib = $$(GCC.dylib)
+ $(1).GCC.ML = $$(GCC.ML)
+ $(1).GCC.H = $$(GCC.H)
+ $(1).GCC.W = $$(GCC.W)
+ $(1).GCC.archs = $$(GCC.archs)
+ $(1).GCC.vis = $$(GCC.vis)
+ $(1).GCC.pic = $$(GCC.pic)
+ $(1).GCC.g = $$(GCC.g)
+ $(1).GCC.O = $$(GCC.O)
+ $(1).GCC.D = $$(GCC.D)
+ $(1).GCC.I = $$(GCC.I)
+ $(1).GCC.muldefs = $$(GCC.muldefs)
+ $(1).GCC.start = $$(GCC.start)
+ $(1).GCC.a = $$(GCC.a)
+ $(1).GCC.F = $$(GCC.F)
+ $(1).GCC.f = $$(GCC.f)
+ $(1).GCC.L = $$(GCC.L)
+ $(1).GCC.l = $$(GCC.l)
+ $(1).GCC.end = $$(GCC.end)
+
+ $(1).GCC.args.pipe = $$(GCC.args.pipe)
+ $(1).GCC.args.strip = $$(GCC.args.strip)
+ $(1).GCC.args.dylib = $$(GCC.args.dylib)
+ $(1).GCC.args.ML = $$(GCC.args.ML)
+ $(1).GCC.args.H = $$(GCC.args.H)
+ $(1).GCC.args.W = $$(GCC.args.W)
+ $(1).GCC.args.archs = $$(GCC.args.archs)
+ $(1).GCC.args.vis = $$(GCC.args.vis)
+ $(1).GCC.args.pic = $$(GCC.args.pic)
+ $(1).GCC.args.g.none = $$(GCC.args.g.none)
+ $(1).GCC.args.g.min = $$(GCC.args.g.min)
+ $(1).GCC.args.g.std = $$(GCC.args.g.std)
+ $(1).GCC.args.g.max = $$(GCC.args.g.max )
+ $(1).GCC.args.O.none = $$(GCC.args.O.none)
+ $(1).GCC.args.O.size = $$(GCC.args.O.size)
+ $(1).GCC.args.O.speed = $$(GCC.args.O.speed)
+ $(1).GCC.args.D = $$(GCC.args.D)
+ $(1).GCC.args.I = $$(GCC.args.I)
+ $(1).GCC.args.muldefs = $$(GCC.args.muldefs)
+ $(1).GCC.args.start = $$(GCC.args.start)
+ $(1).GCC.args.F = $$(GCC.args.F)
+ $(1).GCC.args.f = $$(GCC.args.f)
+ $(1).GCC.args.L = $$(GCC.args.L)
+ $(1).GCC.args.l = $$(GCC.args.l)
+ $(1).GCC.args.end = $$(GCC.args.end)
+
+ ###########################################################################
+
+ $(1).GCC.c = -c $$(4)
+ $(1).GCC.o = -o $$(3)
+
+ # FUNCTION: C precompiled headers
+ $(1).GCC.H_O.args = !gcc ?pipe ?ML ?H *W *archs ?vis ?pic .g .O *D *I !c !o
+ $(1).GCC.H_O = $$(call fn.ARGS,$(1).GCC,$$($(1).GCC.H_O.args),$$(1),$$(2))
+
+ # FUNCTION: C compile source
+ $(1).GCC.C_O.args = !gcc ?pipe ?ML ?H *W *archs ?vis ?pic .g .O *D *I !c !o
+ $(1).GCC.C_O = $$(call fn.ARGS,$(1).GCC,$$($(1).GCC.C_O.args),$$(1),$$(2))
+
+ # FUNCTION: C++ precompile headers
+ $(1).GCC.HPP_O.args = !gxx ?pipe ?ML ?H *W *archs ?vis ?pic .g .O *D *I !c !o
+ $(1).GCC.HPP_O = $$(call fn.ARGS,$(1).GCC,$$($(1).GCC.HPP_O.args),$$(1),$$(2))
+
+ # FUNCTION: C++ compile source
+ $(1).GCC.CPP_O.args = !gxx ?pipe ?ML ?H *W *archs ?vis ?pic .g .O *D *I !c !o
+ $(1).GCC.CPP_O = $$(call fn.ARGS,$(1).GCC,$$($(1).GCC.CPP_O.args),$$(1),$$(2))
+
+ ###########################################################################
+
+ $(1).GCC.i = $$(4)
+
+ # FUNCTION: C link dynamic-lib
+ $(1).GCC.DYLIB.args = !gcc ?pipe ?strip ?dylib ?ML *W *archs ?vis ?pic .g .O *D *I !o ?muldefs ?start !i *F *f *L *l *i !a ?end
+ $(1).GCC.DYLIB = $$(call fn.ARGS,$(1).GCC,$$($(1).GCC.DYLIB.args),$$(1),$$(2))
+
+ # FUNCTION: C link executable
+ $(1).GCC.EXE.args = !gcc ?pipe ?strip ?ML *W *archs ?vis ?pic .g .O *D *I !o ?muldefs ?start !i *F *f *L *l *i !a ?end
+ $(1).GCC.EXE = $$(call fn.ARGS,$(1).GCC,$$($(1).GCC.EXE.args),$$(1),$$(2))
+
+ # FUNCTION: C++ link dynamic-lib
+ $(1).GCC.DYLIB++.args = !gxx ?pipe ?strip ?dylib ?ML *W *archs ?vis ?pic .g .O *D *I !o ?muldefs ?start !i *F *f *L *l *i !a ?end
+ $(1).GCC.DYLIB++ = $$(call fn.ARGS,$(1).GCC,$$($(1).GCC.DYLIB++.args),$$(1),$$(2))
+
+ # FUNCTION: C++ link executable
+ $(1).GCC.EXE++.args = !gxx ?pipe ?strip ?ML *W *archs ?vis ?pic .g .O *D *I !o ?muldefs ?start !i *F *f *L *l *i !a ?end
+ $(1).GCC.EXE++ = $$(call fn.ARGS,$(1).GCC,$$($(1).GCC.EXE++.args),$$(1),$$(2))
+endef
diff --git a/make/include/main.defs b/make/include/main.defs
new file mode 100644
index 000000000..c40e2b62a
--- /dev/null
+++ b/make/include/main.defs
@@ -0,0 +1,75 @@
+.DELETE_ON_ERROR:
+.SUFFIXES:
+
+.PHONY: build
+build:
+
+###############################################################################
+
+include $(PROJECT/)make/include/base.defs
+include $(PROJECT/)make/include/contrib.defs
+include $(PROJECT/)make/include/function.defs
+include $(PROJECT/)make/include/gcc.defs
+include $(PROJECT/)make/include/select.defs
+include $(PROJECT/)make/include/target.defs
+include $(PROJECT/)make/include/tool.defs
+
+###############################################################################
+
+MODULES += contrib/a52dec
+
+ifneq (,$(filter $(BUILD.system),cygwin))
+ MODULES += contrib/bzip2
+endif
+
+MODULES += contrib/faac
+MODULES += contrib/faad2
+MODULES += contrib/ffmpeg
+MODULES += contrib/lame
+MODULES += contrib/libdca
+MODULES += contrib/libdvdread
+MODULES += contrib/libmkv
+MODULES += contrib/libmp4v2
+MODULES += contrib/libogg
+MODULES += contrib/libsamplerate
+MODULES += contrib/libtheora
+MODULES += contrib/libvorbis
+MODULES += contrib/mpeg2dec
+MODULES += contrib/x264
+MODULES += contrib/xvidcore
+
+ifneq (,$(filter $(BUILD.system),cygwin))
+ MODULES += contrib/zlib
+endif
+
+## these must come after contrib since some contrib modules are optional
+MODULES += libhb
+
+###############################################################################
+
+## test module is replaced with macosx when Darwin+Xcode
+ifneq (,$(filter $(BUILD.system),darwin))
+ ifeq (1,$(FEATURE.xcode))
+ MODULES += macosx
+ else
+ MODULES += test
+ endif
+else
+ MODULES += test
+endif
+
+ifneq (,$(filter $(BUILD.system),linux))
+ ifeq (1,$(FEATURE.gtk))
+ MODULES += gtk
+ endif
+endif
+
+###############################################################################
+
+MODULES += doc
+
+###############################################################################
+
+include $(MODULES:%=$(PROJECT/)%/module.defs)
+include $(PROJECT/)make/variant/$(HOST.system).defs
+-include $(PROJECT/)make/variant/$(HOST.system).$(BUILD.proc).defs
diff --git a/make/include/main.rules b/make/include/main.rules
new file mode 100644
index 000000000..f46d22398
--- /dev/null
+++ b/make/include/main.rules
@@ -0,0 +1,39 @@
+## only included using special report targets
+ifneq (,$(REPORT))
+ include $(PROJECT/)make/include/report.defs
+endif
+
+###############################################################################
+
+.PHONY: clean xclean doc report
+
+clean:
+xclean: contrib.xclean clean
+doc:
+report:: report.main report.modules
+
+## legacy
+mrproper: xclean
+
+###############################################################################
+
+include $(MODULES:%=$(PROJECT/)%/module.rules)
+include $(PROJECT/)make/variant/$(HOST.system).rules
+-include $(PROJECT/)make/variant/$(HOST.system).$(BUILD.proc).rules
+
+###############################################################################
+
+## target which causes re-configure if project-root is svn update'd
+$(BUILD/)GNUmakefile: $(wildcard $(PROJECT/).svn/entries)
+ $(PROJECT/)configure $(CONF.args)
+
+## target useful to force reconfigure; only helpful for build-system development
+.PHONY: reconfigure
+reconfigure:
+ $(PROJECT/)configure $(CONF.args)
+
+###############################################################################
+
+## target to build all dependency dirs
+$(sort $(dir $(BUILD.out))):
+ $(MKDIR.exe) -p $@
diff --git a/make/include/report.defs b/make/include/report.defs
new file mode 100644
index 000000000..6ff71dc99
--- /dev/null
+++ b/make/include/report.defs
@@ -0,0 +1,53 @@
+## function: print a var's name, definition and expanded value
+##
+## $(1) = name of variable
+##
+define fn.PRINTVAR
+
+$(1)
+ ORIGIN = $(origin $(1))
+ FLAVOR = $(flavor $(1))
+ DEFINITION = $(value $(1))
+ EXPANDED = $($(1))
+endef
+
+## report: module
+##
+## REPORT.module = module name (uppercase)
+##
+ifeq (module,$(REPORT))
+$(info ###############################################################################)
+$(info ##)
+$(info ## MODULE: $(REPORT.module))
+$(info ##)
+$(info ###############################################################################)
+$(info $(foreach v,$(sort $(filter $(REPORT.module).%,$(.VARIABLES))),$(call fn.PRINTVAR,$v)))
+$(info )
+endif
+
+## report: main
+##
+ifeq (main,$(REPORT))
+$(info ###############################################################################)
+$(info ##)
+$(info ## MAIN)
+$(info ##)
+$(info ###############################################################################)
+$(info $(foreach v,$(sort $(filter HB.%,$(.VARIABLES))),$(call fn.PRINTVAR,$v)))
+$(info $(foreach v,$(sort $(filter HOST.%,$(.VARIABLES))),$(call fn.PRINTVAR,$v)))
+$(info $(foreach v,$(sort $(filter BUILD.%,$(.VARIABLES))),$(call fn.PRINTVAR,$v)))
+$(info $(foreach v,$(sort $(filter CONTRIB.%,$(.VARIABLES))),$(call fn.PRINTVAR,$v)))
+$(info )
+endif
+
+## report: gcc
+##
+ifeq (gcc,$(REPORT))
+$(info ###############################################################################)
+$(info ##)
+$(info ## GCC)
+$(info ##)
+$(info ###############################################################################)
+$(info $(foreach v,$(sort $(filter GCC.%,$(.VARIABLES))),$(call fn.PRINTVAR,$v)))
+$(info )
+endif
diff --git a/make/include/select.defs b/make/include/select.defs
new file mode 100644
index 000000000..32a652523
--- /dev/null
+++ b/make/include/select.defs
@@ -0,0 +1,12 @@
+##
+## fetch a file from the web via well-known anonymous protocols such as HTTP.
+##
+## $(1) = output filename
+## $(2) = URL
+##
+FETCH = $(FETCH.$(FETCH.select))
+
+FETCH.select = MISSING
+FETCH.MISSING = $(error one of the following tools is required: wget, curl)
+FETCH.curl = $(CURL.exe) -q -L -o $(1) $(2)
+FETCH.wget = $(WGET.exe) -O $(1) $(2)
diff --git a/make/include/target.defs b/make/include/target.defs
new file mode 100644
index 000000000..64bdde434
--- /dev/null
+++ b/make/include/target.defs
@@ -0,0 +1,14 @@
+TARGET.dylib.prefix = lib
+TARGET.dylib.suffix =
+TARGET.dylib.ext = .dylib
+TARGET.dylib = $(TARGET.dylib.prefix)$(1)$(TARGET.dylib.suffix)$(TARGET.dylib.ext)
+
+TARGET.archive.prefix = lib
+TARGET.archive.suffix =
+TARGET.archive.ext = .a
+TARGET.archive = $(TARGET.archive.prefix)$(1)$(TARGET.archive.suffix)$(TARGET.archive.ext)
+
+TARGET.exe.prefix =
+TARGET.exe.suffix =
+TARGET.exe.ext =
+TARGET.exe = $(TARGET.exe.prefix)$(1)$(TARGET.exe.suffix)$(TARGET.exe.ext)
diff --git a/make/include/tool.defs b/make/include/tool.defs
new file mode 100644
index 000000000..0ccccd728
--- /dev/null
+++ b/make/include/tool.defs
@@ -0,0 +1,10 @@
+AR.exe = ar
+CP.exe = cp
+CURL.exe = curl
+M4.exe = m4
+MKDIR.exe = mkdir
+PATCH.exe = patch
+RM.exe = rm
+TAR.exe = tar
+TOUCH.exe = touch
+WGET.exe = wget