Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <torvalds@linux-foundation.org>
Closes: https://lore.kernel.org/all/CAHk-=wj03hLzK2D=+OYmjgcmGM+XYymp8GyaEs=C0=rXG2nb7w@mail.gmail.com/
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Link: https://patch.msgid.link/20260220-kconfig-error-out-on-duplicated-inclusion-v1-1-be78aa241a53@kernel.org
Signed-off-by: Nicolas Schier <nsc@kernel.org>

+56 -7
+2 -2
scripts/kconfig/lexer.l
··· 402 402 exit(1); 403 403 } 404 404 405 - cur_filename = file_lookup(name); 405 + cur_filename = file_lookup(name, NULL, 0); 406 406 yylineno = 1; 407 407 } 408 408 ··· 443 443 } 444 444 445 445 yylineno = 1; 446 - cur_filename = file_lookup(name); 446 + cur_filename = file_lookup(name, cur_filename, cur_lineno); 447 447 } 448 448 449 449 static void zconf_endfile(void)
+2 -1
scripts/kconfig/lkc.h
··· 51 51 } 52 52 53 53 /* util.c */ 54 - const char *file_lookup(const char *name); 54 + const char *file_lookup(const char *name, 55 + const char *parent_name, int parent_lineno); 55 56 56 57 /* lexer.l */ 57 58 int yylex(void);
+3
scripts/kconfig/tests/err_repeated_inc/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + 3 + source "Kconfig.inc1"
+4
scripts/kconfig/tests/err_repeated_inc/Kconfig.inc1
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + 3 + source "Kconfig.inc2" 4 + source "Kconfig.inc3"
+3
scripts/kconfig/tests/err_repeated_inc/Kconfig.inc2
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + 3 + source "Kconfig.inc3"
+1
scripts/kconfig/tests/err_repeated_inc/Kconfig.inc3
··· 1 + # SPDX-License-Identifier: GPL-2.0-only
+10
scripts/kconfig/tests/err_repeated_inc/__init__.py
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + """ 3 + Detect repeated inclusion error. 4 + 5 + If repeated inclusion is detected, it should fail with error message. 6 + """ 7 + 8 + def test(conf): 9 + assert conf.oldaskconfig() != 0 10 + assert conf.stderr_contains('expected_stderr')
+2
scripts/kconfig/tests/err_repeated_inc/expected_stderr
··· 1 + Kconfig.inc1:4: error: Repeated inclusion of Kconfig.inc3 2 + Kconfig.inc2:3: note: Location of first inclusion of Kconfig.inc3
+29 -4
scripts/kconfig/util.c
··· 18 18 19 19 struct file { 20 20 struct hlist_node node; 21 + struct { 22 + const char *name; 23 + int lineno; 24 + } parent; 21 25 char name[]; 22 26 }; 23 27 24 - /* file already present in list? If not add it */ 25 - const char *file_lookup(const char *name) 28 + static void die_duplicated_include(struct file *file, 29 + const char *parent, int lineno) 26 30 { 31 + fprintf(stderr, 32 + "%s:%d: error: repeated inclusion of %s\n" 33 + "%s:%d: note: location of first inclusion of %s\n", 34 + parent, lineno, file->name, 35 + file->parent.name, file->parent.lineno, file->name); 36 + exit(1); 37 + } 38 + 39 + /* file already present in list? If not add it */ 40 + const char *file_lookup(const char *name, 41 + const char *parent_name, int parent_lineno) 42 + { 43 + const char *parent = NULL; 27 44 struct file *file; 28 45 size_t len; 29 46 int hash = hash_str(name); 30 47 48 + if (parent_name) 49 + parent = file_lookup(parent_name, NULL, 0); 50 + 31 51 hash_for_each_possible(file_hashtable, file, node, hash) 32 - if (!strcmp(name, file->name)) 33 - return file->name; 52 + if (!strcmp(name, file->name)) { 53 + if (!parent_name) 54 + return file->name; 55 + die_duplicated_include(file, parent, parent_lineno); 56 + } 34 57 35 58 len = strlen(name); 36 59 file = xmalloc(sizeof(*file) + len + 1); 37 60 memset(file, 0, sizeof(*file)); 38 61 memcpy(file->name, name, len); 39 62 file->name[len] = '\0'; 63 + file->parent.name = parent; 64 + file->parent.lineno = parent_lineno; 40 65 41 66 hash_add(file_hashtable, &file->node, hash); 42 67