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

@ -370,7 +370,7 @@ choices:
This defines a choice group and accepts any of the above attributes as This defines a choice group and accepts any of the above attributes as
options. A choice can only be of type bool or tristate. If no type is options. A choice can only be of type bool or tristate. If no type is
specified for a choice, it's type will be determined by the type of specified for a choice, its type will be determined by the type of
the first choice element in the group or remain unknown if none of the the first choice element in the group or remain unknown if none of the
choice elements have a type specified, as well. choice elements have a type specified, as well.
@ -384,7 +384,7 @@ A choice accepts another option "optional", which allows to set the
choice to 'n' and no entry needs to be selected. choice to 'n' and no entry needs to be selected.
If no [symbol] is associated with a choice, then you can not have multiple If no [symbol] is associated with a choice, then you can not have multiple
definitions of that choice. If a [symbol] is associated to the choice, definitions of that choice. If a [symbol] is associated to the choice,
then you may define the same choice (ie. with the same entries) in another then you may define the same choice (i.e. with the same entries) in another
place. place.
comment: comment:

View File

@ -81,6 +81,14 @@ The build system has, as of 4.13, switched to using thin archives (`ar T`)
rather than incremental linking (`ld -r`) for built-in.a intermediate steps. rather than incremental linking (`ld -r`) for built-in.a intermediate steps.
This requires binutils 2.20 or newer. This requires binutils 2.20 or newer.
pkg-config
----------
The build system, as of 4.18, requires pkg-config to check for installed
kconfig tools and to determine flags settings for use in
'make {menu,n,g,x}config'. Previously pkg-config was being used but not
verified or documented.
Flex Flex
---- ----

View File

@ -225,10 +225,13 @@ no-dot-config-targets := $(clean-targets) \
cscope gtags TAGS tags help% %docs check% coccicheck \ cscope gtags TAGS tags help% %docs check% coccicheck \
$(version_h) headers_% archheaders archscripts \ $(version_h) headers_% archheaders archscripts \
%asm-generic kernelversion %src-pkg %asm-generic kernelversion %src-pkg
no-sync-config-targets := $(no-dot-config-targets) install %install \
kernelrelease
config-targets := 0 config-targets := 0
mixed-targets := 0 mixed-targets := 0
dot-config := 1 dot-config := 1
may-sync-config := 1
ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
@ -236,6 +239,16 @@ ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
endif endif
endif endif
ifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),)
ifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),)
may-sync-config := 0
endif
endif
ifneq ($(KBUILD_EXTMOD),)
may-sync-config := 0
endif
ifeq ($(KBUILD_EXTMOD),) ifeq ($(KBUILD_EXTMOD),)
ifneq ($(filter config %config,$(MAKECMDGOALS)),) ifneq ($(filter config %config,$(MAKECMDGOALS)),)
config-targets := 1 config-targets := 1
@ -585,7 +598,7 @@ virt-y := virt/
endif # KBUILD_EXTMOD endif # KBUILD_EXTMOD
ifeq ($(dot-config),1) ifeq ($(dot-config),1)
-include include/config/auto.conf include include/config/auto.conf
endif endif
# The all: target is the default when no target is given on the # The all: target is the default when no target is given on the
@ -607,7 +620,7 @@ ARCH_CFLAGS :=
include arch/$(SRCARCH)/Makefile include arch/$(SRCARCH)/Makefile
ifeq ($(dot-config),1) ifeq ($(dot-config),1)
ifeq ($(KBUILD_EXTMOD),) ifeq ($(may-sync-config),1)
# Read in dependencies to all Kconfig* files, make sure to run syncconfig if # Read in dependencies to all Kconfig* files, make sure to run syncconfig if
# changes are detected. This should be included after arch/$(SRCARCH)/Makefile # changes are detected. This should be included after arch/$(SRCARCH)/Makefile
# because some architectures define CROSS_COMPILE there. # because some architectures define CROSS_COMPILE there.
@ -622,8 +635,9 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
$(Q)$(MAKE) -f $(srctree)/Makefile syncconfig $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig
else else
# external modules needs include/generated/autoconf.h and include/config/auto.conf # External modules and some install targets need include/generated/autoconf.h
# but do not care if they are up-to-date. Use auto.conf to trigger the test # and include/config/auto.conf but do not care if they are up-to-date.
# Use auto.conf to trigger the test
PHONY += include/config/auto.conf PHONY += include/config/auto.conf
include/config/auto.conf: include/config/auto.conf:
@ -635,11 +649,7 @@ include/config/auto.conf:
echo >&2 ; \ echo >&2 ; \
/bin/false) /bin/false)
endif # KBUILD_EXTMOD endif # may-sync-config
else
# Dummy target needed, because used as prerequisite
include/config/auto.conf: ;
endif # $(dot-config) endif # $(dot-config)
KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,) KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)
@ -1035,15 +1045,14 @@ define filechk_kernel.release
endef endef
# Store (new) KERNELRELEASE string in include/config/kernel.release # Store (new) KERNELRELEASE string in include/config/kernel.release
include/config/kernel.release: include/config/auto.conf FORCE include/config/kernel.release: $(srctree)/Makefile FORCE
$(call filechk,kernel.release) $(call filechk,kernel.release)
# Additional helpers built in scripts/ # Additional helpers built in scripts/
# Carefully list dependencies so we do not try to build scripts twice # Carefully list dependencies so we do not try to build scripts twice
# in parallel # in parallel
PHONY += scripts PHONY += scripts
scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \ scripts: scripts_basic asm-generic gcc-plugins $(autoksyms_h)
asm-generic gcc-plugins $(autoksyms_h)
$(Q)$(MAKE) $(build)=$(@) $(Q)$(MAKE) $(build)=$(@)
# Things we need to do before we recursively start building the kernel # Things we need to do before we recursively start building the kernel
@ -1073,8 +1082,7 @@ endif
# that need to depend on updated CONFIG_* values can be checked here. # that need to depend on updated CONFIG_* values can be checked here.
prepare2: prepare3 outputmakefile asm-generic prepare2: prepare3 outputmakefile asm-generic
prepare1: prepare2 $(version_h) $(autoksyms_h) include/generated/utsrelease.h \ prepare1: prepare2 $(version_h) $(autoksyms_h) include/generated/utsrelease.h
include/config/auto.conf
$(cmd_crmodverdir) $(cmd_crmodverdir)
archprepare: archheaders archscripts prepare1 scripts_basic archprepare: archheaders archscripts prepare1 scripts_basic
@ -1212,7 +1220,7 @@ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
modules.builtin: $(vmlinux-dirs:%=%/modules.builtin) modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
$(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin $(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin
%/modules.builtin: include/config/auto.conf %/modules.builtin: include/config/auto.conf include/config/tristate.conf
$(Q)$(MAKE) $(modbuiltin)=$* $(Q)$(MAKE) $(modbuiltin)=$*

View File

@ -2,9 +2,9 @@ config DEFCONFIG_LIST
string string
depends on !UML depends on !UML
option defconfig_list option defconfig_list
default "/lib/modules/$(shell,uname --release)/.config" default "/lib/modules/$(shell,uname -r)/.config"
default "/etc/kernel-config" default "/etc/kernel-config"
default "/boot/config-$(shell,uname --release)" default "/boot/config-$(shell,uname -r)"
default ARCH_DEFCONFIG default ARCH_DEFCONFIG
default "arch/$(ARCH)/defconfig" default "arch/$(ARCH)/defconfig"

View File

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

View File

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

View File

@ -3,8 +3,7 @@
# Kernel configuration targets # Kernel configuration targets
# These targets are used from top-level makefile # These targets are used from top-level makefile
PHONY += xconfig gconfig menuconfig config syncconfig \ PHONY += xconfig gconfig menuconfig config localmodconfig localyesconfig
localmodconfig localyesconfig
ifdef KBUILD_KCONFIG ifdef KBUILD_KCONFIG
Kconfig := $(KBUILD_KCONFIG) Kconfig := $(KBUILD_KCONFIG)
@ -34,14 +33,7 @@ config: $(obj)/conf
nconfig: $(obj)/nconf nconfig: $(obj)/nconf
$< $(silent) $(Kconfig) $< $(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 localyesconfig localmodconfig: $(obj)/conf
$(Q)mkdir -p include/config include/generated
$(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config $(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config
$(Q)if [ -f .config ]; then \ $(Q)if [ -f .config ]; then \
cmp -s .tmp.config .config || \ cmp -s .tmp.config .config || \
@ -56,8 +48,12 @@ localyesconfig localmodconfig: $(obj)/conf
$(Q)rm -f .tmp.config $(Q)rm -f .tmp.config
# These targets map 1:1 to the commandline options of 'conf' # 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 \ simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
alldefconfig randconfig listnewconfig olddefconfig alldefconfig randconfig listnewconfig olddefconfig syncconfig
PHONY += $(simple-targets) PHONY += $(simple-targets)
$(simple-targets): $(obj)/conf $(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 # check if necessary packages are available, and configure build flags
define filechk_conf_cfg define filechk_conf_cfg
$(CONFIG_SHELL) $(srctree)/scripts/kconfig/check-pkgconfig.sh; \
$(CONFIG_SHELL) $< $(CONFIG_SHELL) $<
endef 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; int opt;
const char *name, *defconfig_file = NULL /* gcc uninit */; const char *name, *defconfig_file = NULL /* gcc uninit */;
struct stat tmpstat; struct stat tmpstat;
int no_conf_write = 0;
tty_stdio = isatty(0) && isatty(1); tty_stdio = isatty(0) && isatty(1);
@ -633,13 +634,14 @@ int main(int ac, char **av)
} }
if (sync_kconfig) { if (sync_kconfig) {
if (conf_get_changed()) { name = getenv("KCONFIG_NOSILENTUPDATE");
name = getenv("KCONFIG_NOSILENTUPDATE"); if (name && *name) {
if (name && *name) { if (conf_get_changed()) {
fprintf(stderr, fprintf(stderr,
"\n*** The configuration requires explicit update.\n\n"); "\n*** The configuration requires explicit update.\n\n");
return 1; return 1;
} }
no_conf_write = 1;
} }
} }
@ -684,29 +686,32 @@ int main(int ac, char **av)
break; break;
} }
if (sync_kconfig) { if (input_mode == savedefconfig) {
/* 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 (conf_write_defconfig(defconfig_file)) { if (conf_write_defconfig(defconfig_file)) {
fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n", fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
defconfig_file); defconfig_file);
return 1; return 1;
} }
} else if (input_mode != listnewconfig) { } 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"); fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
exit(1); 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; return 0;
} }

View File

@ -16,6 +16,64 @@
#include "lkc.h" #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 { struct conf_printer {
void (*print_symbol)(FILE *, struct symbol *, const char *, void *); void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
void (*print_comment)(FILE *, const char *, void *); void (*print_comment)(FILE *, const char *, void *);
@ -43,16 +101,16 @@ static void conf_warning(const char *fmt, ...)
conf_warnings++; 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# "); printf("#\n# ");
vprintf(fmt, ap); printf("%s", s);
printf("\n#\n"); 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; 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; 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, ...) static void conf_message(const char *fmt, ...)
{ {
va_list ap; va_list ap;
char buf[4096];
if (!conf_message_callback)
return;
va_start(ap, fmt); 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); va_end(ap);
} }
@ -83,7 +146,6 @@ const char *conf_get_autoconfig_name(void)
char *conf_get_default_confname(void) char *conf_get_default_confname(void)
{ {
struct stat buf;
static char fullname[PATH_MAX+1]; static char fullname[PATH_MAX+1];
char *env, *name; char *env, *name;
@ -91,7 +153,7 @@ char *conf_get_default_confname(void)
env = getenv(SRCTREE); env = getenv(SRCTREE);
if (env) { if (env) {
sprintf(fullname, "%s/%s", env, name); sprintf(fullname, "%s/%s", env, name);
if (!stat(fullname, &buf)) if (is_present(fullname))
return fullname; return fullname;
} }
return name; return name;
@ -397,7 +459,7 @@ int conf_read(const char *name)
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
sym_calc_value(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; continue;
if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
/* check that calculated value agrees with saved value */ /* check that calculated value agrees with saved value */
@ -725,10 +787,9 @@ int conf_write(const char *name)
dirname[0] = 0; dirname[0] = 0;
if (name && name[0]) { if (name && name[0]) {
struct stat st;
char *slash; char *slash;
if (!stat(name, &st) && S_ISDIR(st.st_mode)) { if (is_dir(name)) {
strcpy(dirname, name); strcpy(dirname, name);
strcat(dirname, "/"); strcat(dirname, "/");
basename = conf_get_configname(); basename = conf_get_configname();
@ -813,26 +874,59 @@ int conf_write(const char *name)
return 0; 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) static int conf_split_config(void)
{ {
const char *name; const char *name;
char path[PATH_MAX+1]; char path[PATH_MAX+1];
char *s, *d, c; char *s, *d, c;
struct symbol *sym; struct symbol *sym;
struct stat sb;
int res, i, fd; int res, i, fd;
name = conf_get_autoconfig_name(); name = conf_get_autoconfig_name();
conf_read_simple(name, S_DEF_AUTO); conf_read_simple(name, S_DEF_AUTO);
sym_calc_value(modules_sym); sym_calc_value(modules_sym);
if (make_parent_dir("include/config/foo.h"))
return 1;
if (chdir("include/config")) if (chdir("include/config"))
return 1; return 1;
res = 0; res = 0;
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
sym_calc_value(sym); sym_calc_value(sym);
if ((sym->flags & SYMBOL_AUTO) || !sym->name) if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
continue; continue;
if (sym->flags & SYMBOL_WRITE) { if (sym->flags & SYMBOL_WRITE) {
if (sym->flags & SYMBOL_DEF_AUTO) { if (sym->flags & SYMBOL_DEF_AUTO) {
@ -897,19 +991,12 @@ static int conf_split_config(void)
res = 1; res = 1;
break; break;
} }
/*
* Create directory components, if (make_parent_dir(path)) {
* unless they exist already. res = 1;
*/ goto out;
d = path;
while ((d = strchr(d, '/'))) {
*d = 0;
if (stat(path, &sb) && mkdir(path, 0755)) {
res = 1;
goto out;
}
*d++ = '/';
} }
/* Try it again. */ /* Try it again. */
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) { if (fd == -1) {
@ -926,16 +1013,20 @@ static int conf_split_config(void)
return res; return res;
} }
int conf_write_autoconf(void) int conf_write_autoconf(int overwrite)
{ {
struct symbol *sym; struct symbol *sym;
const char *name; const char *name;
const char *autoconf_name = conf_get_autoconfig_name();
FILE *out, *tristate, *out_h; FILE *out, *tristate, *out_h;
int i; int i;
if (!overwrite && is_present(autoconf_name))
return 0;
sym_clear_all_valid(); sym_clear_all_valid();
file_write_dep("include/config/auto.conf.cmd"); conf_write_dep("include/config/auto.conf.cmd");
if (conf_split_config()) if (conf_split_config())
return 1; return 1;
@ -982,19 +1073,26 @@ int conf_write_autoconf(void)
name = getenv("KCONFIG_AUTOHEADER"); name = getenv("KCONFIG_AUTOHEADER");
if (!name) if (!name)
name = "include/generated/autoconf.h"; name = "include/generated/autoconf.h";
if (make_parent_dir(name))
return 1;
if (rename(".tmpconfig.h", name)) if (rename(".tmpconfig.h", name))
return 1; return 1;
name = getenv("KCONFIG_TRISTATE"); name = getenv("KCONFIG_TRISTATE");
if (!name) if (!name)
name = "include/config/tristate.conf"; name = "include/config/tristate.conf";
if (make_parent_dir(name))
return 1;
if (rename(".tmpconfig_tristate", name)) if (rename(".tmpconfig_tristate", name))
return 1; 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 * This must be the last step, kbuild has a dependency on auto.conf
* and this marks the successful completion of the previous steps. * and this marks the successful completion of the previous steps.
*/ */
if (rename(".tmpconfig", name)) if (rename(".tmpconfig", autoconf_name))
return 1; return 1;
return 0; return 0;

View File

@ -141,7 +141,7 @@ struct symbol {
#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ #define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */
#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ #define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */
#define SYMBOL_CHANGED 0x0400 /* ? */ #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_CHECKED 0x2000 /* used during dependency checking */
#define SYMBOL_WARNED 0x8000 /* warning has been issued */ #define SYMBOL_WARNED 0x8000 /* warning has been issued */
@ -185,7 +185,6 @@ enum prop_type {
P_SELECT, /* select BAR */ P_SELECT, /* select BAR */
P_IMPLY, /* imply BAR */ P_IMPLY, /* imply BAR */
P_RANGE, /* range 7..100 (for a symbol) */ P_RANGE, /* range 7..100 (for a symbol) */
P_ENV, /* value from environment variable */
P_SYMBOL, /* where a symbol is defined */ P_SYMBOL, /* where a symbol is defined */
}; };

View File

@ -101,8 +101,8 @@ const char *dbg_sym_flags(int val)
strcat(buf, "write/"); strcat(buf, "write/");
if (val & SYMBOL_CHANGED) if (val & SYMBOL_CHANGED)
strcat(buf, "changed/"); strcat(buf, "changed/");
if (val & SYMBOL_AUTO) if (val & SYMBOL_NO_WRITE)
strcat(buf, "auto/"); strcat(buf, "no_write/");
buf[strlen(buf) - 1] = '\0'; buf[strlen(buf) - 1] = '\0';
@ -525,6 +525,7 @@ void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
{ {
if (conf_write(NULL)) if (conf_write(NULL))
text_insert_msg("Error", "Unable to save configuration !"); 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 */ /* util.c */
struct file *file_lookup(const char *name); struct file *file_lookup(const char *name);
int file_write_dep(const char *name);
void *xmalloc(size_t size); void *xmalloc(size_t size);
void *xcalloc(size_t nmemb, size_t size); void *xcalloc(size_t nmemb, size_t size);
void *xrealloc(void *p, 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 symbol *sym_check_deps(struct symbol *sym);
struct property *prop_alloc(enum prop_type type, struct symbol *sym); struct property *prop_alloc(enum prop_type type, struct symbol *sym);
struct symbol *prop_get_symbol(struct property *prop); 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) 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_read_simple(const char *name, int);
int conf_write_defconfig(const char *name); int conf_write_defconfig(const char *name);
int conf_write(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); bool conf_get_changed(void);
void conf_set_changed_callback(void (*fn)(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 */ /* menu.c */
extern struct menu rootmenu; 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); 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 (save_and_exit) {
if (!silent) if (!silent)
printf("%s", buf); printf("%s", s);
} else { } else {
show_textbox(NULL, buf, 6, 60); show_textbox(NULL, s, 6, 60);
} }
} }
@ -977,6 +974,7 @@ static int handle_exit(void)
"\n\n"); "\n\n");
return 1; return 1;
} }
conf_write_autoconf(0);
/* fall through */ /* fall through */
case -1: case -1:
if (!silent) if (!silent)

View File

@ -212,7 +212,7 @@ void menu_add_option(int token, char *arg)
sym_defconfig_list = current_entry->sym; sym_defconfig_list = current_entry->sym;
else if (sym_defconfig_list != current_entry->sym) else if (sym_defconfig_list != current_entry->sym)
zconf_error("trying to redefine defconfig symbol"); zconf_error("trying to redefine defconfig symbol");
sym_defconfig_list->flags |= SYMBOL_AUTO; sym_defconfig_list->flags |= SYMBOL_NO_WRITE;
break; break;
case T_OPT_ALLNOCONFIG_Y: case T_OPT_ALLNOCONFIG_Y:
current_entry->sym->flags |= SYMBOL_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.", "Your configuration changes were NOT saved.",
1, 1,
"<OK>"); "<OK>");
conf_write_autoconf(0);
break; break;
default: default:
btn_dialog( 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]; btn_dialog(main_window, s, 1, "<OK>");
vsnprintf(buf, sizeof(buf), fmt, ap);
btn_dialog(main_window, buf, 1, "<OK>");
} }
static void show_help(struct menu *menu) 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_DEFAULT:
case P_SELECT: case P_SELECT:
case P_RANGE: case P_RANGE:
case P_ENV:
debug += prop_get_type_name(prop->type); debug += prop_get_type_name(prop->type);
debug += ": "; debug += ": ";
expr_print(prop->expr, expr_print_help, &debug, E_NONE); 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!"); QMessageBox::information(this, "qconf", "Unable to save configuration!");
return false; return false;
} }
conf_write_autoconf(0);
return true; return true;
} }

View File

@ -76,15 +76,6 @@ struct property *sym_get_choice_prop(struct symbol *sym)
return NULL; 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) static struct property *sym_get_default_prop(struct symbol *sym)
{ {
struct property *prop; 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; sym->flags &= ~SYMBOL_WRITE;
if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
@ -1298,8 +1289,6 @@ const char *prop_get_type_name(enum prop_type type)
switch (type) { switch (type) {
case P_PROMPT: case P_PROMPT:
return "prompt"; return "prompt";
case P_ENV:
return "env";
case P_COMMENT: case P_COMMENT:
return "comment"; return "comment";
case P_MENU: case P_MENU:

View File

@ -29,36 +29,6 @@ struct file *file_lookup(const char *name)
return file; 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 */ /* Allocate initial growable string */
struct gstr str_new(void) struct gstr str_new(void)
{ {

View File

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