From 102d712ded3ef2ee5b38ee6afa686aff63afd444 Mon Sep 17 00:00:00 2001 From: Nicolas Schier Date: Fri, 20 Feb 2026 19:55:19 +0100 Subject: kconfig: Error out on duplicated kconfig inclusion Let kconfig exit with error on duplicated Kconfig file inclusion. Repeated inclusion of Kbuild files are considered bad-practise with regard to maintenance; and Kconfig language is rich enough that there should be no need for that. If repeated inclusion of Kconfig files is detected, error out with messages like: Kconfig.inc1:4: error: repeated inclusion of Kconfig.inc3 Kconfig.inc2:3: note: location of first inclusion of Kconfig.inc3 While commit f094f8a1b273 ("kconfig: allow multiple inclusion of the same file") introduced detection of recursive inclusions of Kconfig files, it explicitly allowed repeated inclusions, unfortunately w/o reasoning. Reported-by: Linus Torvalds Closes: https://lore.kernel.org/all/CAHk-=wj03hLzK2D=+OYmjgcmGM+XYymp8GyaEs=C0=rXG2nb7w@mail.gmail.com/ Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Link: https://patch.msgid.link/20260220-kconfig-error-out-on-duplicated-inclusion-v1-1-be78aa241a53@kernel.org Signed-off-by: Nicolas Schier --- scripts/kconfig/util.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'scripts/kconfig/util.c') diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index 5cdcee144b58..0809aa061b6a 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -18,25 +18,50 @@ static HASHTABLE_DEFINE(file_hashtable, 1U << 11); struct file { struct hlist_node node; + struct { + const char *name; + int lineno; + } parent; char name[]; }; +static void die_duplicated_include(struct file *file, + const char *parent, int lineno) +{ + fprintf(stderr, + "%s:%d: error: repeated inclusion of %s\n" + "%s:%d: note: location of first inclusion of %s\n", + parent, lineno, file->name, + file->parent.name, file->parent.lineno, file->name); + exit(1); +} + /* file already present in list? If not add it */ -const char *file_lookup(const char *name) +const char *file_lookup(const char *name, + const char *parent_name, int parent_lineno) { + const char *parent = NULL; struct file *file; size_t len; int hash = hash_str(name); + if (parent_name) + parent = file_lookup(parent_name, NULL, 0); + hash_for_each_possible(file_hashtable, file, node, hash) - if (!strcmp(name, file->name)) - return file->name; + if (!strcmp(name, file->name)) { + if (!parent_name) + return file->name; + die_duplicated_include(file, parent, parent_lineno); + } len = strlen(name); file = xmalloc(sizeof(*file) + len + 1); memset(file, 0, sizeof(*file)); memcpy(file->name, name, len); file->name[len] = '\0'; + file->parent.name = parent; + file->parent.lineno = parent_lineno; hash_add(file_hashtable, &file->node, hash); -- cgit