Message ID | 20200226113355.2532224-14-anthony.perard@citrix.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | xen: Build system improvements | expand |
On 26.02.2020 12:33, Anthony PERARD wrote: > --- a/xen/Makefile > +++ b/xen/Makefile > @@ -49,7 +49,71 @@ default: build > .PHONY: dist > dist: install > > -build install:: include/config/auto.conf > + > +ifeq ($(root-make-done),) This getting communicated between make recursion instances via ... > +# section to run before calling Rules.mk, but only once. > +# > +# To make sure we do not include .config for any of the *config targets > +# catch them early, and hand them over to tools/kconfig/Makefile > + > +clean-targets := %clean > +no-dot-config-targets := $(clean-targets) \ > + uninstall debug cloc \ > + cscope TAGS tags MAP gtags \ > + xenversion > + > +config-build := n > +need-config := y > + > +ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) > + ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) > + need-config := n > + endif > +endif > + > +ifneq ($(filter %config,$(MAKECMDGOALS)),) > + config-build := y > +endif > + > +export root-make-done := y ... the environment, can we be as resilient as possible against a variable of this name already existing in the environment before the top level make invocation, by making the construct above ifneq ($(root-make-done),y) ? > +endif # root-make-done > + > +ifeq ($(config-build),y) > +# =========================================================================== > +# *config targets only - make sure prerequisites are updated, and descend > +# in tools/kconfig to make the *config target > + > +config: FORCE > + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" $@ This, ... > + > +# Config.mk tries to include .config file, don't try to remake it > +%/.config: ; > + > +%config: FORCE > + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" $@ ... this, ... > +else # !config-build > + > +ifeq ($(need-config),y) > +include include/config/auto.conf > +# Read in dependencies to all Kconfig* files, make sure to run syncconfig if > +# changes are detected. > +include include/config/auto.conf.cmd > + > +# Allow people to just run `make` as before and not force them to configure > +$(KCONFIG_CONFIG): > + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" defconfig ... this, and ... > +# The actual configuration files used during the build are stored in > +# include/generated/ and include/config/. Update them if .config is newer than > +# include/config/auto.conf (which mirrors .config). > +# > +# This exploits the 'multi-target pattern rule' trick. > +# The syncconfig should be executed only once to make all the targets. > +include/config/%.conf include/config/%.conf.cmd: $(KCONFIG_CONFIG) > + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" syncconfig ... this are almost identical, pretty long lines. Can this be macroized, please, with the actual make goal as parameter? Jan
On Wed, Mar 04, 2020 at 03:29:55PM +0100, Jan Beulich wrote: > On 26.02.2020 12:33, Anthony PERARD wrote: > > --- a/xen/Makefile > > +++ b/xen/Makefile > > @@ -49,7 +49,71 @@ default: build > > .PHONY: dist > > dist: install > > > > -build install:: include/config/auto.conf > > + > > +ifeq ($(root-make-done),) > > This getting communicated between make recursion instances via ... > > > +# section to run before calling Rules.mk, but only once. > > +# > > +# To make sure we do not include .config for any of the *config targets > > +# catch them early, and hand them over to tools/kconfig/Makefile > > + > > +clean-targets := %clean > > +no-dot-config-targets := $(clean-targets) \ > > + uninstall debug cloc \ > > + cscope TAGS tags MAP gtags \ > > + xenversion > > + > > +config-build := n > > +need-config := y > > + > > +ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) > > + ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) > > + need-config := n > > + endif > > +endif > > + > > +ifneq ($(filter %config,$(MAKECMDGOALS)),) > > + config-build := y > > +endif > > + > > +export root-make-done := y > > ... the environment, can we be as resilient as possible against a > variable of this name already existing in the environment before > the top level make invocation, by making the construct above > > ifneq ($(root-make-done),y) > > ? Sound good, I'll do that. > > +endif # root-make-done > > + > > +ifeq ($(config-build),y) > > +# =========================================================================== > > +# *config targets only - make sure prerequisites are updated, and descend > > +# in tools/kconfig to make the *config target > > + > > +config: FORCE > > + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" $@ > > This, ... > > > + > > +# Config.mk tries to include .config file, don't try to remake it > > +%/.config: ; > > + > > +%config: FORCE > > + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" $@ > > ... this, ... > > > +else # !config-build > > + > > +ifeq ($(need-config),y) > > +include include/config/auto.conf > > +# Read in dependencies to all Kconfig* files, make sure to run syncconfig if > > +# changes are detected. > > +include include/config/auto.conf.cmd > > + > > +# Allow people to just run `make` as before and not force them to configure > > +$(KCONFIG_CONFIG): > > + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" defconfig > > ... this, and ... > > > +# The actual configuration files used during the build are stored in > > +# include/generated/ and include/config/. Update them if .config is newer than > > +# include/config/auto.conf (which mirrors .config). > > +# > > +# This exploits the 'multi-target pattern rule' trick. > > +# The syncconfig should be executed only once to make all the targets. > > +include/config/%.conf include/config/%.conf.cmd: $(KCONFIG_CONFIG) > > + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" syncconfig > > ... this are almost identical, pretty long lines. Can this be macroized, > please, with the actual make goal as parameter? Sound good, would the following be fine? kconfig = -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" config: $(MAKE) $(kconfig) $@ I will put that new `kconfig' macro in Kbuild.include, along the shorthand for clean. Thanks,
On 10.03.2020 18:10, Anthony PERARD wrote: > On Wed, Mar 04, 2020 at 03:29:55PM +0100, Jan Beulich wrote: >> On 26.02.2020 12:33, Anthony PERARD wrote: >>> +# The actual configuration files used during the build are stored in >>> +# include/generated/ and include/config/. Update them if .config is newer than >>> +# include/config/auto.conf (which mirrors .config). >>> +# >>> +# This exploits the 'multi-target pattern rule' trick. >>> +# The syncconfig should be executed only once to make all the targets. >>> +include/config/%.conf include/config/%.conf.cmd: $(KCONFIG_CONFIG) >>> + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" syncconfig >> >> ... this are almost identical, pretty long lines. Can this be macroized, >> please, with the actual make goal as parameter? > > Sound good, would the following be fine? > > kconfig = -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" > config: > $(MAKE) $(kconfig) $@ > > I will put that new `kconfig' macro in Kbuild.include, along the > shorthand for clean. Looks okay at the first glance. Jan
diff --git a/xen/Makefile b/xen/Makefile index 8267ace51b0d..a6120e577e9b 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -49,7 +49,71 @@ default: build .PHONY: dist dist: install -build install:: include/config/auto.conf + +ifeq ($(root-make-done),) +# section to run before calling Rules.mk, but only once. +# +# To make sure we do not include .config for any of the *config targets +# catch them early, and hand them over to tools/kconfig/Makefile + +clean-targets := %clean +no-dot-config-targets := $(clean-targets) \ + uninstall debug cloc \ + cscope TAGS tags MAP gtags \ + xenversion + +config-build := n +need-config := y + +ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) + ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) + need-config := n + endif +endif + +ifneq ($(filter %config,$(MAKECMDGOALS)),) + config-build := y +endif + +export root-make-done := y +endif # root-make-done + +ifeq ($(config-build),y) +# =========================================================================== +# *config targets only - make sure prerequisites are updated, and descend +# in tools/kconfig to make the *config target + +config: FORCE + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" $@ + +# Config.mk tries to include .config file, don't try to remake it +%/.config: ; + +%config: FORCE + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" $@ + +else # !config-build + +ifeq ($(need-config),y) +include include/config/auto.conf +# Read in dependencies to all Kconfig* files, make sure to run syncconfig if +# changes are detected. +include include/config/auto.conf.cmd + +# Allow people to just run `make` as before and not force them to configure +$(KCONFIG_CONFIG): + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" defconfig + +# The actual configuration files used during the build are stored in +# include/generated/ and include/config/. Update them if .config is newer than +# include/config/auto.conf (which mirrors .config). +# +# This exploits the 'multi-target pattern rule' trick. +# The syncconfig should be executed only once to make all the targets. +include/config/%.conf include/config/%.conf.cmd: $(KCONFIG_CONFIG) + $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" syncconfig + +endif # need-config .PHONY: build install uninstall clean distclean MAP build install uninstall debug clean distclean MAP:: @@ -254,9 +318,6 @@ cscope: _MAP: $(NM) -n $(TARGET)-syms | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' > System.map -.PHONY: FORCE -FORCE: - %.o %.i %.s: %.c FORCE $(MAKE) -f $(BASEDIR)/Rules.mk -C $(*D) $(@F) @@ -277,25 +338,6 @@ $(foreach base,arch/x86/mm/guest_walk_% \ arch/x86/mm/shadow/guest_%, \ $(foreach ext,o i s,$(call build-intermediate,$(base).$(ext)))) -kconfig := oldconfig config menuconfig defconfig \ - nconfig xconfig gconfig savedefconfig listnewconfig olddefconfig \ - randconfig $(notdir $(wildcard arch/$(SRCARCH)/configs/*_defconfig)) -.PHONY: $(kconfig) -$(kconfig): - $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" $@ - -include/config/%.conf: include/config/auto.conf.cmd $(KCONFIG_CONFIG) - $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" syncconfig - -# Allow people to just run `make` as before and not force them to configure -$(KCONFIG_CONFIG): - $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" defconfig - -# Break the dependency chain for the first run -include/config/auto.conf.cmd: ; - --include $(BASEDIR)/include/config/auto.conf.cmd - .PHONY: cloc cloc: $(eval tmpfile := $(shell mktemp)) @@ -307,3 +349,11 @@ cloc: cloc --list-file=$(tmpfile) rm $(tmpfile) +endif #config-build + +PHONY += FORCE +FORCE: + +# Declare the contents of the PHONY variable as phony. We keep that +# information in a variable so we can use it in if_changed and friends. +.PHONY: $(PHONY)
We are going to generate the CFLAGS early from "xen/Makefile" instead of in "Rules.mk", but we need to include "config/auto.conf", so include it in "Makefile". Before including "config/auto.conf" we check which make target a user is calling, as some targets don't need "auto.conf". For targets that needs auto.conf, make will generate it (and a default .config if missing). root-make-done is to avoid doing the calculation again once Rules.mk takes over and is been executed with the root Makefile. When Rules.mk is including xen/Makefile, `config-build' and `need-config' are undefined so auto.conf will not be included again (it is already included by Rules.mk) and kconfig target are out of reach of Rules.mk. We are introducing a target %config to catch all targets for kconfig. So we need an extra target %/.config to prevent make from trying to regenerate $(XEN_ROOT)/.config that is included in Config.mk. The way targets are filtered is inspired by Kbuild, with some code imported from Linux. That's why there is PHONY variable that isn't used yet, for example. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- Notes: v3: - filter only for %config instead of both config %config - keep the multi-target pattern rule trick for include/config/auto.conf instead of using Linux's newer pattern (we dont have tristate.conf so don't need to change it) - use y/n for root-make-done, config-build, need-config instead of relying on ifdef and ifndef and on assigning an empty value meaning undef - use space for indentation - explain why %/.config is suddenly needed. xen/Makefile | 96 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 23 deletions(-)