diff --git a/hypervisor/scripts/kconfig/kconfig.mk b/hypervisor/scripts/kconfig/kconfig.mk index aa48bb41c..2154e88af 100644 --- a/hypervisor/scripts/kconfig/kconfig.mk +++ b/hypervisor/scripts/kconfig/kconfig.mk @@ -30,6 +30,12 @@ endif endif -include $(HV_OBJDIR)/$(HV_CONFIG_MK) +ifeq ($(shell [ $(HV_OBJDIR)/$(HV_CONFIG) -nt $(HV_OBJDIR)/$(HV_CONFIG_MK) ] && echo 1),1) +# config.mk may be outdated if .config has been overwritten. To update config.mk +# in such cases, we include .config again to get the new configurations. This +# only happens when GNU make checks the prerequisites. +-include $(HV_OBJDIR)/$(HV_CONFIG) +endif # Backward-compatibility for PLATFORM=(sbl|uefi) # * PLATFORM=sbl is equivalent to BOARD=apl-mrb @@ -85,9 +91,6 @@ defconfig: $(KCONFIG_DEPS) # new one if no previous .config exists. This target can be used as a # prerequisite of all the others to make sure that the .config is consistent # even it has been modified manually before. -# -# Note: Should not pass CONFIG_xxx to silentoldconfig here because config.mk can -# be out-dated. .PHONY: oldconfig oldconfig: $(KCONFIG_DEPS) @mkdir -p $(HV_OBJDIR) diff --git a/scripts/kconfig/silentoldconfig.py b/scripts/kconfig/silentoldconfig.py index ef2528d3c..3a67ec39a 100644 --- a/scripts/kconfig/silentoldconfig.py +++ b/scripts/kconfig/silentoldconfig.py @@ -31,12 +31,6 @@ def main(): kconfig = kconfiglib.Kconfig(kconfig_path) - config_path = sys.argv[2] - has_old_config = False - if os.path.isfile(config_path): - kconfig.load_config(config_path) - has_old_config = True - # Parse the configs specified on cmdline cmdline_conf = {} @@ -47,23 +41,72 @@ def main(): if sym_name in kconfig.syms.keys() and val: cmdline_conf[sym_name] = val - # Check if the old .config conflicts with those specified on cmdline + # Determine the base config. + # + # If either + # + # 1. no .config exists, or + # 2. the BOARD in the existing .config is different from the BOARD + # specified in the environment variable + # + # the defconfig will be used as the base config. Otherwise the existing + # .config is used as the base. + # + # Note that the BOARD given by the environment variable may be different + # from what is specified in the corresponding defconfig. Thus we get the + # target_board by loading the defconfig first. + # + # To be backward compatible, do not look for any defconfig in the Kconfig if + # such BOARD is not given. Simply use the .config or all default values + # (when no .config exists) as the base. + config_path = sys.argv[2] + target_board = None + if 'BOARD' in os.environ: + defconfig_path = kconfig.defconfig_filename + if defconfig_path and os.path.isfile(defconfig_path): + kconfig.load_config(defconfig_path) + target_board = kconfig.syms['BOARD'].str_value + + need_update = False + if os.path.isfile(config_path): + kconfig.load_config(config_path) + if target_board and kconfig.syms['BOARD'].str_value != target_board: + kconfig.load_config(defconfig_path) + sys.stdout.write("Overwrite with default configuration based on %s.\n" % defconfig_path) + need_update = True + else: + # create a default configuration + if target_board: + # target_board is not None if and only if a BOARD is specified and the + # corresponding defconfig has been loaded. + sys.stdout.write("Default configuration based on %s.\n" % defconfig_path) + else: + # If no known defconfig exists, either report an error if a + # BOARD is specified in the environment, or use the default values in + # Kconfig. + if 'BOARD' in os.environ: + sys.stderr.write("No defconfig found for board %s.\n" % target_board) + sys.exit(1) + need_update = True + + # Update the old .config with those specified on cmdline + # + # Note: the user shall be careful what configuration symbols to overwrite by + # silentoldconfig. After changing a symbol value, the invisible symbols are + # updated accordingly because they always use the default value, while + # visible symbols keep their original value in the old .config. This may + # lead to invalid .config for a specific platform. + # + # Currently it is recommended to use the following update only for + # RELEASE. For PLATFORM reinvoke defconfig is preferred. - has_conflict = False for sym_name, val in cmdline_conf.items(): sym = kconfig.syms[sym_name] if sym.str_value and sym.str_value != val: - has_conflict = True - break - - # If there's any conflict, reconfigure using those from the cmdline. The - # default values are used for unspecified symbols. - - if not has_old_config or has_conflict: - kconfig.unset_values() - for sym_name, val in cmdline_conf.items(): kconfig.syms[sym_name].set_value(val) + need_update = True + if need_update: kconfig.write_config(config_path) sys.stdout.write("Configuration written to %s.\n" % config_path)