From 3c900323692704b2b860feb23b1f14e2023ad096 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 6 Feb 2017 17:02:07 +1100 Subject: [PATCH] build system: Fix parallel & double menuconfig issues when sdkconfig missing Fixes misbehaviour of default menuconfig when sdkconfig is missing. (Either appearing twice, or breaking if make -jN is used.) --- make/common.mk | 2 +- make/project_config.mk | 70 +++++++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/make/common.mk b/make/common.mk index d19f7eb46c..4281bad94b 100644 --- a/make/common.mk +++ b/make/common.mk @@ -6,7 +6,7 @@ # # (Note that we only rebuild this makefile automatically for some # targets, see project_config.mk for details.) -SDKCONFIG_MAKEFILE ?= $(BUILD_DIR_BASE)/include/config/auto.conf +SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf) include $(SDKCONFIG_MAKEFILE) export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path diff --git a/make/project_config.mk b/make/project_config.mk index d33ae11969..3537f786ba 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -20,44 +20,66 @@ $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf: MAKEFLAGS=$(ORIGINAL_MAKEFLAGS) CC=$(HOSTCC) LD=$(HOSTLD) \ $(MAKE) -C $(KCONFIG_TOOL_DIR) -# use a wrapper environment for where we run Kconfig tools -KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \ - COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ - COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" - -menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(call prereq_if_explicit,defconfig) - $(summary) MENUCONFIG - $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig - ifeq ("$(wildcard $(SDKCONFIG))","") -ifeq ("$(call prereq_if_explicit,defconfig)","") -# if not configuration is present and defconfig is not a target, run defconfig then menuconfig -$(SDKCONFIG): defconfig menuconfig +ifeq ("$(filter defconfig, $(MAKECMDGOALS))","") +# if no configuration file is present and defconfig is not a named +# target, run defconfig then menuconfig to get the initial config +$(SDKCONFIG): menuconfig +menuconfig: defconfig else -# otherwise, just defconfig +# otherwise, just run defconfig $(SDKCONFIG): defconfig endif endif +# macro for the commands to run kconfig tools conf or mconf. +# $1 is the name (& args) of the conf tool to run +define RunConf + mkdir -p $(BUILD_DIR_BASE)/include/config + cd $(BUILD_DIR_BASE); KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \ + COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ + COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \ + $(KCONFIG_TOOL_DIR)/$1 $(IDF_PATH)/Kconfig +endef + +ifeq ("$(MAKE_RESTARTS)","") +# menuconfig, defconfig and "GENCONFIG" configuration generation only +# ever run on the first make pass, subsequent passes don't run these +# (make often wants to re-run them as the conf tool can regenerate the +# sdkconfig input file as an output file, but this is not what the +# user wants - a single config pass is enough to produce all output +# files.) +# +# To prevent problems missing genconfig, ensure none of these targets +# depend on any prerequisite that may cause a make restart as part of +# the prerequisite's own recipe. + +menuconfig: $(KCONFIG_TOOL_DIR)/mconf + $(summary) MENUCONFIG + $(call RunConf,mconf) + # defconfig creates a default config, based on SDKCONFIG_DEFAULTS if present -defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) +defconfig: $(KCONFIG_TOOL_DIR)/conf $(summary) DEFCONFIG ifneq ("$(wildcard $(SDKCONFIG_DEFAULTS))","") cat $(SDKCONFIG_DEFAULTS) >> $(SDKCONFIG) # append defaults to sdkconfig, will override existing values endif - mkdir -p $(BUILD_DIR_BASE)/include/config - $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig + $(call RunConf,conf --olddefconfig) -$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) +# if neither defconfig or menuconfig are requested, use the GENCONFIG rule to +# ensure generated config files are up to date +$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(KCONFIG_TOOL_DIR)/conf $(SDKCONFIG) $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) | $(call prereq_if_explicit,defconfig) $(call prereq_if_explicit,menuconfig) $(summary) GENCONFIG - mkdir -p $(BUILD_DIR_BASE)/include/config - cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig - touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h -# touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this, -# sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer -# than the target(!) + $(call RunConf,conf --silentoldconfig) + touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # ensure newer than sdkconfig -.PHONY: config-clean +else # "$(MAKE_RESTARTS)" != "" +# on subsequent make passes, skip config generation entirely +defconfig: +menuconfig: +endif + +.PHONY: config-clean defconfig menuconfig config-clean: $(summary RM CONFIG) $(MAKE) -C $(KCONFIG_TOOL_DIR) clean