summaryrefslogtreecommitdiffstats
path: root/build
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-11-19 14:32:11 +0200
committerTimo Teras <timo.teras@iki.fi>2009-11-24 08:12:45 +0200
commite4e54c2ec744e884f6f55c135bea78e815d28d6c (patch)
tree3278c0bdb3eedc47eaf71ef53b9ff849cb136593 /build
downloadlibtf-e4e54c2ec744e884f6f55c135bea78e815d28d6c.tar.bz2
libtf-e4e54c2ec744e884f6f55c135bea78e815d28d6c.tar.xz
libtf: initial commit
libtf is to be user-space cooperative threading library similar to State Threads (http://state-threads.sourceforge.net/), but with additional support for multiple cores, using better algorithms and taking advantage of new Linux kernel syscalls such as eventfd, signalfd and epoll (edge-triggered mode). Initial implementation has setjmp based user-space context switching and trivial testcase. Works on Linux/x86. TFbuild uses ideas from different build systems, namely Kbuild, but it's inner workings are quite different. All build files are included (using macro trickery) instead of recursive making. Thus the build dependency graph is complete and should yield good make performance. Also parallel stuff should work.
Diffstat (limited to 'build')
-rw-r--r--build/TFbuild.epilogue20
-rw-r--r--build/TFbuild.main233
-rw-r--r--build/TFbuild.prologue18
3 files changed, 271 insertions, 0 deletions
diff --git a/build/TFbuild.epilogue b/build/TFbuild.epilogue
new file mode 100644
index 0000000..af0baad
--- /dev/null
+++ b/build/TFbuild.epilogue
@@ -0,0 +1,20 @@
+# Store per-directory variables
+#$(call MemoizeVariables, CFLAGS LDFLAGS LIBS)
+
+file-vars := $(filter $(foreach m,$(local-vars),$(m)_%),$(.VARIABLES))
+file-vars := $(filter-out $(foreach m,$(local-vars),$(m)_ALL),$(file-vars))
+$(foreach m,$(file-vars),$(eval $(call MemoizeVariable,$(m))))
+
+# Handle this directory's rules
+$(foreach m,$(libs-y),$(eval $(call CreateLibrary,$(m))))
+$(foreach m,$(progs-y),$(eval $(call CreateProgram,$(m))))
+
+# Handle subdir of this subdir
+subdirs--$(recursion-level) := $(addsuffix /,$(subdirs-y))
+include $(subdirs-y:%=$(build-prologue) $(current-dir)%/TFbuild $(build-epilogue))
+
+# And restore parent context
+$(foreach m,$(local-vars),$(eval $(call MemoizeAndPopVariable,$(m))))
+
+current-dir := $(parent-dir--$(recursion-level))
+current-dirc := $(parent-dirc--$(recursion-level))
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
diff --git a/build/TFbuild.prologue b/build/TFbuild.prologue
new file mode 100644
index 0000000..2878ca0
--- /dev/null
+++ b/build/TFbuild.prologue
@@ -0,0 +1,18 @@
+# Reset all per-directory variables
+subdirs-y :=
+libs-y :=
+progs-y :=
+
+# Remove this directory as being handled
+current-subdir := $(firstword $(subdirs--$(recursion-level)))
+subdirs--$(recursion-level) := $(filter-out $(current-subdir),$(subdirs--$(recursion-level)))
+
+# Traverse down to selected subdir
+parent-dir--$(next-recursion-level) := $(current-dir)
+parent-dirc--$(next-recursion-level) := $(current-dirc)
+current-dir := $(current-dir)$(current-subdir)
+current-dirc += $(current-subdir)
+
+$(foreach m,$(local-vars),$(eval $(call PushVariable,$(m))))
+
+#$(warning Enter $(current-dir))