Commit 7b95f056 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'kbuild-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kbuild updates from Masahiro Yamada:

 - Use /usr/bin/env for shebang lines in scripts

 - Remove useless -Wnested-externs warning flag

 - Update documents

 - Refactor log handling in modpost

 - Stop building modules without MODULE_LICENSE() tag

 - Make the insane combination of 'static' and EXPORT_SYMBOL an error

 - Improve genksyms to handle _Static_assert()

* tag 'kbuild-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild:
  Documentation/kbuild: Document platform dependency practises
  Documentation/kbuild: Document COMPILE_TEST dependencies
  genksyms: Ignore module scoped _Static_assert()
  modpost: turn static exports into error
  modpost: turn section mismatches to error from fatal()
  modpost: change license incompatibility to error() from fatal()
  modpost: turn missing MODULE_LICENSE() into error
  modpost: refactor error handling and clarify error/fatal difference
  modpost: rename merror() to error()
  kbuild: don't hardcode depmod path
  kbuild: doc: document subdir-y syntax
  kbuild: doc: clarify the difference between extra-y and always-y
  kbuild: doc: split if_changed explanation to a separate section
  kbuild: doc: merge 'Special Rules' and 'Custom kbuild commands' sections
  kbuild: doc: fix 'List directories to visit when descending' section
  kbuild: doc: replace arch/$(ARCH)/ with arch/$(SRCARCH)/
  kbuild: doc: update the description about kbuild Makefiles
  Makefile.extrawarn: remove -Wnested-externs warning
  tweewide: Fix most Shebang lines
parents 1375b980 18084e43
...@@ -553,6 +553,41 @@ with "depends on m". E.g.:: ...@@ -553,6 +553,41 @@ with "depends on m". E.g.::
limits FOO to module (=m) or disabled (=n). limits FOO to module (=m) or disabled (=n).
Compile-testing
~~~~~~~~~~~~~~~
If a config symbol has a dependency, but the code controlled by the config
symbol can still be compiled if the dependency is not met, it is encouraged to
increase build coverage by adding an "|| COMPILE_TEST" clause to the
dependency. This is especially useful for drivers for more exotic hardware, as
it allows continuous-integration systems to compile-test the code on a more
common system, and detect bugs that way.
Note that compile-tested code should avoid crashing when run on a system where
the dependency is not met.
Architecture and platform dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Due to the presence of stubs, most drivers can now be compiled on most
architectures. However, this does not mean it makes sense to have all drivers
available everywhere, as the actual hardware may only exist on specific
architectures and platforms. This is especially true for on-SoC IP cores,
which may be limited to a specific vendor or SoC family.
To prevent asking the user about drivers that cannot be used on the system(s)
the user is compiling a kernel for, and if it makes sense, config symbols
controlling the compilation of a driver should contain proper dependencies,
limiting the visibility of the symbol to (a superset of) the platform(s) the
driver can be used on. The dependency can be an architecture (e.g. ARM) or
platform (e.g. ARCH_OMAP4) dependency. This makes life simpler not only for
distro config owners, but also for every single developer or user who
configures a kernel.
Such a dependency can be relaxed by combining it with the compile-testing rule
above, leading to:
config FOO
bool "Support for foo hardware"
depends on ARCH_FOO_VENDOR || COMPILE_TEST
Kconfig recursive dependency limitations Kconfig recursive dependency limitations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
This diff is collapsed.
...@@ -332,7 +332,7 @@ according to the following rule: ...@@ -332,7 +332,7 @@ according to the following rule:
There are two notable exceptions to this rule: larger There are two notable exceptions to this rule: larger
subsystems have their own directory under include/, such as subsystems have their own directory under include/, such as
include/scsi; and architecture specific headers are located include/scsi; and architecture specific headers are located
under arch/$(ARCH)/include/. under arch/$(SRCARCH)/include/.
4.1 Kernel Includes 4.1 Kernel Includes
------------------- -------------------
......
#!/usr/bin/perl #!/usr/bin/env perl
use strict; use strict;
use Text::Tabs; use Text::Tabs;
use Getopt::Long; use Getopt::Long;
......
#!/usr/bin/python #!/usr/bin/env python
# The TCM v4 multi-protocol fabric module generation script for drivers/target/$NEW_MOD # The TCM v4 multi-protocol fabric module generation script for drivers/target/$NEW_MOD
# #
# Copyright (c) 2010 Rising Tide Systems # Copyright (c) 2010 Rising Tide Systems
......
#!/usr/bin/python #!/usr/bin/env python
# add symbolic names to read_msr / write_msr in trace # add symbolic names to read_msr / write_msr in trace
# decode_msr msr-index.h < trace # decode_msr msr-index.h < trace
import sys import sys
......
#!/usr/bin/perl #!/usr/bin/env perl
# This is a POC (proof of concept or piece of crap, take your pick) for reading the # This is a POC (proof of concept or piece of crap, take your pick) for reading the
# text representation of trace output related to page allocation. It makes an attempt # text representation of trace output related to page allocation. It makes an attempt
# to extract some high-level information on what is going on. The accuracy of the parser # to extract some high-level information on what is going on. The accuracy of the parser
......
#!/usr/bin/perl #!/usr/bin/env perl
# This is a POC for reading the text representation of trace output related to # This is a POC for reading the text representation of trace output related to
# page reclaim. It makes an attempt to extract some high-level information on # page reclaim. It makes an attempt to extract some high-level information on
# what is going on. The accuracy of the parser may vary # what is going on. The accuracy of the parser may vary
......
...@@ -450,7 +450,7 @@ LEX = flex ...@@ -450,7 +450,7 @@ LEX = flex
YACC = bison YACC = bison
AWK = awk AWK = awk
INSTALLKERNEL := installkernel INSTALLKERNEL := installkernel
DEPMOD = /sbin/depmod DEPMOD = depmod
PERL = perl PERL = perl
PYTHON = python PYTHON = python
PYTHON3 = python3 PYTHON3 = python3
......
#!/usr/bin/python #!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# #
# Usage: unwcheck.py FILE # Usage: unwcheck.py FILE
......
...@@ -61,7 +61,6 @@ endif ...@@ -61,7 +61,6 @@ endif
ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),)
KBUILD_CFLAGS += -Wdisabled-optimization KBUILD_CFLAGS += -Wdisabled-optimization
KBUILD_CFLAGS += -Wnested-externs
KBUILD_CFLAGS += -Wshadow KBUILD_CFLAGS += -Wshadow
KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) KBUILD_CFLAGS += $(call cc-option, -Wlogical-op)
KBUILD_CFLAGS += -Wmissing-field-initializers KBUILD_CFLAGS += -Wmissing-field-initializers
......
#!/usr/bin/python #!/usr/bin/env python
# #
# Copyright 2004 Matt Mackall <mpm@selenic.com> # Copyright 2004 Matt Mackall <mpm@selenic.com>
# #
......
#!/bin/bash #!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# Manipulate options in a .config file from the command line # Manipulate options in a .config file from the command line
......
#!/usr/bin/python #!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# #
# diffconfig - a tool to compare .config files. # diffconfig - a tool to compare .config files.
......
...@@ -32,6 +32,9 @@ static struct resword { ...@@ -32,6 +32,9 @@ static struct resword {
{ "restrict", RESTRICT_KEYW }, { "restrict", RESTRICT_KEYW },
{ "asm", ASM_KEYW }, { "asm", ASM_KEYW },
// c11 keywords that can be used at module scope
{ "_Static_assert", STATIC_ASSERT_KEYW },
// attribute commented out in modutils 2.4.2. People are using 'attribute' as a // attribute commented out in modutils 2.4.2. People are using 'attribute' as a
// field name which breaks the genksyms parser. It is not a gcc keyword anyway. // field name which breaks the genksyms parser. It is not a gcc keyword anyway.
// KAO. }, // KAO. },
......
...@@ -118,7 +118,7 @@ yylex(void) ...@@ -118,7 +118,7 @@ yylex(void)
{ {
static enum { static enum {
ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_TYPEOF, ST_TYPEOF_1, ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_TYPEOF, ST_TYPEOF_1,
ST_BRACKET, ST_BRACE, ST_EXPRESSION, ST_BRACKET, ST_BRACE, ST_EXPRESSION, ST_STATIC_ASSERT,
ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
ST_TABLE_5, ST_TABLE_6 ST_TABLE_5, ST_TABLE_6
} lexstate = ST_NOTSTARTED; } lexstate = ST_NOTSTARTED;
...@@ -201,6 +201,11 @@ repeat: ...@@ -201,6 +201,11 @@ repeat:
case EXPORT_SYMBOL_KEYW: case EXPORT_SYMBOL_KEYW:
goto fini; goto fini;
case STATIC_ASSERT_KEYW:
lexstate = ST_STATIC_ASSERT;
count = 0;
goto repeat;
} }
} }
if (!suppress_type_lookup) if (!suppress_type_lookup)
...@@ -401,6 +406,26 @@ repeat: ...@@ -401,6 +406,26 @@ repeat:
} }
break; break;
case ST_STATIC_ASSERT:
APP;
switch (token)
{
case '(':
++count;
goto repeat;
case ')':
if (--count == 0)
{
lexstate = ST_NORMAL;
token = STATIC_ASSERT_PHRASE;
break;
}
goto repeat;
default:
goto repeat;
}
break;
case ST_TABLE_1: case ST_TABLE_1:
goto repeat; goto repeat;
......
...@@ -80,6 +80,7 @@ static void record_compound(struct string_list **keyw, ...@@ -80,6 +80,7 @@ static void record_compound(struct string_list **keyw,
%token SHORT_KEYW %token SHORT_KEYW
%token SIGNED_KEYW %token SIGNED_KEYW
%token STATIC_KEYW %token STATIC_KEYW
%token STATIC_ASSERT_KEYW
%token STRUCT_KEYW %token STRUCT_KEYW
%token TYPEDEF_KEYW %token TYPEDEF_KEYW
%token UNION_KEYW %token UNION_KEYW
...@@ -97,6 +98,7 @@ static void record_compound(struct string_list **keyw, ...@@ -97,6 +98,7 @@ static void record_compound(struct string_list **keyw,
%token BRACE_PHRASE %token BRACE_PHRASE
%token BRACKET_PHRASE %token BRACKET_PHRASE
%token EXPRESSION_PHRASE %token EXPRESSION_PHRASE
%token STATIC_ASSERT_PHRASE
%token CHAR %token CHAR
%token DOTS %token DOTS
...@@ -130,6 +132,7 @@ declaration1: ...@@ -130,6 +132,7 @@ declaration1:
| function_definition | function_definition
| asm_definition | asm_definition
| export_definition | export_definition
| static_assert
| error ';' { $$ = $2; } | error ';' { $$ = $2; }
| error '}' { $$ = $2; } | error '}' { $$ = $2; }
; ;
...@@ -493,6 +496,10 @@ export_definition: ...@@ -493,6 +496,10 @@ export_definition:
{ export_symbol((*$3)->string); $$ = $5; } { export_symbol((*$3)->string); $$ = $5; }
; ;
/* Ignore any module scoped _Static_assert(...) */
static_assert:
STATIC_ASSERT_PHRASE ';' { $$ = $2; }
;
%% %%
......
#!/usr/bin/perl #!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
use strict; use strict;
......
...@@ -34,12 +34,14 @@ static int external_module = 0; ...@@ -34,12 +34,14 @@ static int external_module = 0;
static int warn_unresolved = 0; static int warn_unresolved = 0;
/* How a symbol is exported */ /* How a symbol is exported */
static int sec_mismatch_count = 0; static int sec_mismatch_count = 0;
static int sec_mismatch_fatal = 0; static int sec_mismatch_warn_only = true;
/* ignore missing files */ /* ignore missing files */
static int ignore_missing_files; static int ignore_missing_files;
/* If set to 1, only warn (instead of error) about missing ns imports */ /* If set to 1, only warn (instead of error) about missing ns imports */
static int allow_missing_ns_imports; static int allow_missing_ns_imports;
static bool error_occurred;
enum export { enum export {
export_plain, export_unused, export_gpl, export_plain, export_unused, export_gpl,
export_unused_gpl, export_gpl_future, export_unknown export_unused_gpl, export_gpl_future, export_unknown
...@@ -78,6 +80,8 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...) ...@@ -78,6 +80,8 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...)
if (loglevel == LOG_FATAL) if (loglevel == LOG_FATAL)
exit(1); exit(1);
if (loglevel == LOG_ERROR)
error_occurred = true;
} }
static inline bool strends(const char *str, const char *postfix) static inline bool strends(const char *str, const char *postfix)
...@@ -403,8 +407,8 @@ static void sym_update_namespace(const char *symname, const char *namespace) ...@@ -403,8 +407,8 @@ static void sym_update_namespace(const char *symname, const char *namespace)
* actually an assertion. * actually an assertion.
*/ */
if (!s) { if (!s) {
merror("Could not update namespace(%s) for symbol %s\n", error("Could not update namespace(%s) for symbol %s\n",
namespace, symname); namespace, symname);
return; return;
} }
...@@ -2014,7 +2018,7 @@ static void read_symbols(const char *modname) ...@@ -2014,7 +2018,7 @@ static void read_symbols(const char *modname)
if (!mod->is_vmlinux) { if (!mod->is_vmlinux) {
license = get_modinfo(&info, "license"); license = get_modinfo(&info, "license");
if (!license) if (!license)
warn("missing MODULE_LICENSE() in %s\n", modname); error("missing MODULE_LICENSE() in %s\n", modname);
while (license) { while (license) {
if (license_is_gpl_compatible(license)) if (license_is_gpl_compatible(license))
mod->gpl_compatible = 1; mod->gpl_compatible = 1;
...@@ -2141,11 +2145,11 @@ static void check_for_gpl_usage(enum export exp, const char *m, const char *s) ...@@ -2141,11 +2145,11 @@ static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
{ {
switch (exp) { switch (exp) {
case export_gpl: case export_gpl:
fatal("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n", error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
m, s); m, s);
break; break;
case export_unused_gpl: case export_unused_gpl:
fatal("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n", error("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n",
m, s); m, s);
break; break;
case export_gpl_future: case export_gpl_future:
...@@ -2174,22 +2178,18 @@ static void check_for_unused(enum export exp, const char *m, const char *s) ...@@ -2174,22 +2178,18 @@ static void check_for_unused(enum export exp, const char *m, const char *s)
} }
} }
static int check_exports(struct module *mod) static void check_exports(struct module *mod)
{ {
struct symbol *s, *exp; struct symbol *s, *exp;
int err = 0;
for (s = mod->unres; s; s = s->next) { for (s = mod->unres; s; s = s->next) {
const char *basename; const char *basename;
exp = find_symbol(s->name); exp = find_symbol(s->name);
if (!exp || exp->module == mod) { if (!exp || exp->module == mod) {
if (have_vmlinux && !s->weak) { if (have_vmlinux && !s->weak)
modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR, modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
"\"%s\" [%s.ko] undefined!\n", "\"%s\" [%s.ko] undefined!\n",
s->name, mod->name); s->name, mod->name);
if (!warn_unresolved)
err = 1;
}
continue; continue;
} }
basename = strrchr(mod->name, '/'); basename = strrchr(mod->name, '/');
...@@ -2203,8 +2203,6 @@ static int check_exports(struct module *mod) ...@@ -2203,8 +2203,6 @@ static int check_exports(struct module *mod)
modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR, modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR,
"module %s uses symbol %s from namespace %s, but does not import it.\n", "module %s uses symbol %s from namespace %s, but does not import it.\n",
basename, exp->name, exp->namespace); basename, exp->name, exp->namespace);
if (!allow_missing_ns_imports)
err = 1;
add_namespace(&mod->missing_namespaces, exp->namespace); add_namespace(&mod->missing_namespaces, exp->namespace);
} }
...@@ -2212,11 +2210,9 @@ static int check_exports(struct module *mod) ...@@ -2212,11 +2210,9 @@ static int check_exports(struct module *mod)
check_for_gpl_usage(exp->export, basename, exp->name); check_for_gpl_usage(exp->export, basename, exp->name);
check_for_unused(exp->export, basename, exp->name); check_for_unused(exp->export, basename, exp->name);
} }
return err;
} }
static int check_modname_len(struct module *mod) static void check_modname_len(struct module *mod)
{ {
const char *mod_name; const char *mod_name;
...@@ -2225,12 +2221,8 @@ static int check_modname_len(struct module *mod) ...@@ -2225,12 +2221,8 @@ static int check_modname_len(struct module *mod)
mod_name = mod->name; mod_name = mod->name;
else else
mod_name++; mod_name++;
if (strlen(mod_name) >= MODULE_NAME_LEN) { if (strlen(mod_name) >= MODULE_NAME_LEN)
merror("module name is too long [%s.ko]\n", mod->name); error("module name is too long [%s.ko]\n", mod->name);
return 1;
}
return 0;
} }
/** /**
...@@ -2289,10 +2281,9 @@ static void add_staging_flag(struct buffer *b, const char *name) ...@@ -2289,10 +2281,9 @@ static void add_staging_flag(struct buffer *b, const char *name)
/** /**
* Record CRCs for unresolved symbols * Record CRCs for unresolved symbols
**/ **/
static int add_versions(struct buffer *b, struct module *mod) static void add_versions(struct buffer *b, struct module *mod)
{ {
struct symbol *s, *exp; struct symbol *s, *exp;
int err = 0;
for (s = mod->unres; s; s = s->next) { for (s = mod->unres; s; s = s->next) {
exp = find_symbol(s->name); exp = find_symbol(s->name);
...@@ -2304,7 +2295,7 @@ static int add_versions(struct buffer *b, struct module *mod) ...@@ -2304,7 +2295,7 @@ static int add_versions(struct buffer *b, struct module *mod)
} }
if (!modversions) if (!modversions)
return err; return;
buf_printf(b, "\n"); buf_printf(b, "\n");
buf_printf(b, "static const struct modversion_info ____versions[]\n"); buf_printf(b, "static const struct modversion_info ____versions[]\n");
...@@ -2319,9 +2310,8 @@ static int add_versions(struct buffer *b, struct module *mod) ...@@ -2319,9 +2310,8 @@ static int add_versions(struct buffer *b, struct module *mod)
continue; continue;
} }
if (strlen(s->name) >= MODULE_NAME_LEN) { if (strlen(s->name) >= MODULE_NAME_LEN) {
merror("too long symbol \"%s\" [%s.ko]\n", error("too long symbol \"%s\" [%s.ko]\n",
s->name, mod->name); s->name, mod->name);
err = 1;
break; break;
} }
buf_printf(b, "\t{ %#8x, \"%s\" },\n", buf_printf(b, "\t{ %#8x, \"%s\" },\n",
...@@ -2329,8 +2319,6 @@ static int add_versions(struct buffer *b, struct module *mod) ...@@ -2329,8 +2319,6 @@ static int add_versions(struct buffer *b, struct module *mod)
} }
buf_printf(b, "};\n"); buf_printf(b, "};\n");
return err;
} }
static void add_depends(struct buffer *b, struct module *mod) static void add_depends(struct buffer *b, struct module *mod)
...@@ -2554,7 +2542,6 @@ int main(int argc, char **argv) ...@@ -2554,7 +2542,6 @@ int main(int argc, char **argv)
char *missing_namespace_deps = NULL; char *missing_namespace_deps = NULL;
char *dump_write = NULL, *files_source = NULL; char *dump_write = NULL, *files_source = NULL;
int opt; int opt;
int err;
int n; int n;
struct dump_list *dump_read_start = NULL; struct dump_list *dump_read_start = NULL;
struct dump_list **dump_read_iter = &dump_read_start; struct dump_list **dump_read_iter = &dump_read_start;
...@@ -2589,7 +2576,7 @@ int main(int argc, char **argv) ...@@ -2589,7 +2576,7 @@ int main(int argc, char **argv)
warn_unresolved = 1; warn_unresolved = 1;
break; break;
case 'E': case 'E':
sec_mismatch_fatal = 1; sec_mismatch_warn_only = false;
break; break;
case 'N': case 'N':
allow_missing_ns_imports = 1; allow_missing_ns_imports = 1;
...@@ -2624,8 +2611,6 @@ int main(int argc, char **argv) ...@@ -2624,8 +2611,6 @@ int main(int argc, char **argv)
if (!have_vmlinux) if (!have_vmlinux)
warn("Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.\n"); warn("Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.\n");
err = 0;
for (mod = modules; mod; mod = mod->next) { for (mod = modules; mod; mod = mod->next) {
char fname[PATH_MAX]; char fname[PATH_MAX];
...@@ -2634,14 +2619,14 @@ int main(int argc, char **argv) ...@@ -2634,14 +2619,14 @@ int main(int argc, char **argv)
buf.pos = 0; buf.pos = 0;
err |= check_modname_len(mod); check_modname_len(mod);
err |= check_exports(mod); check_exports(mod);
add_header(&buf, mod); add_header(&buf, mod);
add_intree_flag(&buf, !external_module); add_intree_flag(&buf, !external_module);
add_retpoline(&buf); add_retpoline(&buf);
add_staging_flag(&buf, mod->name); add_staging_flag(&buf, mod->name);
err |= add_versions(&buf, mod); add_versions(&buf, mod);
add_depends(&buf, mod); add_depends(&buf, mod);
add_moddevtable(&buf, mod); add_moddevtable(&buf, mod);
add_srcversion(&buf, mod); add_srcversion(&buf, mod);
...@@ -2655,21 +2640,21 @@ int main(int argc, char **argv) ...@@ -2655,21 +2640,21 @@ int main(int argc, char **argv)
if (dump_write) if (dump_write)
write_dump(dump_write); write_dump(dump_write);
if (sec_mismatch_count && sec_mismatch_fatal) if (sec_mismatch_count && !sec_mismatch_warn_only)
fatal("Section mismatches detected.\n" error("Section mismatches detected.\n"
"Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n"); "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
for (n = 0; n < SYMBOL_HASH_SIZE; n++) { for (n = 0; n < SYMBOL_HASH_SIZE; n++) {
struct symbol *s; struct symbol *s;
for (s = symbolhash[n]; s; s = s->next) { for (s = symbolhash[n]; s; s = s->next) {
if (s->is_static) if (s->is_static)
warn("\"%s\" [%s] is a static %s\n", error("\"%s\" [%s] is a static %s\n",
s->name, s->module->name, s->name, s->module->name,
export_str(s->export)); export_str(s->export));
} }
} }
free(buf.p); free(buf.p);
return err; return error_occurred ? 1 : 0;
} }
...@@ -201,6 +201,19 @@ enum loglevel { ...@@ -201,6 +201,19 @@ enum loglevel {
void modpost_log(enum loglevel loglevel, const char *fmt, ...); void modpost_log(enum loglevel loglevel, const char *fmt, ...);
/*
* warn - show the given message, then let modpost continue running, still
* allowing modpost to exit successfully. This should be used when
* we still allow to generate vmlinux and modules.
*
* error - show the given message, then let modpost continue running, but fail
* in the end. This should be used when we should stop building vmlinux
* or modules, but we can continue running modpost to catch as many
* issues as possible.
*
* fatal - show the given message, and bail out immediately. This should be
* used when there is no point to continue running modpost.
*/
#define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args) #define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args)
#define merror(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args) #define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args)
#define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args) #define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args)
#!/usr/bin/python #!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
# #
# show_deltas: Read list of printk messages instrumented with # show_deltas: Read list of printk messages instrumented with
......
#!/usr/bin/perl #!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
use strict; use strict;
......
#!/usr/bin/perl #!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# #
# Author: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> # Author: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
......
#!/usr/bin/python #!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
""" """
......
#! /usr/bin/python #! /usr/bin/env python
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# -*- python -*- # -*- python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
......
#! /usr/bin/python #! /usr/bin/env python
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
# -*- python -*- # -*- python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
......
#!/usr/bin/python #!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
......
#!/usr/bin/perl #!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
open (IN,"ktest.pl"); open (IN,"ktest.pl");
......
#!/usr/bin/python3 #!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# #
# A thin wrapper on top of the KUnit Kernel # A thin wrapper on top of the KUnit Kernel
......
#!/usr/bin/python3 #!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# #
# A collection of tests for tools/testing/kunit/kunit.py # A collection of tests for tools/testing/kunit/kunit.py
......
#!/usr/bin/python3 #!/usr/bin/env python3
# Copyright (C) 2017 Netronome Systems, Inc. # Copyright (C) 2017 Netronome Systems, Inc.
# Copyright (c) 2019 Mellanox Technologies. All rights reserved # Copyright (c) 2019 Mellanox Technologies. All rights reserved
......
#!/usr/bin/python #!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
import subprocess import subprocess
......
#!/usr/bin/perl #!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# Prefix all lines with "# ", unbuffered. Command being piped in may need # Prefix all lines with "# ", unbuffered. Command being piped in may need
# to have unbuffering forced with "stdbuf -i0 -o0 -e0 $cmd". # to have unbuffering forced with "stdbuf -i0 -o0 -e0 $cmd".
......
#!/usr/bin/python3 #!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
from subprocess import PIPE, Popen from subprocess import PIPE, Popen
......
#!/usr/bin/python3 #!/usr/bin/env python3
""" """
tdc_batch.py - a script to generate TC batch file tdc_batch.py - a script to generate TC batch file
......
#!/usr/bin/python3 #!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
""" """
tdc_multibatch.py - a thin wrapper over tdc_batch.py to generate multiple batch tdc_multibatch.py - a thin wrapper over tdc_batch.py to generate multiple batch
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment