summaryrefslogtreecommitdiffstats
path: root/build/TFbuild.main
diff options
context:
space:
mode:
Diffstat (limited to 'build/TFbuild.main')
-rw-r--r--build/TFbuild.main233
1 files changed, 233 insertions, 0 deletions
diff --git a/build/TFbuild.main b/build/TFbuild.main
new file mode 100644
index 0000000..23ca461
--- /dev/null
+++ b/build/TFbuild.main
@@ -0,0 +1,233 @@
+# call once recursively so we get rid of default rules and variables
+ifndef RECURSIVE
+
+all:
+
+Makefile: ;
+
+%:
+ @$(MAKE) -rR --no-print-directory RECURSIVE=1 $(MAKECMDGOALS)
+
+else
+
+# default target
+all: libs progs
+ @:
+
+.SECONDEXPANSION:
+
+# default directories
+DESTDIR ?=
+SBINDIR ?= /usr/sbin
+CONFDIR ?= /etc/$(PACKAGE)
+MANDIR ?= /usr/share/man
+DOCDIR ?= /usr/share/doc/$(PACKAGE)
+STATEDIR ?= /var/run
+
+# utilities and default flags for them.
+CROSS_COMPILE ?=
+CC := $(CROSS_COMPILE)gcc
+AR := $(CROSS_COMPILE)ar
+RANLIB := $(CROSS_COMPILE)ranlib
+LD := $(CROSS_COMPILE)ld
+INSTALL := install
+INSTALLDIR := $(INSTALL) -d
+
+CFLAGS := -Wall -Wstrict-prototypes -D_GNU_SOURCE -std=gnu99
+CFLAGS_ALL ?= -g -O2
+LDFLAGS := $(LDFLAGS)
+LDFLAGS_ALL ?= -g
+
+# some helpers
+PHONY:=all libs progs allobjdirs arguments-changed
+build-prologue:=$(TFBUILD)TFbuild.prologue
+build-epilogue:=$(TFBUILD)TFbuild.epilogue
+comma:=,
+squote:='
+empty:=
+space:=$(empty) $(empty)
+separator:=--
+
+ifdef V
+ ifeq ("$(origin V)", "command line")
+ VERBOSE = $(V)
+ endif
+endif
+ifndef VERBOSE
+ VERBOSE = 0
+endif
+ifeq ($(VERBOSE),1)
+ quiet =
+ Q =
+else
+ quiet=quiet_
+ Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+ quiet=silent_
+endif
+
+# recursion related stuff
+srctree :=
+objtree := obj/
+current-dir :=
+current-dirc :=
+recursion-level = $(words $(current-dirc))
+next-recursion-level = $(words $(current-dirc) dummy)
+objdir = $(objtree)$(current-dir)
+
+# globals
+all-progs :=
+all-libs :=
+local-vars := CFLAGS LDFLAGS LIBS
+
+# helper macros for targets
+escsq = $(subst $(squote),'\$(squote)',$1)
+printable-target = $(patsubst $(objtree)%,%,$@)
+depfile = $(subst $(comma),_,$(@).d)
+#arg-check-prereq = $(if $(arg-check),arguments-changed \
+ #$(warning arg-check $(arg-check))\
+ #$(warning old $@ - $(cmd_$(@)))\
+ #$(warning new $1 - $(cmd_$(1)))\
+ #)
+arg-check-prereq = $(if $(arg-check),arguments-changed)
+arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$(@))) \
+ $(filter-out $(cmd_$(@)), $(cmd_$(1))) )
+echo-cmd = $(if $($(quiet)cmd_$(1)),\
+ echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
+make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1)))))
+cmd = @$(echo-cmd) $(cmd_$(1))
+primary_source = $(firstword $^)
+
+#target-objects2=$(addprefix $(objdir),$(if $(filter-out $(origin $(1)-objs-y),undefined),$($(1)-objs-y),$(1).o))
+#target-objects=$(warning target-objects $(1)=$(target-objects2))$(target-objects2)
+target-objects=$(addprefix $(objdir),$(if $(filter-out $(origin $(1)-objs-y),undefined),$($(1)-objs-y),$(1).o))
+
+# why - tell all prerequisites that have changed
+ifeq ($(VERBOSE),2)
+why = - due to $(filter-out $(PHONY),$?) $(filter $(PHONY),$^)
+echo-why = $(call escsq, $(strip $(why)))
+endif
+
+# rules for targets
+define CreateDirectory
+ifeq ($(filter createdir-$(1),$(PHONY)),)
+PHONY+=createdir-$(1)
+ifneq ($(shell [ -d $(1) ] && echo yes), yes)
+createdir-$(1):
+ $(Q)mkdir -p $(1)
+allobjdirs: createdir-$(1)
+endif
+endif
+endef
+
+define CallRule
+ @set -e; \
+ $(rule_$(1))
+endef
+
+define ExecuteCommand
+ @set -e; \
+ $(echo-cmd) $(cmd_$(1)); \
+ echo 'cmd_$@ := $(make-cmd)' > $(@).cmd
+endef
+
+define MemoizeVariable
+ifneq ($($(1)),)
+$(current-dir)--$(1):=$($(1))
+$(1):=
+endif
+endef
+
+define PushVariable
+inherit-$(1)-$(recursion-level):=$($(1))
+endef
+
+define PopVariable
+$(current-dir)--$(1):=$($(1))
+$(1):=$(inherit-$(1)-$(recursion-level))
+endef
+
+define MemoizeAndPopVariable
+$(current-dir)--$(1):=$($(1))
+$(1):=$(inherit-$(1)-$(recursion-level))
+endef
+
+# GCC C-compiler
+c_flags = -Wp,-MD,$(depfile),-MT,$@ $(CFLAGS_ALL) \
+ $($(dir $(printable-target))--CFLAGS) \
+ $($(dir $(printable-target))--CFLAGS_$(notdir $(primary_source)))
+
+quiet_cmd_cc_o_c = CC $(printable-target)
+ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $(primary_source)
+
+define rule_cc_o_c
+ $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
+ (echo 'cmd_$@ := $(call make-cmd,cc_o_c)'; echo; cat $(depfile)) \
+ > $@.cmd ; \
+ rm $(depfile)
+endef
+
+$(objtree)%.o: $(srctree)%.c $$(call arg-check-prereq,cc_o_c) |allobjdirs
+ $(call CallRule,cc_o_c)
+
+# AR static library archiver
+quiet_cmd_ar = AR $(printable-target)
+ cmd_ar = $(AR) -r $@ $? 2> /dev/null && \
+ $(RANLIB) $@
+
+define CreateLibrary
+all-libs += $(objdir)$(1).a
+
+$(objdir)$(1).a: $(target-objects) $(LIBS) | createdir-$(objdir)
+
+-include $(addsuffix .cmd,$(target-objects))
+
+$(call CreateDirectory,$(objdir))
+endef
+
+# Linker
+ld_flags = $(LDFLAGS_ALL) \
+ $($(dir $(printable-target))--LDFLAGS) \
+ $($(dir $(printable-target))--LDFLAGS_$(notdir $(primary_source)))
+
+quiet_cmd_ld = LD $(printable-target)
+ cmd_ld = $(CC) $(ld_flags) -o $@ $(filter-out $(PHONY),$^) $($(@D)--LIBS) $($@--LIBS)
+
+define CreateProgram
+all-progs += $(objdir)$(1)
+
+$(objdir)$(1): $(target-objects) $(LIBS) | createdir-$(objdir)
+
+-include $(addsuffix .cmd,$(objdir)$(1) $(target-objects))
+
+$(call CreateDirectory,$(objdir))
+endef
+
+# version string
+GIT_REV := $(shell test -d .git && git describe 2> /dev/null || echo exported)
+ifneq ($(GIT_REV), exported)
+FULL_VERSION := $(patsubst v%,%,$(GIT_REV))
+else
+FULL_VERSION := $(VERSION)
+endif
+
+# include the main directory's TFbuild
+include $(build-prologue) TFbuild $(build-epilogue)
+
+# debug dump all variables
+#$(foreach VAR,$(sort $(.VARIABLES)),$(warning $(VAR)=$($(VAR))))
+
+progs: $(all-progs)
+libs: $(all-libs)
+
+$(all-libs): %:
+ $(call ExecuteCommand,ar)
+
+$(all-progs): %: $$(call arg-check-prereq,ld)
+ $(call ExecuteCommand,ld)
+
+.PHONY: $(PHONY)
+$(PHONY):
+
+endif