mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
Merge tag 'kbuild-7.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux
Pull more Kbuild updates from Nathan Chancellor: - Link host programs with ld.lld when $(LLVM) is set to match user's expectations that LLVM will be used exclusively during the build process - Fix modpost warnings from static variable name promotion that can happen more aggressively with the recently merged distributed ThinLTO support - Add an optional warning for user-supplied Kconfig values that changed after processing, such as out of range values or options that have incorrect / missing dependencies * tag 'kbuild-7.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux: kconfig: add optional warnings for changed input values modpost: Ignore Clang LTO suffixes in symbol matching kbuild: Use ld.lld for linking host programs when LLVM is set
This commit is contained in:
@@ -59,6 +59,11 @@ Environment variables for ``*config``:
|
||||
This environment variable makes Kconfig warn about all unrecognized
|
||||
symbols in the config input.
|
||||
|
||||
``KCONFIG_WARN_CHANGED_INPUT``
|
||||
If set to a non-blank value, Kconfig prints optional warnings for
|
||||
user-provided values that change after Kconfig resolves dependencies
|
||||
or applies other constraints such as ranges.
|
||||
|
||||
``KCONFIG_WERROR``
|
||||
If set, Kconfig treats warnings as errors.
|
||||
|
||||
|
||||
3
Makefile
3
Makefile
@@ -528,6 +528,9 @@ OBJCOPY = $(LLVM_PREFIX)llvm-objcopy$(LLVM_SUFFIX)
|
||||
OBJDUMP = $(LLVM_PREFIX)llvm-objdump$(LLVM_SUFFIX)
|
||||
READELF = $(LLVM_PREFIX)llvm-readelf$(LLVM_SUFFIX)
|
||||
STRIP = $(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX)
|
||||
ifeq ($(filter -fuse-ld=% --ld-path=%,$(KBUILD_HOSTLDFLAGS)),)
|
||||
KBUILD_HOSTLDFLAGS += -fuse-ld=lld
|
||||
endif
|
||||
else
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
|
||||
@@ -206,6 +206,78 @@ static void conf_message(const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void conf_changed_input_warning(const char *s)
|
||||
{
|
||||
fputs(s, stderr);
|
||||
}
|
||||
|
||||
static bool conf_warn_changed_input_enabled(void)
|
||||
{
|
||||
const char *env = getenv("KCONFIG_WARN_CHANGED_INPUT");
|
||||
|
||||
return env && *env;
|
||||
}
|
||||
|
||||
static const char *sym_get_user_value_string(struct symbol *sym)
|
||||
{
|
||||
switch (sym->type) {
|
||||
case S_BOOLEAN:
|
||||
case S_TRISTATE:
|
||||
switch (sym->def[S_DEF_USER].tri) {
|
||||
case yes:
|
||||
return "y";
|
||||
case mod:
|
||||
return "m";
|
||||
default:
|
||||
return "n";
|
||||
}
|
||||
default:
|
||||
return sym->def[S_DEF_USER].val ?: "";
|
||||
}
|
||||
}
|
||||
|
||||
static bool sym_user_value_changed(struct symbol *sym)
|
||||
{
|
||||
if (!sym_has_value(sym) || sym->type == S_UNKNOWN)
|
||||
return false;
|
||||
|
||||
switch (sym->type) {
|
||||
case S_BOOLEAN:
|
||||
case S_TRISTATE:
|
||||
return sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym);
|
||||
default:
|
||||
return strcmp(sym_get_user_value_string(sym),
|
||||
sym_get_string_value(sym));
|
||||
}
|
||||
}
|
||||
|
||||
static void conf_clear_written_flags(void)
|
||||
{
|
||||
struct symbol *sym;
|
||||
|
||||
for_all_symbols(sym)
|
||||
sym->flags &= ~SYMBOL_WRITTEN;
|
||||
}
|
||||
|
||||
static void conf_append_changed_input_warning(struct gstr *gs,
|
||||
struct symbol *sym,
|
||||
bool *changed_input_found)
|
||||
{
|
||||
if (!sym_user_value_changed(sym))
|
||||
return;
|
||||
|
||||
if (!*changed_input_found) {
|
||||
str_printf(gs,
|
||||
"warning: user-provided values changed by Kconfig:\n");
|
||||
*changed_input_found = true;
|
||||
}
|
||||
|
||||
str_printf(gs, " %s%s: %s -> %s\n",
|
||||
CONFIG_, sym->name,
|
||||
sym_get_user_value_string(sym),
|
||||
sym_get_string_value(sym));
|
||||
}
|
||||
|
||||
const char *conf_get_configname(void)
|
||||
{
|
||||
char *name = getenv("KCONFIG_CONFIG");
|
||||
@@ -759,11 +831,15 @@ int conf_write_defconfig(const char *filename)
|
||||
{
|
||||
struct symbol *sym;
|
||||
struct menu *menu;
|
||||
struct gstr gs;
|
||||
FILE *out;
|
||||
bool warn_changed_input = conf_warn_changed_input_enabled();
|
||||
bool changed_input_found = false;
|
||||
|
||||
out = fopen(filename, "w");
|
||||
if (!out)
|
||||
return 1;
|
||||
gs = str_new();
|
||||
|
||||
sym_clear_all_valid();
|
||||
|
||||
@@ -772,10 +848,14 @@ int conf_write_defconfig(const char *filename)
|
||||
|
||||
sym = menu->sym;
|
||||
|
||||
if (!sym || sym_is_choice(sym))
|
||||
if (!sym || sym_is_choice(sym) || sym->flags & SYMBOL_WRITTEN)
|
||||
continue;
|
||||
|
||||
sym_calc_value(sym);
|
||||
if (warn_changed_input)
|
||||
conf_append_changed_input_warning(&gs, sym,
|
||||
&changed_input_found);
|
||||
sym->flags |= SYMBOL_WRITTEN;
|
||||
if (!(sym->flags & SYMBOL_WRITE))
|
||||
continue;
|
||||
sym->flags &= ~SYMBOL_WRITE;
|
||||
@@ -798,6 +878,13 @@ int conf_write_defconfig(const char *filename)
|
||||
print_symbol_for_dotconfig(out, sym);
|
||||
}
|
||||
fclose(out);
|
||||
|
||||
conf_clear_written_flags();
|
||||
|
||||
if (changed_input_found)
|
||||
conf_changed_input_warning(str_get(&gs));
|
||||
|
||||
str_free(&gs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -809,7 +896,10 @@ int conf_write(const char *name)
|
||||
const char *str;
|
||||
char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
|
||||
char *env;
|
||||
struct gstr gs;
|
||||
bool need_newline = false;
|
||||
bool warn_changed_input = conf_warn_changed_input_enabled();
|
||||
bool changed_input_found = false;
|
||||
|
||||
if (!name)
|
||||
name = conf_get_configname();
|
||||
@@ -838,6 +928,7 @@ int conf_write(const char *name)
|
||||
}
|
||||
if (!out)
|
||||
return 1;
|
||||
gs = str_new();
|
||||
|
||||
conf_write_heading(out, &comment_style_pound);
|
||||
|
||||
@@ -859,13 +950,16 @@ int conf_write(const char *name)
|
||||
} else if (!sym_is_choice(sym) &&
|
||||
!(sym->flags & SYMBOL_WRITTEN)) {
|
||||
sym_calc_value(sym);
|
||||
if (warn_changed_input)
|
||||
conf_append_changed_input_warning(&gs, sym,
|
||||
&changed_input_found);
|
||||
sym->flags |= SYMBOL_WRITTEN;
|
||||
if (!(sym->flags & SYMBOL_WRITE))
|
||||
goto next;
|
||||
if (need_newline) {
|
||||
fprintf(out, "\n");
|
||||
need_newline = false;
|
||||
}
|
||||
sym->flags |= SYMBOL_WRITTEN;
|
||||
print_symbol_for_dotconfig(out, sym);
|
||||
}
|
||||
|
||||
@@ -892,8 +986,12 @@ int conf_write(const char *name)
|
||||
}
|
||||
fclose(out);
|
||||
|
||||
for_all_symbols(sym)
|
||||
sym->flags &= ~SYMBOL_WRITTEN;
|
||||
conf_clear_written_flags();
|
||||
|
||||
if (changed_input_found)
|
||||
conf_changed_input_warning(str_get(&gs));
|
||||
|
||||
str_free(&gs);
|
||||
|
||||
if (*tmpname) {
|
||||
if (is_same(name, tmpname)) {
|
||||
|
||||
@@ -37,7 +37,8 @@ class Conf:
|
||||
|
||||
# runners
|
||||
def _run_conf(self, mode, dot_config=None, out_file='.config',
|
||||
interactive=False, in_keys=None, extra_env={}):
|
||||
interactive=False, in_keys=None, extra_env={},
|
||||
silent=False):
|
||||
"""Run text-based Kconfig executable and save the result.
|
||||
|
||||
mode: input mode option (--oldaskconfig, --defconfig=<file> etc.)
|
||||
@@ -48,7 +49,10 @@ class Conf:
|
||||
extra_env: additional environments
|
||||
returncode: exit status of the Kconfig executable
|
||||
"""
|
||||
command = [CONF_PATH, mode, 'Kconfig']
|
||||
command = [CONF_PATH]
|
||||
if silent:
|
||||
command.append('-s')
|
||||
command += [mode, 'Kconfig']
|
||||
|
||||
# Override 'srctree' environment to make the test as the top directory
|
||||
extra_env['srctree'] = self._test_dir
|
||||
|
||||
40
scripts/kconfig/tests/warn_changed_input/Kconfig
Normal file
40
scripts/kconfig/tests/warn_changed_input/Kconfig
Normal file
@@ -0,0 +1,40 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
config DEP
|
||||
bool "DEP"
|
||||
help
|
||||
Test dependency symbol for Kconfig warning coverage.
|
||||
This is used by the warn_changed_input selftest.
|
||||
It intentionally stays unset in the input fragment.
|
||||
The test checks how dependent user input is adjusted.
|
||||
|
||||
config A
|
||||
bool "A"
|
||||
depends on DEP
|
||||
help
|
||||
Test bool symbol for changed-input diagnostics.
|
||||
The input fragment requests this symbol as built-in.
|
||||
The unmet dependency on DEP forces the final value to n.
|
||||
The warning should report that downgrade.
|
||||
|
||||
config NUM
|
||||
int "NUM"
|
||||
range 10 20
|
||||
help
|
||||
Test integer symbol for changed-input diagnostics.
|
||||
The input fragment requests a value outside the allowed range.
|
||||
Kconfig resolves it to the constrained in-range value.
|
||||
The warning should report that adjustment.
|
||||
|
||||
config DUP
|
||||
bool "DUP"
|
||||
depends on DEP
|
||||
help
|
||||
Test duplicate-definition handling for changed-input diagnostics.
|
||||
The input fragment requests this symbol as built-in.
|
||||
The duplicate definition below must not produce a duplicate warning.
|
||||
This keeps the warning output stable for repeated menu entries.
|
||||
|
||||
config DUP
|
||||
bool
|
||||
depends on DEP
|
||||
33
scripts/kconfig/tests/warn_changed_input/__init__.py
Normal file
33
scripts/kconfig/tests/warn_changed_input/__init__.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
"""
|
||||
Test optional warnings for user-provided values changed by Kconfig.
|
||||
|
||||
Warnings should stay disabled by default, and should only appear when
|
||||
KCONFIG_WARN_CHANGED_INPUT is enabled.
|
||||
"""
|
||||
|
||||
|
||||
def test(conf):
|
||||
assert conf.olddefconfig('config') == 0
|
||||
assert 'user-provided values changed by Kconfig' not in conf.stderr
|
||||
|
||||
assert conf._run_conf('--olddefconfig', dot_config='config',
|
||||
extra_env={
|
||||
'KCONFIG_WARN_CHANGED_INPUT': '1',
|
||||
}) == 0
|
||||
assert conf.stderr_contains('expected_stderr')
|
||||
assert conf.config_matches('expected_config')
|
||||
|
||||
assert conf._run_conf('--olddefconfig', dot_config='config',
|
||||
extra_env={
|
||||
'KCONFIG_WARN_CHANGED_INPUT': '1',
|
||||
}, silent=True) == 0
|
||||
assert conf.stderr_contains('expected_stderr')
|
||||
|
||||
assert conf._run_conf('--savedefconfig=defconfig', dot_config='config',
|
||||
out_file='defconfig',
|
||||
extra_env={
|
||||
'KCONFIG_WARN_CHANGED_INPUT': '1',
|
||||
}) == 0
|
||||
assert conf.stderr_contains('expected_stderr')
|
||||
assert conf.config_matches('expected_defconfig')
|
||||
3
scripts/kconfig/tests/warn_changed_input/config
Normal file
3
scripts/kconfig/tests/warn_changed_input/config
Normal file
@@ -0,0 +1,3 @@
|
||||
CONFIG_A=y
|
||||
CONFIG_NUM=30
|
||||
CONFIG_DUP=y
|
||||
6
scripts/kconfig/tests/warn_changed_input/expected_config
Normal file
6
scripts/kconfig/tests/warn_changed_input/expected_config
Normal file
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Main menu
|
||||
#
|
||||
# CONFIG_DEP is not set
|
||||
CONFIG_NUM=20
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_NUM=20
|
||||
4
scripts/kconfig/tests/warn_changed_input/expected_stderr
Normal file
4
scripts/kconfig/tests/warn_changed_input/expected_stderr
Normal file
@@ -0,0 +1,4 @@
|
||||
warning: user-provided values changed by Kconfig:
|
||||
CONFIG_A: y -> n
|
||||
CONFIG_NUM: 30 -> 20
|
||||
CONFIG_DUP: y -> n
|
||||
@@ -969,7 +969,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,
|
||||
/* symbols in data sections that may refer to any init/exit sections */
|
||||
if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&
|
||||
match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) &&
|
||||
match(fromsym, PATTERNS("*_ops", "*_console")))
|
||||
match(fromsym, PATTERNS("*_ops", "*_ops.llvm.*", "*_console")))
|
||||
return 0;
|
||||
|
||||
/* Check for pattern 3 */
|
||||
|
||||
Reference in New Issue
Block a user