public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] kconfig: Error out on duplicated kconfig inclusion
@ 2026-02-20 18:55 Nicolas Schier
  2026-02-24  6:00 ` Nathan Chancellor
  2026-02-27  8:30 ` Nicolas Schier
  0 siblings, 2 replies; 3+ messages in thread
From: Nicolas Schier @ 2026-02-20 18:55 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: linux-kernel, linux-kbuild, Linus Torvalds, Nicolas Schier

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 <torvalds@linux-foundation.org>
Closes: https://lore.kernel.org/all/CAHk-=wj03hLzK2D=+OYmjgcmGM+XYymp8GyaEs=C0=rXG2nb7w@mail.gmail.com/
Signed-off-by: Nicolas Schier <nsc@kernel.org>
---
 scripts/kconfig/lexer.l                            |  4 +--
 scripts/kconfig/lkc.h                              |  3 ++-
 scripts/kconfig/tests/err_repeated_inc/Kconfig     |  3 +++
 .../kconfig/tests/err_repeated_inc/Kconfig.inc1    |  4 +++
 .../kconfig/tests/err_repeated_inc/Kconfig.inc2    |  3 +++
 .../kconfig/tests/err_repeated_inc/Kconfig.inc3    |  1 +
 scripts/kconfig/tests/err_repeated_inc/__init__.py | 10 +++++++
 .../kconfig/tests/err_repeated_inc/expected_stderr |  2 ++
 scripts/kconfig/util.c                             | 31 +++++++++++++++++++---
 9 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 6d2c92c6095dd8c247e6c2dd5dd0b56b8ea6a769..a6155422b4a688070a40a88edfedbcacb251da76 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -402,7 +402,7 @@ void zconf_initscan(const char *name)
 		exit(1);
 	}
 
-	cur_filename = file_lookup(name);
+	cur_filename = file_lookup(name, NULL, 0);
 	yylineno = 1;
 }
 
@@ -443,7 +443,7 @@ void zconf_nextfile(const char *name)
 	}
 
 	yylineno = 1;
-	cur_filename = file_lookup(name);
+	cur_filename = file_lookup(name, cur_filename, cur_lineno);
 }
 
 static void zconf_endfile(void)
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 79898596121563350d2fa63fcf879743b756d003..7e6f6ca299cf1a74e4aed704972bc098616a94b0 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -51,7 +51,8 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
 }
 
 /* util.c */
-const char *file_lookup(const char *name);
+const char *file_lookup(const char *name,
+			const char *parent_name, int parent_lineno);
 
 /* lexer.l */
 int yylex(void);
diff --git a/scripts/kconfig/tests/err_repeated_inc/Kconfig b/scripts/kconfig/tests/err_repeated_inc/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..09a88fd29cb5a90f50585c9381a3f1b2f64a6087
--- /dev/null
+++ b/scripts/kconfig/tests/err_repeated_inc/Kconfig
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+source "Kconfig.inc1"
diff --git a/scripts/kconfig/tests/err_repeated_inc/Kconfig.inc1 b/scripts/kconfig/tests/err_repeated_inc/Kconfig.inc1
new file mode 100644
index 0000000000000000000000000000000000000000..495dc38314a1ac0303f9ce23500af8b009eaad3d
--- /dev/null
+++ b/scripts/kconfig/tests/err_repeated_inc/Kconfig.inc1
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+source "Kconfig.inc2"
+source "Kconfig.inc3"
diff --git a/scripts/kconfig/tests/err_repeated_inc/Kconfig.inc2 b/scripts/kconfig/tests/err_repeated_inc/Kconfig.inc2
new file mode 100644
index 0000000000000000000000000000000000000000..2b630eec2e99163cd04bc9d3e55393c70f8a886c
--- /dev/null
+++ b/scripts/kconfig/tests/err_repeated_inc/Kconfig.inc2
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+source "Kconfig.inc3"
diff --git a/scripts/kconfig/tests/err_repeated_inc/Kconfig.inc3 b/scripts/kconfig/tests/err_repeated_inc/Kconfig.inc3
new file mode 100644
index 0000000000000000000000000000000000000000..a4e40e534e6a84db241abfe5076962a90f8a71bd
--- /dev/null
+++ b/scripts/kconfig/tests/err_repeated_inc/Kconfig.inc3
@@ -0,0 +1 @@
+# SPDX-License-Identifier: GPL-2.0-only
diff --git a/scripts/kconfig/tests/err_repeated_inc/__init__.py b/scripts/kconfig/tests/err_repeated_inc/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..129d740a874b30e73acde797bd00e9f160c7a7ef
--- /dev/null
+++ b/scripts/kconfig/tests/err_repeated_inc/__init__.py
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Detect repeated inclusion error.
+
+If repeated inclusion is detected, it should fail with error message.
+"""
+
+def test(conf):
+    assert conf.oldaskconfig() != 0
+    assert conf.stderr_contains('expected_stderr')
diff --git a/scripts/kconfig/tests/err_repeated_inc/expected_stderr b/scripts/kconfig/tests/err_repeated_inc/expected_stderr
new file mode 100644
index 0000000000000000000000000000000000000000..95d90d6a93c52ec886a6309600c8c88205253497
--- /dev/null
+++ b/scripts/kconfig/tests/err_repeated_inc/expected_stderr
@@ -0,0 +1,2 @@
+Kconfig.inc1:4: error: Repeated inclusion of Kconfig.inc3
+Kconfig.inc2:3: note: Location of first inclusion of Kconfig.inc3
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 5cdcee144b58126dcfab50fd709be9fc40e99423..1b69dd9e1872a0671a70e24b45a30e449dd2c75e 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);
 

---
base-commit: ca4ee40bf13dbd3a4be3b40a00c33a1153d487e5
change-id: 20260218-kconfig-error-out-on-duplicated-inclusion-5e96d6b7ef44

Best regards,
-- 
Nicolas


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] kconfig: Error out on duplicated kconfig inclusion
  2026-02-20 18:55 [PATCH] kconfig: Error out on duplicated kconfig inclusion Nicolas Schier
@ 2026-02-24  6:00 ` Nathan Chancellor
  2026-02-27  8:30 ` Nicolas Schier
  1 sibling, 0 replies; 3+ messages in thread
From: Nathan Chancellor @ 2026-02-24  6:00 UTC (permalink / raw)
  To: Nicolas Schier; +Cc: linux-kernel, linux-kbuild, Linus Torvalds

Hi Nicolas,

On Fri, Feb 20, 2026 at 07:55:19PM +0100, Nicolas Schier wrote:
> 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 <torvalds@linux-foundation.org>
> Closes: https://lore.kernel.org/all/CAHk-=wj03hLzK2D=+OYmjgcmGM+XYymp8GyaEs=C0=rXG2nb7w@mail.gmail.com/
> Signed-off-by: Nicolas Schier <nsc@kernel.org>

Nice! That was quite simple in terms of actual implementation and I like
the tests :) I verified that there are errors from the drm/Kconfig state
at ca4ee40bf13d^:

  drivers/gpu/drm/Kconfig:427: error: Repeated inclusion of drivers/gpu/drm/adp/Kconfig
  drivers/gpu/drm/Kconfig:385: note: Location of first inclusion of drivers/gpu/drm/adp/Kconfig

and that testconfig passes for me locally.

Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>

> diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
> index 5cdcee144b58126dcfab50fd709be9fc40e99423..1b69dd9e1872a0671a70e24b45a30e449dd2c75e 100644
> --- a/scripts/kconfig/util.c
> +++ b/scripts/kconfig/util.c
> @@ -18,25 +18,50 @@ static HASHTABLE_DEFINE(file_hashtable, 1U << 11);
...
> +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",

I think for visual consistency with compiler warnings/errors and the
rest of scripts/kconfig, Repeated and Location should be lowercased in
these prints.

> +		parent, lineno, file->name,
> +		file->parent.name, file->parent.lineno, file->name);
> +	exit(1);

Cheers,
Nathan

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] kconfig: Error out on duplicated kconfig inclusion
  2026-02-20 18:55 [PATCH] kconfig: Error out on duplicated kconfig inclusion Nicolas Schier
  2026-02-24  6:00 ` Nathan Chancellor
@ 2026-02-27  8:30 ` Nicolas Schier
  1 sibling, 0 replies; 3+ messages in thread
From: Nicolas Schier @ 2026-02-27  8:30 UTC (permalink / raw)
  To: Nathan Chancellor, Nicolas Schier
  Cc: linux-kernel, linux-kbuild, Linus Torvalds


On Fri, 20 Feb 2026 19:55:19 +0100, Nicolas Schier wrote:
> 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:
> 
> [...]

Nathan, thanks for spotting the upper case letters.  I fixed it locally.

Applied, thanks!

[1/1] kconfig: Error out on duplicated kconfig inclusion
      https://git.kernel.org/kbuild/c/102d712d

Best regards,
-- 
Nicolas


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-02-27  8:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-20 18:55 [PATCH] kconfig: Error out on duplicated kconfig inclusion Nicolas Schier
2026-02-24  6:00 ` Nathan Chancellor
2026-02-27  8:30 ` Nicolas Schier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox