Kconfig updates for v4.19

- show clearer error messages where pkg-config is needed, but not
   installed
 
 - rename SYMBOL_AUTO to SYMBOL_NO_WRITE to reflect its semantics
 
 - create all necessary directories by Kconfig tool itself instead
   of Makefile
 
 - update the .config unconditionally when syncconfig is invoked
 
 - use 'include' directive instead of '-include' where
   include/config/{auto,tristate}.conf is mandatory
 
 - do not try to update the .config when running install targets
 
 - add .DELETE_ON_ERROR to delete partially updated files
 
 - misc cleanups and fixes
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJbdFbBAAoJED2LAQed4NsGJbQP/icdG5Cj8YVuIlqBEe50KkbT
 V0jJdCyxSSUXiuTaGlFJ4RFlcbH9+4JcMdGIHqRrrtW0UpqXNcHgIOjbCaq4zLCw
 oRtva0/VC3KVlNDZR702t58t8os3qS03XuuRd1bBao19Mje7YOtHGrBfaEmZ3TIV
 jn9TX3K8PxPE8NLRuY5P3OT4fEeeUwXbleo5RuReQR8mWY3p6Gf8YjJ/mxDnoSbF
 gnot+ahWKdvJBjAbbTgoFePM7zOp4YA6Z1Nw0OerXKbchLG2D/wyDNbS2AnME3TR
 RSFuEZL3LqkZlVN1q7oQ0kzVuafghcUSx5LiRovejw7ZRemU30ixqSTZ6w6aL3X8
 nvm+arCGPS85v6RiPEnDMI9iXaqA0+yhwdKi3OLhoOEz+Y8G74JkOZErIoVpE2Ok
 wrSrmLzLzx6kcOaL50hhWQ5Jm3SGclFO1+uEcMP2vSRrrUJlkrBRvpLm+BInFVYS
 HnifGBSD73+UIrVmAcEM30YXUX4kFDoLWUd659nop270vr1JZr2/ie+WODH/fsfn
 aSDQq7AUbwybYHcSnzrv/eiZ5xiDBXcfRsvAcjpwzrUzpj6mM95XwBFOk7O/4a5w
 SuXiMSPbf/zemKhVp2wk6/nxS8SI07qEpXYMRcf3JL/kcT0KDg2/sPou//beYC56
 /s3cTXUlMrG7KTTfr0jz
 =/Dow
 -----END PGP SIGNATURE-----

Merge tag 'kconfig-v4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kconfig updates from Masahiro Yamada:

 - show clearer error messages where pkg-config is needed, but not
   installed

 - rename SYMBOL_AUTO to SYMBOL_NO_WRITE to reflect its semantics

 - create all necessary directories by Kconfig tool itself instead of
   Makefile

 - update the .config unconditionally when syncconfig is invoked

 - use 'include' directive instead of '-include' where
   include/config/{auto,tristate}.conf is mandatory

 - do not try to update the .config when running install targets

 - add .DELETE_ON_ERROR to delete partially updated files

 - misc cleanups and fixes

* tag 'kconfig-v4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild:
  kconfig: remove P_ENV property type
  kconfig: remove unused sym_get_env_prop() function
  kconfig: fix the rule of mainmenu_stmt symbol
  init/Kconfig: Use short unix-style option instead of --longname
  Kbuild: Makefile.modbuiltin: include auto.conf and tristate.conf mandatory
  kbuild: remove auto.conf from prerequisite of phony targets
  kbuild: do not update config for 'make kernelrelease'
  kbuild: do not update config when running install targets
  kbuild: add .DELETE_ON_ERROR special target
  kbuild: use 'include' directive to load auto.conf from top Makefile
  kconfig: allow all config targets to write auto.conf if missing
  kconfig: make syncconfig update .config regardless of sym_change_count
  kconfig: create directories needed for syncconfig by itself
  kconfig: remove unneeded directory generation from local*config
  kconfig: split out useful helpers in confdata.c
  kconfig: rename file_write_dep and move it to confdata.c
  kconfig: fix typos in description of "choice" in kconfig-language.txt
  kconfig: handle format string before calling conf_message_callback()
  kconfig: rename SYMBOL_AUTO to SYMBOL_NO_WRITE
  kconfig: check for pkg-config on make {menu,n,g,x}config
This commit is contained in:
Linus Torvalds 2018-08-15 12:50:10 -07:00
commit 01f0e5cded
21 changed files with 227 additions and 146 deletions

View file

@ -400,3 +400,6 @@ endif
endef
#
###############################################################################
# delete partially updated (i.e. corrupted) files on error
.DELETE_ON_ERROR:

View file

@ -8,10 +8,10 @@ src := $(obj)
PHONY := __modbuiltin
__modbuiltin:
-include include/config/auto.conf
include include/config/auto.conf
# tristate.conf sets tristate variables to uppercase 'Y' or 'M'
# That way, we get the list of built-in modules in obj-Y
-include include/config/tristate.conf
include include/config/tristate.conf
include scripts/Kbuild.include

View file

@ -3,8 +3,7 @@
# Kernel configuration targets
# These targets are used from top-level makefile
PHONY += xconfig gconfig menuconfig config syncconfig \
localmodconfig localyesconfig
PHONY += xconfig gconfig menuconfig config localmodconfig localyesconfig
ifdef KBUILD_KCONFIG
Kconfig := $(KBUILD_KCONFIG)
@ -34,14 +33,7 @@ config: $(obj)/conf
nconfig: $(obj)/nconf
$< $(silent) $(Kconfig)
# This has become an internal implementation detail and is now deprecated
# for external use.
syncconfig: $(obj)/conf
$(Q)mkdir -p include/config include/generated
$< $(silent) --$@ $(Kconfig)
localyesconfig localmodconfig: $(obj)/conf
$(Q)mkdir -p include/config include/generated
$(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config
$(Q)if [ -f .config ]; then \
cmp -s .tmp.config .config || \
@ -56,8 +48,12 @@ localyesconfig localmodconfig: $(obj)/conf
$(Q)rm -f .tmp.config
# These targets map 1:1 to the commandline options of 'conf'
#
# Note:
# syncconfig has become an internal implementation detail and is now
# deprecated for external use
simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
alldefconfig randconfig listnewconfig olddefconfig
alldefconfig randconfig listnewconfig olddefconfig syncconfig
PHONY += $(simple-targets)
$(simple-targets): $(obj)/conf
@ -215,6 +211,7 @@ $(obj)/zconf.tab.o: $(obj)/zconf.lex.c
# check if necessary packages are available, and configure build flags
define filechk_conf_cfg
$(CONFIG_SHELL) $(srctree)/scripts/kconfig/check-pkgconfig.sh; \
$(CONFIG_SHELL) $<
endef

View file

@ -0,0 +1,8 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Check for pkg-config presence
if [ -z $(command -v pkg-config) ]; then
echo "'make *config' requires 'pkg-config'. Please install it." 1>&2
exit 1
fi

View file

@ -496,6 +496,7 @@ int main(int ac, char **av)
int opt;
const char *name, *defconfig_file = NULL /* gcc uninit */;
struct stat tmpstat;
int no_conf_write = 0;
tty_stdio = isatty(0) && isatty(1);
@ -633,13 +634,14 @@ int main(int ac, char **av)
}
if (sync_kconfig) {
if (conf_get_changed()) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {
if (conf_get_changed()) {
fprintf(stderr,
"\n*** The configuration requires explicit update.\n\n");
return 1;
}
no_conf_write = 1;
}
}
@ -684,29 +686,32 @@ int main(int ac, char **av)
break;
}
if (sync_kconfig) {
/* syncconfig is used during the build so we shall update autoconf.
* All other commands are only used to generate a config.
*/
if (conf_get_changed() && conf_write(NULL)) {
fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
exit(1);
}
if (conf_write_autoconf()) {
fprintf(stderr, "\n*** Error during update of the configuration.\n\n");
return 1;
}
} else if (input_mode == savedefconfig) {
if (input_mode == savedefconfig) {
if (conf_write_defconfig(defconfig_file)) {
fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
defconfig_file);
return 1;
}
} else if (input_mode != listnewconfig) {
if (conf_write(NULL)) {
if (!no_conf_write && conf_write(NULL)) {
fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
exit(1);
}
/*
* Create auto.conf if it does not exist.
* This prevents GNU Make 4.1 or older from emitting
* "include/config/auto.conf: No such file or directory"
* in the top-level Makefile
*
* syncconfig always creates or updates auto.conf because it is
* used during the build.
*/
if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
fprintf(stderr,
"\n*** Error during sync of the configuration.\n\n");
return 1;
}
}
return 0;
}

View file

@ -16,6 +16,64 @@
#include "lkc.h"
/* return true if 'path' exists, false otherwise */
static bool is_present(const char *path)
{
struct stat st;
return !stat(path, &st);
}
/* return true if 'path' exists and it is a directory, false otherwise */
static bool is_dir(const char *path)
{
struct stat st;
if (stat(path, &st))
return 0;
return S_ISDIR(st.st_mode);
}
/*
* Create the parent directory of the given path.
*
* For example, if 'include/config/auto.conf' is given, create 'include/config'.
*/
static int make_parent_dir(const char *path)
{
char tmp[PATH_MAX + 1];
char *p;
strncpy(tmp, path, sizeof(tmp));
tmp[sizeof(tmp) - 1] = 0;
/* Remove the base name. Just return if nothing is left */
p = strrchr(tmp, '/');
if (!p)
return 0;
*(p + 1) = 0;
/* Just in case it is an absolute path */
p = tmp;
while (*p == '/')
p++;
while ((p = strchr(p, '/'))) {
*p = 0;
/* skip if the directory exists */
if (!is_dir(tmp) && mkdir(tmp, 0755))
return -1;
*p = '/';
while (*p == '/')
p++;
}
return 0;
}
struct conf_printer {
void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
void (*print_comment)(FILE *, const char *, void *);
@ -43,16 +101,16 @@ static void conf_warning(const char *fmt, ...)
conf_warnings++;
}
static void conf_default_message_callback(const char *fmt, va_list ap)
static void conf_default_message_callback(const char *s)
{
printf("#\n# ");
vprintf(fmt, ap);
printf("%s", s);
printf("\n#\n");
}
static void (*conf_message_callback) (const char *fmt, va_list ap) =
static void (*conf_message_callback)(const char *s) =
conf_default_message_callback;
void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
void conf_set_message_callback(void (*fn)(const char *s))
{
conf_message_callback = fn;
}
@ -60,10 +118,15 @@ void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
static void conf_message(const char *fmt, ...)
{
va_list ap;
char buf[4096];
if (!conf_message_callback)
return;
va_start(ap, fmt);
if (conf_message_callback)
conf_message_callback(fmt, ap);
vsnprintf(buf, sizeof(buf), fmt, ap);
conf_message_callback(buf);
va_end(ap);
}
@ -83,7 +146,6 @@ const char *conf_get_autoconfig_name(void)
char *conf_get_default_confname(void)
{
struct stat buf;
static char fullname[PATH_MAX+1];
char *env, *name;
@ -91,7 +153,7 @@ char *conf_get_default_confname(void)
env = getenv(SRCTREE);
if (env) {
sprintf(fullname, "%s/%s", env, name);
if (!stat(fullname, &buf))
if (is_present(fullname))
return fullname;
}
return name;
@ -397,7 +459,7 @@ int conf_read(const char *name)
for_all_symbols(i, sym) {
sym_calc_value(sym);
if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
continue;
if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
/* check that calculated value agrees with saved value */
@ -725,10 +787,9 @@ int conf_write(const char *name)
dirname[0] = 0;
if (name && name[0]) {
struct stat st;
char *slash;
if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
if (is_dir(name)) {
strcpy(dirname, name);
strcat(dirname, "/");
basename = conf_get_configname();
@ -813,26 +874,59 @@ next:
return 0;
}
/* write a dependency file as used by kbuild to track dependencies */
static int conf_write_dep(const char *name)
{
struct file *file;
FILE *out;
if (!name)
name = ".kconfig.d";
out = fopen("..config.tmp", "w");
if (!out)
return 1;
fprintf(out, "deps_config := \\\n");
for (file = file_list; file; file = file->next) {
if (file->next)
fprintf(out, "\t%s \\\n", file->name);
else
fprintf(out, "\t%s\n", file->name);
}
fprintf(out, "\n%s: \\\n"
"\t$(deps_config)\n\n", conf_get_autoconfig_name());
env_write_dep(out, conf_get_autoconfig_name());
fprintf(out, "\n$(deps_config): ;\n");
fclose(out);
if (make_parent_dir(name))
return 1;
rename("..config.tmp", name);
return 0;
}
static int conf_split_config(void)
{
const char *name;
char path[PATH_MAX+1];
char *s, *d, c;
struct symbol *sym;
struct stat sb;
int res, i, fd;
name = conf_get_autoconfig_name();
conf_read_simple(name, S_DEF_AUTO);
sym_calc_value(modules_sym);
if (make_parent_dir("include/config/foo.h"))
return 1;
if (chdir("include/config"))
return 1;
res = 0;
for_all_symbols(i, sym) {
sym_calc_value(sym);
if ((sym->flags & SYMBOL_AUTO) || !sym->name)
if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
continue;
if (sym->flags & SYMBOL_WRITE) {
if (sym->flags & SYMBOL_DEF_AUTO) {
@ -897,19 +991,12 @@ static int conf_split_config(void)
res = 1;
break;
}
/*
* Create directory components,
* unless they exist already.
*/
d = path;
while ((d = strchr(d, '/'))) {
*d = 0;
if (stat(path, &sb) && mkdir(path, 0755)) {
res = 1;
goto out;
}
*d++ = '/';
if (make_parent_dir(path)) {
res = 1;
goto out;
}
/* Try it again. */
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
@ -926,16 +1013,20 @@ out:
return res;
}
int conf_write_autoconf(void)
int conf_write_autoconf(int overwrite)
{
struct symbol *sym;
const char *name;
const char *autoconf_name = conf_get_autoconfig_name();
FILE *out, *tristate, *out_h;
int i;
if (!overwrite && is_present(autoconf_name))
return 0;
sym_clear_all_valid();
file_write_dep("include/config/auto.conf.cmd");
conf_write_dep("include/config/auto.conf.cmd");
if (conf_split_config())
return 1;
@ -982,19 +1073,26 @@ int conf_write_autoconf(void)
name = getenv("KCONFIG_AUTOHEADER");
if (!name)
name = "include/generated/autoconf.h";
if (make_parent_dir(name))
return 1;
if (rename(".tmpconfig.h", name))
return 1;
name = getenv("KCONFIG_TRISTATE");
if (!name)
name = "include/config/tristate.conf";
if (make_parent_dir(name))
return 1;
if (rename(".tmpconfig_tristate", name))
return 1;
name = conf_get_autoconfig_name();
if (make_parent_dir(autoconf_name))
return 1;
/*
* This must be the last step, kbuild has a dependency on auto.conf
* and this marks the successful completion of the previous steps.
*/
if (rename(".tmpconfig", name))
if (rename(".tmpconfig", autoconf_name))
return 1;
return 0;

View file

@ -141,7 +141,7 @@ struct symbol {
#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */
#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */
#define SYMBOL_CHANGED 0x0400 /* ? */
#define SYMBOL_AUTO 0x1000 /* value from environment variable */
#define SYMBOL_NO_WRITE 0x1000 /* Symbol for internal use only; it will not be written */
#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */
#define SYMBOL_WARNED 0x8000 /* warning has been issued */
@ -185,7 +185,6 @@ enum prop_type {
P_SELECT, /* select BAR */
P_IMPLY, /* imply BAR */
P_RANGE, /* range 7..100 (for a symbol) */
P_ENV, /* value from environment variable */
P_SYMBOL, /* where a symbol is defined */
};

View file

@ -101,8 +101,8 @@ const char *dbg_sym_flags(int val)
strcat(buf, "write/");
if (val & SYMBOL_CHANGED)
strcat(buf, "changed/");
if (val & SYMBOL_AUTO)
strcat(buf, "auto/");
if (val & SYMBOL_NO_WRITE)
strcat(buf, "no_write/");
buf[strlen(buf) - 1] = '\0';
@ -525,6 +525,7 @@ void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
{
if (conf_write(NULL))
text_insert_msg("Error", "Unable to save configuration !");
conf_write_autoconf(0);
}

View file

@ -97,7 +97,6 @@ void menu_set_type(int type);
/* util.c */
struct file *file_lookup(const char *name);
int file_write_dep(const char *name);
void *xmalloc(size_t size);
void *xcalloc(size_t nmemb, size_t size);
void *xrealloc(void *p, size_t size);
@ -126,7 +125,6 @@ const char *sym_get_string_default(struct symbol *sym);
struct symbol *sym_check_deps(struct symbol *sym);
struct property *prop_alloc(enum prop_type type, struct symbol *sym);
struct symbol *prop_get_symbol(struct property *prop);
struct property *sym_get_env_prop(struct symbol *sym);
static inline tristate sym_get_tristate_value(struct symbol *sym)
{

View file

@ -7,10 +7,10 @@ int conf_read(const char *name);
int conf_read_simple(const char *name, int);
int conf_write_defconfig(const char *name);
int conf_write(const char *name);
int conf_write_autoconf(void);
int conf_write_autoconf(int overwrite);
bool conf_get_changed(void);
void conf_set_changed_callback(void (*fn)(void));
void conf_set_message_callback(void (*fn)(const char *fmt, va_list ap));
void conf_set_message_callback(void (*fn)(const char *s));
/* menu.c */
extern struct menu rootmenu;

View file

@ -772,16 +772,13 @@ static void show_helptext(const char *title, const char *text)
show_textbox(title, text, 0, 0);
}
static void conf_message_callback(const char *fmt, va_list ap)
static void conf_message_callback(const char *s)
{
char buf[PATH_MAX+1];
vsnprintf(buf, sizeof(buf), fmt, ap);
if (save_and_exit) {
if (!silent)
printf("%s", buf);
printf("%s", s);
} else {
show_textbox(NULL, buf, 6, 60);
show_textbox(NULL, s, 6, 60);
}
}
@ -977,6 +974,7 @@ static int handle_exit(void)
"\n\n");
return 1;
}
conf_write_autoconf(0);
/* fall through */
case -1:
if (!silent)

View file

@ -212,7 +212,7 @@ void menu_add_option(int token, char *arg)
sym_defconfig_list = current_entry->sym;
else if (sym_defconfig_list != current_entry->sym)
zconf_error("trying to redefine defconfig symbol");
sym_defconfig_list->flags |= SYMBOL_AUTO;
sym_defconfig_list->flags |= SYMBOL_NO_WRITE;
break;
case T_OPT_ALLNOCONFIG_Y:
current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;

View file

@ -674,6 +674,7 @@ static int do_exit(void)
"Your configuration changes were NOT saved.",
1,
"<OK>");
conf_write_autoconf(0);
break;
default:
btn_dialog(
@ -1210,12 +1211,9 @@ static void conf(struct menu *menu)
}
}
static void conf_message_callback(const char *fmt, va_list ap)
static void conf_message_callback(const char *s)
{
char buf[1024];
vsnprintf(buf, sizeof(buf), fmt, ap);
btn_dialog(main_window, buf, 1, "<OK>");
btn_dialog(main_window, s, 1, "<OK>");
}
static void show_help(struct menu *menu)

View file

@ -1149,7 +1149,6 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
case P_DEFAULT:
case P_SELECT:
case P_RANGE:
case P_ENV:
debug += prop_get_type_name(prop->type);
debug += ": ";
expr_print(prop->expr, expr_print_help, &debug, E_NONE);
@ -1535,6 +1534,8 @@ bool ConfigMainWindow::saveConfig(void)
QMessageBox::information(this, "qconf", "Unable to save configuration!");
return false;
}
conf_write_autoconf(0);
return true;
}

View file

@ -76,15 +76,6 @@ struct property *sym_get_choice_prop(struct symbol *sym)
return NULL;
}
struct property *sym_get_env_prop(struct symbol *sym)
{
struct property *prop;
for_all_properties(sym, prop, P_ENV)
return prop;
return NULL;
}
static struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
@ -463,7 +454,7 @@ void sym_calc_value(struct symbol *sym)
}
}
if (sym->flags & SYMBOL_AUTO)
if (sym->flags & SYMBOL_NO_WRITE)
sym->flags &= ~SYMBOL_WRITE;
if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
@ -1298,8 +1289,6 @@ const char *prop_get_type_name(enum prop_type type)
switch (type) {
case P_PROMPT:
return "prompt";
case P_ENV:
return "env";
case P_COMMENT:
return "comment";
case P_MENU:

View file

@ -29,36 +29,6 @@ struct file *file_lookup(const char *name)
return file;
}
/* write a dependency file as used by kbuild to track dependencies */
int file_write_dep(const char *name)
{
struct file *file;
FILE *out;
if (!name)
name = ".kconfig.d";
out = fopen("..config.tmp", "w");
if (!out)
return 1;
fprintf(out, "deps_config := \\\n");
for (file = file_list; file; file = file->next) {
if (file->next)
fprintf(out, "\t%s \\\n", file->name);
else
fprintf(out, "\t%s\n", file->name);
}
fprintf(out, "\n%s: \\\n"
"\t$(deps_config)\n\n", conf_get_autoconfig_name());
env_write_dep(out, conf_get_autoconfig_name());
fprintf(out, "\n$(deps_config): ;\n");
fclose(out);
rename("..config.tmp", name);
return 0;
}
/* Allocate initial growable string */
struct gstr str_new(void)
{

View file

@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE];
static struct menu *current_menu, *current_entry;
%}
%expect 31
%expect 30
%union
{
@ -117,7 +117,7 @@ start: mainmenu_stmt stmt_list | stmt_list;
/* mainmenu entry */
mainmenu_stmt: T_MAINMENU prompt nl
mainmenu_stmt: T_MAINMENU prompt T_EOL
{
menu_add_prompt(P_MENU, $2, NULL);
};
@ -265,7 +265,7 @@ symbol_option_arg:
choice: T_CHOICE word_opt T_EOL
{
struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE);
sym->flags |= SYMBOL_AUTO;
sym->flags |= SYMBOL_NO_WRITE;
menu_add_entry(sym);
menu_add_expr(P_CHOICE, NULL, NULL);
free($2);