aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-03-27 13:39:08 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-03-27 13:39:08 +0200
commit794a56f1f6d986b04651b4ab7aa04f6e2fbb9972 (patch)
tree0b0ee748d03da09dbb196e2b31722a26952f7aac
parentf12616d9bbf7bdd7868e583298ef4120921db5dc (diff)
Add on-the-fly thunk makefile generation support for out_root != src_root
-rw-r--r--build/bootstrap.make47
-rw-r--r--build/generator91
2 files changed, 131 insertions, 7 deletions
diff --git a/build/bootstrap.make b/build/bootstrap.make
index c9d1e97..f40850f 100644
--- a/build/bootstrap.make
+++ b/build/bootstrap.make
@@ -61,7 +61,12 @@ export MAKE
# also it will be consistent.
#
-%makefile% := $(abspath $(firstword $(MAKEFILE_LIST)))
+# By convention, the makefile name is the third last word from the end.
+#
+%makefile% := $(subst $(lastword $(MAKEFILE_LIST)),,$(MAKEFILE_LIST))
+%makefile% := $(subst $(lastword $(%makefile%)),,$(%makefile%))
+%makefile% := $(abspath $(lastword $(%makefile%)))
+
%makefile_realpath% := $(realpath $(%makefile%))
@@ -327,17 +332,45 @@ ifneq ($(bld_root),$(scf_root))
$(call -include,$(scf_root)/configuration-static.make)
endif
-
# `disfigure' target.
#
.PHONY: disfigure
-.PHONY: $(dcf_root)/.disfigure
+.PHONY: $(dcf_root)/.disfigure $(out_root)/.disfigure
-disfigure:: $(build_absolute_clean_target) $(dcf_root)/.disfigure
+disfigure:: $(build_absolute_clean_target)
+disfigure:: $(dcf_root)/.disfigure
+disfigure:: $(out_root)/.disfigure
-ifeq ($(.DEFAULT_GOAL),disfigure)
-.DEFAULT_GOAL :=
+ifneq ($(out_root),$(out_base))
+.PHONY: $(out_base)/.disfigure
+$(out_root)/.disfigure:: $(out_base)/.disfigure
+endif
+
+# Clean up generated makefiles.
+#
+ifndef %foreign%
+ifneq ($(out_root),$(src_root))
+$(out_base)/.disfigure::
+ $(call message, rm $$1,rm -f $$1,$(out_base)/makefile)
+endif
endif
-# Dynamic configuration.
+# Dynamic configuration (interactive check is to make sure we only do
+# this once).
#
+ifdef %interactive%
+ifneq ($(out_root),$(src_root))
+
+$(call -include,$(dcf_root)/bootstrap-dynamic.make)
+
+$(dcf_root)/bootstrap-dynamic.make: | $(dcf_root)/.
+ $(call message,,echo "src_root := $(src_root)" >$@)
+
+$(dcf_root)/.disfigure::
+ $(call message, rm $$1,rm -f $$1,$(dcf_root)/bootstrap-dynamic.make)
+endif
+endif
+
+ifeq ($(.DEFAULT_GOAL),disfigure)
+.DEFAULT_GOAL :=
+endif
diff --git a/build/generator b/build/generator
new file mode 100644
index 0000000..ed235d8
--- /dev/null
+++ b/build/generator
@@ -0,0 +1,91 @@
+# file : build/generator
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2004-2011 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# This makefile is an optional, transparent generator of "thunk" makefiles
+# for the build setups with separate src and out directories. Without the
+# generator, the make invocation for this setup has the following general
+# form:
+#
+# make -C out_root/subdir -f src_root/subdir/makefile
+#
+# With the generator enabled, the same can be achieved with the following
+# shorter command:
+#
+# make -C out_root/subdir
+#
+# Or, if the subdir directory may not yet exist, with this variant:
+#
+# make -C out_root dir=subdir
+#
+# To enable the generator, you will need to instruct make to pre-load it
+# for every invocation by adding it to the MAKEFILES environment variable:
+#
+# export MAKEFILES=build-X.Y/generator
+#
+# The thunk makefiles for individual sub-directories are generated as
+# needed and are automatically removed by the disfigure target.
+#
+
+ifdef dir
+
+.PHONY: _all
+_all:
+ @mkdir -p $(dir)
+ @$(MAKE) -C $(dir) dir= $(MAKECMDGOALS)
+
+ifneq ($(MAKECMDGOALS),)
+.PHONY: $(MAKECMDGOALS)
+$(MAKECMDGOALS): _all
+else
+.DEFAULT_GOAL := _all
+endif
+
+else
+ifeq ($(wildcard makefile Makefile GNUmakefile),)
+
+define literal_newline
+
+
+endef
+
+makefile: empty :=
+makefile: space := $(empty) #
+makefile: tab := $(empty) $(empty)
+makefile: newline := $(literal_newline)
+
+
+# Find the src_root directory.
+#
+# $1 - current directory
+#
+makefile: find = \
+$(if $1,$(if $(wildcard $1/build/bootstrap-dynamic.make),$1,$(call \
+find,$(patsubst %/,%,$(dir $1)))))
+
+# Convert /foo/bar to ../../.
+#
+# $1 - relative path from $(CURDIR)
+#
+makefile: path = $(subst $(space),,$(foreach d,$(subst /, ,$1/),../))
+
+# $1 - relative path from $(CURDIR)
+#
+makefile: command_body = \
+@echo '\# Automatically generated by build.' >$@$(newline)\
+$(tab)@echo 'ifndef dir' >>$@$(newline)\
+$(tab)@echo 'override dir :=' >>$@$(newline)\
+$(tab)@echo 'include $(if $1,$(call path,$1))build/bootstrap-dynamic.make' >>$@$(newline)\
+$(tab)@echo 'include $$(src_root)$1/makefile' >>$@$(newline)\
+$(tab)@echo 'endif' >>$@
+
+# $1 - output root directory or empty if none were found
+#
+makefile: command = $(if $1,$(call command_body,$(subst $1,,$(CURDIR))))
+
+makefile:
+ $(call command,$(call find,$(CURDIR)))
+
+endif # makefile
+endif # dir