Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7cf3d73b authored by Sam Ravnborg's avatar Sam Ravnborg Committed by Michal Marek
Browse files

kconfig: add savedefconfig



savedefconfig will save a minimal config to a file
named "defconfig".

The config symbols are saved in the same order as
they appear in the menu structure so it should
be possible to map them to the relevant menus
if desired.

The implementation was tested against several minimal
configs for arm which was created using brute-force.

There was one regression related to default numbers
which had their valid range further limited by another symbol.

Sample:

config FOO
	int "foo"
	default 4

config BAR
	int "bar"
	range 0 FOO

If FOO is set to 3 then BAR cannot take a value higher than 3.
But the current implementation will set BAR equal to 4.

This is seldomly used and the final configuration is OK,
and the fix was non-trivial.
So it was documented in the code and left as is.

Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
Acked-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: default avatarMichal Marek <mmarek@suse.cz>
parent 49192f26
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -90,11 +90,14 @@ PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
	$< --$@ $(Kconfig)

PHONY += listnewconfig oldnoconfig defconfig
PHONY += listnewconfig oldnoconfig savedefconfig defconfig

listnewconfig oldnoconfig: $(obj)/conf
	$< --$@ $(Kconfig)

savedefconfig: $(obj)/conf
	$< --$@=defconfig $(Kconfig)

defconfig: $(obj)/conf
ifeq ($(KBUILD_DEFCONFIG),)
	$< --defconfig $(Kconfig)
@@ -118,6 +121,7 @@ help:
	@echo  '  localyesconfig  - Update current config converting local mods to core'
	@echo  '  silentoldconfig - Same as oldconfig, but quietly, additionally update deps'
	@echo  '  defconfig	  - New config with default from ARCH supplied defconfig'
	@echo  '  savedefconfig   - Save current config as ./defconfig (minimal config)'
	@echo  '  allnoconfig	  - New config where all options are answered with no'
	@echo  '  allyesconfig	  - New config where all options are accepted with yes'
	@echo  '  allmodconfig	  - New config selecting modules when possible'
+14 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ enum input_mode {
	alldefconfig,
	randconfig,
	defconfig,
	savedefconfig,
	listnewconfig,
	oldnoconfig,
} input_mode = oldaskconfig;
@@ -444,6 +445,7 @@ static struct option long_opts[] = {
	{"oldconfig",       no_argument,       NULL, oldconfig},
	{"silentoldconfig", no_argument,       NULL, silentoldconfig},
	{"defconfig",       optional_argument, NULL, defconfig},
	{"savedefconfig",   required_argument, NULL, savedefconfig},
	{"allnoconfig",     no_argument,       NULL, allnoconfig},
	{"allyesconfig",    no_argument,       NULL, allyesconfig},
	{"allmodconfig",    no_argument,       NULL, allmodconfig},
@@ -471,6 +473,7 @@ int main(int ac, char **av)
			sync_kconfig = 1;
			break;
		case defconfig:
		case savedefconfig:
			defconfig_file = optarg;
			break;
		case randconfig:
@@ -526,6 +529,9 @@ int main(int ac, char **av)
			exit(1);
		}
		break;
	case savedefconfig:
		conf_read(NULL);
		break;
	case silentoldconfig:
	case oldaskconfig:
	case oldconfig:
@@ -591,6 +597,8 @@ int main(int ac, char **av)
	case defconfig:
		conf_set_all_new_symbols(def_default);
		break;
	case savedefconfig:
		break;
	case oldconfig:
	case oldaskconfig:
		rootEntry = &rootmenu;
@@ -622,6 +630,12 @@ int main(int ac, char **av)
			fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
			return 1;
		}
	} else if (input_mode == savedefconfig) {
		if (conf_write_defconfig(defconfig_file)) {
			fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
			        defconfig_file);
			return 1;
		}
	} else if (input_mode != listnewconfig) {
		if (conf_write(NULL)) {
			fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
+76 −0
Original line number Diff line number Diff line
@@ -457,6 +457,82 @@ static void conf_write_symbol(struct symbol *sym, enum symbol_type type,
	}
}

/*
 * Write out a minimal config.
 * All values that has default values are skipped as this is redundant.
 */
int conf_write_defconfig(const char *filename)
{
	struct symbol *sym;
	struct menu *menu;
	FILE *out;

	out = fopen(filename, "w");
	if (!out)
		return 1;

	sym_clear_all_valid();

	/* Traverse all menus to find all relevant symbols */
	menu = rootmenu.list;

	while (menu != NULL)
	{
		sym = menu->sym;
		if (sym == NULL) {
			if (!menu_is_visible(menu))
				goto next_menu;
		} else if (!sym_is_choice(sym)) {
			sym_calc_value(sym);
			if (!(sym->flags & SYMBOL_WRITE))
				goto next_menu;
			sym->flags &= ~SYMBOL_WRITE;
			/* If we cannot change the symbol - skip */
			if (!sym_is_changable(sym))
				goto next_menu;
			/* If symbol equals to default value - skip */
			if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
				goto next_menu;

			/*
			 * If symbol is a choice value and equals to the
			 * default for a choice - skip.
			 * But only if value equal to "y".
			 */
			if (sym_is_choice_value(sym)) {
				struct symbol *cs;
				struct symbol *ds;

				cs = prop_get_symbol(sym_get_choice_prop(sym));
				ds = sym_choice_default(cs);
				if (sym == ds) {
					if ((sym->type == S_BOOLEAN ||
					sym->type == S_TRISTATE) &&
					sym_get_tristate_value(sym) == yes)
						goto next_menu;
				}
			}
			conf_write_symbol(sym, sym->type, out, true);
		}
next_menu:
		if (menu->list != NULL) {
			menu = menu->list;
		}
		else if (menu->next != NULL) {
			menu = menu->next;
		} else {
			while ((menu = menu->parent)) {
				if (menu->next != NULL) {
					menu = menu->next;
					break;
				}
			}
		}
	}
	fclose(out);
	return 0;
}

int conf_write(const char *name)
{
	FILE *out;
+1 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ void sym_clear_all_valid(void);
void sym_set_all_changed(void);
void sym_set_changed(struct symbol *sym);
struct symbol *sym_choice_default(struct symbol *sym);
const char *sym_get_string_default(struct symbol *sym);
struct symbol *sym_check_deps(struct symbol *sym);
struct property *prop_alloc(enum prop_type type, struct symbol *sym);
struct symbol *prop_get_symbol(struct property *prop);
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name));
P(conf_read_simple,int,(const char *name, int));
P(conf_write_defconfig,int,(const char *name));
P(conf_write,int,(const char *name));
P(conf_write_autoconf,int,(void));
P(conf_get_changed,bool,(void));
Loading