From 794a56f1f6d986b04651b4ab7aa04f6e2fbb9972 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 27 Mar 2011 13:39:08 +0200 Subject: Add on-the-fly thunk makefile generation support for out_root != src_root --- build/bootstrap.make | 47 +++++++++++++++++++++++---- build/generator | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 build/generator 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 +# 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 -- cgit v1.1