diff options
Diffstat (limited to 'build/TFbuild.main')
-rw-r--r-- | build/TFbuild.main | 233 |
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 |