From: Yann E. MORIN" Date: Mon, 9 Apr 2012 18:37:31 +0000 (+0200) Subject: utils/: new directory for kconfig utilities, install them X-Git-Tag: v3.4.0-0~15 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=404a10227cf8f135796e776a8a42582672a2968c;p=kconfig-frontends utils/: new directory for kconfig utilities, install them Create a new directory to store the utilities that deal with kconfig files, .config and .in alike. For now, only the scripts are installed Signed-off-by: "Yann E. MORIN" --- diff --git a/Makefile.am b/Makefile.am index a889ad7..c4a2e19 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,6 @@ ACLOCAL_AMFLAGS = -I scripts/.autostuff/m4 -SUBDIRS = docs libs frontends +if COND_utils + MAYBE_utils = utils +endif +SUBDIRS = docs libs frontends $(MAYBE_utils) EXTRA_DIST = bootstrap diff --git a/configure.ac b/configure.ac index 7f095b4..1d69a8b 100644 --- a/configure.ac +++ b/configure.ac @@ -83,6 +83,13 @@ AC_ARG_ENABLE( [config_prefix=$enableval])]) AC_SUBST([config_prefix], [${config_prefix-CONFIG_}]) +AC_ARG_ENABLE( + [utils], + [AS_HELP_STRING( + [--enable-utils], + [install utilities to manage .config files (default=no)])]) +AC_SUBST([enable_utils], [${enable_utils:-no}]) + #---------------------------------------- # Options to selectively enable/disable frontends # All are selected by default @@ -385,6 +392,9 @@ AM_CONDITIONAL( AM_CONDITIONAL( [COND_images], [test "$need_images" = "yes"]) +AM_CONDITIONAL( + [COND_utils], + [test "$enable_utils" = "yes"]) #---------------------------------------- # Get the version to apply to the parser shared library @@ -407,11 +417,15 @@ AC_CONFIG_FILES([ frontends/nconf/Makefile frontends/gconf/Makefile frontends/qconf/Makefile + utils/Makefile ]) AC_OUTPUT AC_MSG_NOTICE() AC_MSG_NOTICE([Configured with:]) +AS_IF([test "$enable_utils" = "yes"], + [AC_MSG_NOTICE([- install utilities : yes])], + [AC_MSG_NOTICE([- install utilities : no])]) AS_IF([test "$enable_wall" = "yes"], [AC_MSG_NOTICE([- catch all warnings : yes])], [AC_MSG_NOTICE([- catch all warnings : no])]) diff --git a/misc/config b/misc/config deleted file mode 100755 index a7c7c4b..0000000 --- a/misc/config +++ /dev/null @@ -1,156 +0,0 @@ -#!/bin/bash -# Manipulate options in a .config file from the command line - -usage() { - cat >&2 <>"$FN" - fi -} - -if [ "$1" = "--file" ]; then - FN="$2" - if [ "$FN" = "" ] ; then - usage - fi - shift 2 -else - FN=.config -fi - -if [ "$1" = "" ] ; then - usage -fi - -while [ "$1" != "" ] ; do - CMD="$1" - shift - case "$CMD" in - --refresh) - ;; - --*-after) - checkarg "$1" - A=$ARG - checkarg "$2" - B=$ARG - shift 2 - ;; - -*) - checkarg "$1" - shift - ;; - esac - case "$CMD" in - --enable|-e) - set_var "CONFIG_$ARG" "CONFIG_$ARG=y" - ;; - - --disable|-d) - set_var "CONFIG_$ARG" "# CONFIG_$ARG is not set" - ;; - - --module|-m) - set_var "CONFIG_$ARG" "CONFIG_$ARG=m" - ;; - - --set-str) - set_var "CONFIG_$ARG" "CONFIG_$ARG=\"$1\"" - shift - ;; - - --set-val) - set_var "CONFIG_$ARG" "CONFIG_$ARG=$1" - shift - ;; - - --state|-s) - if grep -q "# CONFIG_$ARG is not set" $FN ; then - echo n - else - V="$(grep "^CONFIG_$ARG=" $FN)" - if [ $? != 0 ] ; then - echo undef - else - V="${V/CONFIG_$ARG=/}" - V="${V/\"/}" - echo "$V" - fi - fi - ;; - - --enable-after|-E) - set_var "CONFIG_$B" "CONFIG_$B=y" "CONFIG_$A" - ;; - - --disable-after|-D) - set_var "CONFIG_$B" "# CONFIG_$B is not set" "CONFIG_$A" - ;; - - --module-after|-M) - set_var "CONFIG_$B" "CONFIG_$B=m" "CONFIG_$A" - ;; - - # undocumented because it ignores --file (fixme) - --refresh) - yes "" | make oldconfig - ;; - - *) - usage - ;; - esac -done - diff --git a/misc/diffconfig b/misc/diffconfig deleted file mode 100755 index b91f3e3..0000000 --- a/misc/diffconfig +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/python -# -# diffconfig - a tool to compare .config files. -# -# originally written in 2006 by Matt Mackall -# (at least, this was in his bloatwatch source code) -# last worked on 2008 by Tim Bird -# - -import sys, os - -def usage(): - print """Usage: diffconfig [-h] [-m] [ ] - -Diffconfig is a simple utility for comparing two .config files. -Using standard diff to compare .config files often includes extraneous and -distracting information. This utility produces sorted output with only the -changes in configuration values between the two files. - -Added and removed items are shown with a leading plus or minus, respectively. -Changed items show the old and new values on a single line. - -If -m is specified, then output will be in "merge" style, which has the -changed and new values in kernel config option format. - -If no config files are specified, .config and .config.old are used. - -Example usage: - $ diffconfig .config config-with-some-changes --EXT2_FS_XATTR n --EXT2_FS_XIP n - CRAMFS n -> y - EXT2_FS y -> n - LOG_BUF_SHIFT 14 -> 16 - PRINTK_TIME n -> y -""" - sys.exit(0) - -# returns a dictionary of name/value pairs for config items in the file -def readconfig(config_file): - d = {} - for line in config_file: - line = line[:-1] - if line[:7] == "CONFIG_": - name, val = line[7:].split("=", 1) - d[name] = val - if line[-11:] == " is not set": - d[line[9:-11]] = "n" - return d - -def print_config(op, config, value, new_value): - global merge_style - - if merge_style: - if new_value: - if new_value=="n": - print "# CONFIG_%s is not set" % config - else: - print "CONFIG_%s=%s" % (config, new_value) - else: - if op=="-": - print "-%s %s" % (config, value) - elif op=="+": - print "+%s %s" % (config, new_value) - else: - print " %s %s -> %s" % (config, value, new_value) - -def main(): - global merge_style - - # parse command line args - if ("-h" in sys.argv or "--help" in sys.argv): - usage() - - merge_style = 0 - if "-m" in sys.argv: - merge_style = 1 - sys.argv.remove("-m") - - argc = len(sys.argv) - if not (argc==1 or argc == 3): - print "Error: incorrect number of arguments or unrecognized option" - usage() - - if argc == 1: - # if no filenames given, assume .config and .config.old - build_dir="" - if os.environ.has_key("KBUILD_OUTPUT"): - build_dir = os.environ["KBUILD_OUTPUT"]+"/" - - configa_filename = build_dir + ".config.old" - configb_filename = build_dir + ".config" - else: - configa_filename = sys.argv[1] - configb_filename = sys.argv[2] - - a = readconfig(file(configa_filename)) - b = readconfig(file(configb_filename)) - - # print items in a but not b (accumulate, sort and print) - old = [] - for config in a: - if config not in b: - old.append(config) - old.sort() - for config in old: - print_config("-", config, a[config], None) - del a[config] - - # print items that changed (accumulate, sort, and print) - changed = [] - for config in a: - if a[config] != b[config]: - changed.append(config) - else: - del b[config] - changed.sort() - for config in changed: - print_config("->", config, a[config], b[config]) - del b[config] - - # now print items in b but not in a - # (items from b that were in a were removed above) - new = b.keys() - new.sort() - for config in new: - print_config("+", config, None, b[config]) - -main() diff --git a/misc/kernel2kfrontends.list b/misc/kernel2kfrontends.list deleted file mode 100644 index c735d03..0000000 --- a/misc/kernel2kfrontends.list +++ /dev/null @@ -1,36 +0,0 @@ -scripts/kconfig/conf.c --> frontends/conf/conf.c -scripts/kconfig/gconf.c --> frontends/gconf/gconf.c -scripts/kconfig/gconf.glade --> frontends/gconf/gconf.glade -scripts/kconfig/mconf.c --> frontends/mconf/mconf.c -scripts/kconfig/nconf.c --> frontends/nconf/nconf.c -scripts/kconfig/nconf.gui.c --> frontends/nconf/nconf.gui.c -scripts/kconfig/nconf.h --> frontends/nconf/nconf.h -scripts/kconfig/qconf.cc --> frontends/qconf/qconf.cc -scripts/kconfig/qconf.h --> frontends/qconf/qconf.h -scripts/kconfig/images.c --> libs/images/images.c_orig -scripts/kconfig/lxdialog/BIG.FAT.WARNING --> libs/lxdialog/BIG.FAT.WARNING -scripts/kconfig/lxdialog/checklist.c --> libs/lxdialog/checklist.c -scripts/kconfig/lxdialog/dialog.h --> libs/lxdialog/dialog.h -scripts/kconfig/lxdialog/inputbox.c --> libs/lxdialog/inputbox.c -scripts/kconfig/lxdialog/menubox.c --> libs/lxdialog/menubox.c -scripts/kconfig/lxdialog/textbox.c --> libs/lxdialog/textbox.c -scripts/kconfig/lxdialog/util.c --> libs/lxdialog/util.c -scripts/kconfig/lxdialog/yesno.c --> libs/lxdialog/yesno.c -scripts/kconfig/confdata.c --> libs/parser/confdata.c -scripts/kconfig/expr.c --> libs/parser/expr.c -scripts/kconfig/expr.h --> libs/parser/expr.h -scripts/kconfig/zconf.gperf --> libs/parser/hconf.gperf -scripts/kconfig/zconf.l --> libs/parser/lconf.l -scripts/kconfig/lkc.h --> libs/parser/lkc.h -scripts/kconfig/lkc_proto.h --> libs/parser/lkc_proto.h -scripts/kconfig/menu.c --> libs/parser/menu.c -scripts/kconfig/symbol.c --> libs/parser/symbol.c -scripts/kconfig/util.c --> libs/parser/util.c -scripts/kconfig/zconf.y --> libs/parser/yconf.y -scripts/config --> misc/config -scripts/diffconfig --> misc/diffconfig -scripts/kconfig/kxgettext.c --> misc/kxgettext.c -scripts/kconfig/merge_config.sh --> misc/merge_config.sh -scripts/kconfig/streamline_config.pl --> misc/streamline_config.pl -Documentation/kbuild/kconfig-language.txt --> docs/kconfig-language.txt -Documentation/kbuild/kconfig.txt --> docs/kconfig.txt diff --git a/misc/kxgettext.c b/misc/kxgettext.c deleted file mode 100644 index 2858738..0000000 --- a/misc/kxgettext.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Arnaldo Carvalho de Melo , 2005 - * - * Released under the terms of the GNU GPL v2.0 - */ - -#include -#include - -#include "lkc.h" - -static char *escape(const char* text, char *bf, int len) -{ - char *bfp = bf; - int multiline = strchr(text, '\n') != NULL; - int eol = 0; - int textlen = strlen(text); - - if ((textlen > 0) && (text[textlen-1] == '\n')) - eol = 1; - - *bfp++ = '"'; - --len; - - if (multiline) { - *bfp++ = '"'; - *bfp++ = '\n'; - *bfp++ = '"'; - len -= 3; - } - - while (*text != '\0' && len > 1) { - if (*text == '"') - *bfp++ = '\\'; - else if (*text == '\n') { - *bfp++ = '\\'; - *bfp++ = 'n'; - *bfp++ = '"'; - *bfp++ = '\n'; - *bfp++ = '"'; - len -= 5; - ++text; - goto next; - } - else if (*text == '\\') { - *bfp++ = '\\'; - len--; - } - *bfp++ = *text++; -next: - --len; - } - - if (multiline && eol) - bfp -= 3; - - *bfp++ = '"'; - *bfp = '\0'; - - return bf; -} - -struct file_line { - struct file_line *next; - const char *file; - int lineno; -}; - -static struct file_line *file_line__new(const char *file, int lineno) -{ - struct file_line *self = malloc(sizeof(*self)); - - if (self == NULL) - goto out; - - self->file = file; - self->lineno = lineno; - self->next = NULL; -out: - return self; -} - -struct message { - const char *msg; - const char *option; - struct message *next; - struct file_line *files; -}; - -static struct message *message__list; - -static struct message *message__new(const char *msg, char *option, - const char *file, int lineno) -{ - struct message *self = malloc(sizeof(*self)); - - if (self == NULL) - goto out; - - self->files = file_line__new(file, lineno); - if (self->files == NULL) - goto out_fail; - - self->msg = strdup(msg); - if (self->msg == NULL) - goto out_fail_msg; - - self->option = option; - self->next = NULL; -out: - return self; -out_fail_msg: - free(self->files); -out_fail: - free(self); - self = NULL; - goto out; -} - -static struct message *mesage__find(const char *msg) -{ - struct message *m = message__list; - - while (m != NULL) { - if (strcmp(m->msg, msg) == 0) - break; - m = m->next; - } - - return m; -} - -static int message__add_file_line(struct message *self, const char *file, - int lineno) -{ - int rc = -1; - struct file_line *fl = file_line__new(file, lineno); - - if (fl == NULL) - goto out; - - fl->next = self->files; - self->files = fl; - rc = 0; -out: - return rc; -} - -static int message__add(const char *msg, char *option, const char *file, - int lineno) -{ - int rc = 0; - char bf[16384]; - char *escaped = escape(msg, bf, sizeof(bf)); - struct message *m = mesage__find(escaped); - - if (m != NULL) - rc = message__add_file_line(m, file, lineno); - else { - m = message__new(escaped, option, file, lineno); - - if (m != NULL) { - m->next = message__list; - message__list = m; - } else - rc = -1; - } - return rc; -} - -static void menu_build_message_list(struct menu *menu) -{ - struct menu *child; - - message__add(menu_get_prompt(menu), NULL, - menu->file == NULL ? "Root Menu" : menu->file->name, - menu->lineno); - - if (menu->sym != NULL && menu_has_help(menu)) - message__add(menu_get_help(menu), menu->sym->name, - menu->file == NULL ? "Root Menu" : menu->file->name, - menu->lineno); - - for (child = menu->list; child != NULL; child = child->next) - if (child->prompt != NULL) - menu_build_message_list(child); -} - -static void message__print_file_lineno(struct message *self) -{ - struct file_line *fl = self->files; - - putchar('\n'); - if (self->option != NULL) - printf("# %s:00000\n", self->option); - - printf("#: %s:%d", fl->file, fl->lineno); - fl = fl->next; - - while (fl != NULL) { - printf(", %s:%d", fl->file, fl->lineno); - fl = fl->next; - } - - putchar('\n'); -} - -static void message__print_gettext_msgid_msgstr(struct message *self) -{ - message__print_file_lineno(self); - - printf("msgid %s\n" - "msgstr \"\"\n", self->msg); -} - -static void menu__xgettext(void) -{ - struct message *m = message__list; - - while (m != NULL) { - /* skip empty lines ("") */ - if (strlen(m->msg) > sizeof("\"\"")) - message__print_gettext_msgid_msgstr(m); - m = m->next; - } -} - -int main(int ac, char **av) -{ - conf_parse(av[1]); - - menu_build_message_list(menu_get_root_menu(NULL)); - menu__xgettext(); - return 0; -} diff --git a/misc/merge_config.sh b/misc/merge_config.sh deleted file mode 100755 index 974d5cb..0000000 --- a/misc/merge_config.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/bin/sh -# merge_config.sh - Takes a list of config fragment values, and merges -# them one by one. Provides warnings on overridden values, and specified -# values that did not make it to the resulting .config file (due to missed -# dependencies or config symbol removal). -# -# Portions reused from kconf_check and generate_cfg: -# http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/kconf_check -# http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/generate_cfg -# -# Copyright (c) 2009-2010 Wind River Systems, Inc. -# Copyright 2011 Linaro -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU General Public License for more details. - -clean_up() { - rm -f $TMP_FILE - exit -} -trap clean_up HUP INT TERM - -usage() { - echo "Usage: $0 [OPTIONS] [CONFIG [...]]" - echo " -h display this help text" - echo " -m only merge the fragments, do not execute the make command" - echo " -n use allnoconfig instead of alldefconfig" - echo " -r list redundant entries when merging fragments" -} - -MAKE=true -ALLTARGET=alldefconfig -WARNREDUN=false - -while true; do - case $1 in - "-n") - ALLTARGET=allnoconfig - shift - continue - ;; - "-m") - MAKE=false - shift - continue - ;; - "-h") - usage - exit - ;; - "-r") - WARNREDUN=true - shift - continue - ;; - *) - break - ;; - esac -done - -INITFILE=$1 -shift; - -MERGE_LIST=$* -SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" -TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) - -echo "Using $INITFILE as base" -cat $INITFILE > $TMP_FILE - -# Merge files, printing warnings on overrided values -for MERGE_FILE in $MERGE_LIST ; do - echo "Merging $MERGE_FILE" - CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) - - for CFG in $CFG_LIST ; do - grep -q -w $CFG $TMP_FILE - if [ $? -eq 0 ] ; then - PREV_VAL=$(grep -w $CFG $TMP_FILE) - NEW_VAL=$(grep -w $CFG $MERGE_FILE) - if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then - echo Value of $CFG is redefined by fragment $MERGE_FILE: - echo Previous value: $PREV_VAL - echo New value: $NEW_VAL - echo - elif [ "$WARNREDUN" = "true" ]; then - echo Value of $CFG is redundant by fragment $MERGE_FILE: - fi - sed -i "/$CFG[ =]/d" $TMP_FILE - fi - done - cat $MERGE_FILE >> $TMP_FILE -done - -if [ "$MAKE" = "false" ]; then - cp $TMP_FILE .config - echo "#" - echo "# merged configuration written to .config (needs make)" - echo "#" - clean_up - exit -fi - -# Use the merged file as the starting point for: -# alldefconfig: Fills in any missing symbols with Kconfig default -# allnoconfig: Fills in any missing symbols with # CONFIG_* is not set -make KCONFIG_ALLCONFIG=$TMP_FILE $ALLTARGET - - -# Check all specified config values took (might have missed-dependency issues) -for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do - - REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) - ACTUAL_VAL=$(grep -w -e "$CFG" .config) - if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then - echo "Value requested for $CFG not in final .config" - echo "Requested value: $REQUESTED_VAL" - echo "Actual value: $ACTUAL_VAL" - echo "" - fi -done - -clean_up diff --git a/misc/streamline_config.pl b/misc/streamline_config.pl deleted file mode 100755 index bccf07d..0000000 --- a/misc/streamline_config.pl +++ /dev/null @@ -1,495 +0,0 @@ -#!/usr/bin/perl -w -# -# Copyright 2005-2009 - Steven Rostedt -# Licensed under the terms of the GNU GPL License version 2 -# -# It's simple enough to figure out how this works. -# If not, then you can ask me at stripconfig@goodmis.org -# -# What it does? -# -# If you have installed a Linux kernel from a distribution -# that turns on way too many modules than you need, and -# you only want the modules you use, then this program -# is perfect for you. -# -# It gives you the ability to turn off all the modules that are -# not loaded on your system. -# -# Howto: -# -# 1. Boot up the kernel that you want to stream line the config on. -# 2. Change directory to the directory holding the source of the -# kernel that you just booted. -# 3. Copy the configuraton file to this directory as .config -# 4. Have all your devices that you need modules for connected and -# operational (make sure that their corresponding modules are loaded) -# 5. Run this script redirecting the output to some other file -# like config_strip. -# 6. Back up your old config (if you want too). -# 7. copy the config_strip file to .config -# 8. Run "make oldconfig" -# -# Now your kernel is ready to be built with only the modules that -# are loaded. -# -# Here's what I did with my Debian distribution. -# -# cd /usr/src/linux-2.6.10 -# cp /boot/config-2.6.10-1-686-smp .config -# ~/bin/streamline_config > config_strip -# mv .config config_sav -# mv config_strip .config -# make oldconfig -# -use strict; -use Getopt::Long; - -my $config = ".config"; - -my $uname = `uname -r`; -chomp $uname; - -my @searchconfigs = ( - { - "file" => ".config", - "exec" => "cat", - }, - { - "file" => "/proc/config.gz", - "exec" => "zcat", - }, - { - "file" => "/boot/config-$uname", - "exec" => "cat", - }, - { - "file" => "/boot/vmlinuz-$uname", - "exec" => "scripts/extract-ikconfig", - "test" => "scripts/extract-ikconfig", - }, - { - "file" => "vmlinux", - "exec" => "scripts/extract-ikconfig", - "test" => "scripts/extract-ikconfig", - }, - { - "file" => "/lib/modules/$uname/kernel/kernel/configs.ko", - "exec" => "scripts/extract-ikconfig", - "test" => "scripts/extract-ikconfig", - }, - { - "file" => "kernel/configs.ko", - "exec" => "scripts/extract-ikconfig", - "test" => "scripts/extract-ikconfig", - }, - { - "file" => "kernel/configs.o", - "exec" => "scripts/extract-ikconfig", - "test" => "scripts/extract-ikconfig", - }, -); - -sub find_config { - foreach my $conf (@searchconfigs) { - my $file = $conf->{"file"}; - - next if ( ! -f "$file"); - - if (defined($conf->{"test"})) { - `$conf->{"test"} $conf->{"file"} 2>/dev/null`; - next if ($?); - } - - my $exec = $conf->{"exec"}; - - print STDERR "using config: '$file'\n"; - - open(CIN, "$exec $file |") || die "Failed to run $exec $file"; - return; - } - die "No config file found"; -} - -find_config; - -# Parse options -my $localmodconfig = 0; -my $localyesconfig = 0; - -GetOptions("localmodconfig" => \$localmodconfig, - "localyesconfig" => \$localyesconfig); - -# Get the build source and top level Kconfig file (passed in) -my $ksource = $ARGV[0]; -my $kconfig = $ARGV[1]; -my $lsmod_file = $ENV{'LSMOD'}; - -my @makefiles = `find $ksource -name Makefile 2>/dev/null`; -chomp @makefiles; - -my %depends; -my %selects; -my %prompts; -my %objects; -my $var; -my $iflevel = 0; -my @ifdeps; - -# prevent recursion -my %read_kconfigs; - -sub read_kconfig { - my ($kconfig) = @_; - - my $state = "NONE"; - my $config; - my @kconfigs; - - my $cont = 0; - my $line; - - my $source = "$ksource/$kconfig"; - my $last_source = ""; - - # Check for any environment variables used - while ($source =~ /\$(\w+)/ && $last_source ne $source) { - my $env = $1; - $last_source = $source; - $source =~ s/\$$env/$ENV{$env}/; - } - - open(KIN, "$source") || die "Can't open $kconfig"; - while () { - chomp; - - # Make sure that lines ending with \ continue - if ($cont) { - $_ = $line . " " . $_; - } - - if (s/\\$//) { - $cont = 1; - $line = $_; - next; - } - - $cont = 0; - - # collect any Kconfig sources - if (/^source\s*"(.*)"/) { - $kconfigs[$#kconfigs+1] = $1; - } - - # configs found - if (/^\s*(menu)?config\s+(\S+)\s*$/) { - $state = "NEW"; - $config = $2; - - for (my $i = 0; $i < $iflevel; $i++) { - if ($i) { - $depends{$config} .= " " . $ifdeps[$i]; - } else { - $depends{$config} = $ifdeps[$i]; - } - $state = "DEP"; - } - - # collect the depends for the config - } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { - $state = "DEP"; - $depends{$config} = $1; - } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { - $depends{$config} .= " " . $1; - - # Get the configs that select this config - } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { - if (defined($selects{$1})) { - $selects{$1} .= " " . $config; - } else { - $selects{$1} = $config; - } - - # configs without prompts must be selected - } elsif ($state ne "NONE" && /^\s*tristate\s\S/) { - # note if the config has a prompt - $prompts{$config} = 1; - - # Check for if statements - } elsif (/^if\s+(.*\S)\s*$/) { - my $deps = $1; - # remove beginning and ending non text - $deps =~ s/^[^a-zA-Z0-9_]*//; - $deps =~ s/[^a-zA-Z0-9_]*$//; - - my @deps = split /[^a-zA-Z0-9_]+/, $deps; - - $ifdeps[$iflevel++] = join ':', @deps; - - } elsif (/^endif/) { - - $iflevel-- if ($iflevel); - - # stop on "help" - } elsif (/^\s*help\s*$/) { - $state = "NONE"; - } - } - close(KIN); - - # read in any configs that were found. - foreach $kconfig (@kconfigs) { - if (!defined($read_kconfigs{$kconfig})) { - $read_kconfigs{$kconfig} = 1; - read_kconfig($kconfig); - } - } -} - -if ($kconfig) { - read_kconfig($kconfig); -} - -sub convert_vars { - my ($line, %vars) = @_; - - my $process = ""; - - while ($line =~ s/^(.*?)(\$\((.*?)\))//) { - my $start = $1; - my $variable = $2; - my $var = $3; - - if (defined($vars{$var})) { - $process .= $start . $vars{$var}; - } else { - $process .= $start . $variable; - } - } - - $process .= $line; - - return $process; -} - -# Read all Makefiles to map the configs to the objects -foreach my $makefile (@makefiles) { - - my $line = ""; - my %make_vars; - - open(MIN,$makefile) || die "Can't open $makefile"; - while () { - # if this line ends with a backslash, continue - chomp; - if (/^(.*)\\$/) { - $line .= $1; - next; - } - - $line .= $_; - $_ = $line; - $line = ""; - - my $objs; - - $_ = convert_vars($_, %make_vars); - - # collect objects after obj-$(CONFIG_FOO_BAR) - if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) { - $var = $1; - $objs = $2; - - # check if variables are set - } elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) { - $make_vars{$1} = $2; - } - if (defined($objs)) { - foreach my $obj (split /\s+/,$objs) { - $obj =~ s/-/_/g; - if ($obj =~ /(.*)\.o$/) { - # Objects may be enabled by more than one config. - # Store configs in an array. - my @arr; - - if (defined($objects{$1})) { - @arr = @{$objects{$1}}; - } - - $arr[$#arr+1] = $var; - - # The objects have a hash mapping to a reference - # of an array of configs. - $objects{$1} = \@arr; - } - } - } - } - close(MIN); -} - -my %modules; - -if (defined($lsmod_file)) { - if ( ! -f $lsmod_file) { - if ( -f $ENV{'objtree'}."/".$lsmod_file) { - $lsmod_file = $ENV{'objtree'}."/".$lsmod_file; - } else { - die "$lsmod_file not found"; - } - } - if ( -x $lsmod_file) { - # the file is executable, run it - open(LIN, "$lsmod_file|"); - } else { - # Just read the contents - open(LIN, "$lsmod_file"); - } -} else { - - # see what modules are loaded on this system - my $lsmod; - - foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { - if ( -x "$dir/lsmod" ) { - $lsmod = "$dir/lsmod"; - last; - } -} - if (!defined($lsmod)) { - # try just the path - $lsmod = "lsmod"; - } - - open(LIN,"$lsmod|") || die "Can not call lsmod with $lsmod"; -} - -while () { - next if (/^Module/); # Skip the first line. - if (/^(\S+)/) { - $modules{$1} = 1; - } -} -close (LIN); - -# add to the configs hash all configs that are needed to enable -# a loaded module. -my %configs; -foreach my $module (keys(%modules)) { - if (defined($objects{$module})) { - my @arr = @{$objects{$module}}; - foreach my $conf (@arr) { - $configs{$conf} = $module; - } - } else { - # Most likely, someone has a custom (binary?) module loaded. - print STDERR "$module config not found!!\n"; - } -} - -my $valid = "A-Za-z_0-9"; -my $repeat = 1; - -# -# Note, we do not care about operands (like: &&, ||, !) we want to add any -# config that is in the depend list of another config. This script does -# not enable configs that are not already enabled. If we come across a -# config A that depends on !B, we can still add B to the list of depends -# to keep on. If A was on in the original config, B would not have been -# and B would not be turned on by this script. -# -sub parse_config_dep_select -{ - my ($p) = @_; - - while ($p =~ /[$valid]/) { - - if ($p =~ /^[^$valid]*([$valid]+)/) { - my $conf = "CONFIG_" . $1; - - $p =~ s/^[^$valid]*[$valid]+//; - - if (!defined($configs{$conf})) { - # We must make sure that this config has its - # dependencies met. - $repeat = 1; # do again - $configs{$conf} = 1; - } - } else { - die "this should never happen"; - } - } -} - -while ($repeat) { - $repeat = 0; - - foreach my $config (keys %configs) { - $config =~ s/^CONFIG_//; - - if (defined($depends{$config})) { - # This config has dependencies. Make sure they are also included - parse_config_dep_select $depends{$config}; - } - - if (defined($prompts{$config}) || !defined($selects{$config})) { - next; - } - - # config has no prompt and must be selected. - parse_config_dep_select $selects{$config}; - } -} - -my %setconfigs; - -# Finally, read the .config file and turn off any module enabled that -# we could not find a reason to keep enabled. -while() { - - if (/CONFIG_IKCONFIG/) { - if (/# CONFIG_IKCONFIG is not set/) { - # enable IKCONFIG at least as a module - print "CONFIG_IKCONFIG=m\n"; - # don't ask about PROC - print "# CONFIG_IKCONFIG_PROC is not set\n"; - } else { - print; - } - next; - } - - if (/^(CONFIG.*)=(m|y)/) { - if (defined($configs{$1})) { - if ($localyesconfig) { - $setconfigs{$1} = 'y'; - } else { - $setconfigs{$1} = $2; - } - } elsif ($2 eq "m") { - print "# $1 is not set\n"; - next; - } - } - print; -} -close(CIN); - -# Integrity check, make sure all modules that we want enabled do -# indeed have their configs set. -loop: -foreach my $module (keys(%modules)) { - if (defined($objects{$module})) { - my @arr = @{$objects{$module}}; - foreach my $conf (@arr) { - if (defined($setconfigs{$conf})) { - next loop; - } - } - print STDERR "module $module did not have configs"; - foreach my $conf (@arr) { - print STDERR " " , $conf; - } - print STDERR "\n"; - } -} diff --git a/scripts/kernel2kfrontends.list b/scripts/kernel2kfrontends.list new file mode 100644 index 0000000..44f597a --- /dev/null +++ b/scripts/kernel2kfrontends.list @@ -0,0 +1,36 @@ +scripts/kconfig/conf.c --> frontends/conf/conf.c +scripts/kconfig/gconf.c --> frontends/gconf/gconf.c +scripts/kconfig/gconf.glade --> frontends/gconf/gconf.glade +scripts/kconfig/mconf.c --> frontends/mconf/mconf.c +scripts/kconfig/nconf.c --> frontends/nconf/nconf.c +scripts/kconfig/nconf.gui.c --> frontends/nconf/nconf.gui.c +scripts/kconfig/nconf.h --> frontends/nconf/nconf.h +scripts/kconfig/qconf.cc --> frontends/qconf/qconf.cc +scripts/kconfig/qconf.h --> frontends/qconf/qconf.h +scripts/kconfig/images.c --> libs/images/images.c_orig +scripts/kconfig/lxdialog/BIG.FAT.WARNING --> libs/lxdialog/BIG.FAT.WARNING +scripts/kconfig/lxdialog/checklist.c --> libs/lxdialog/checklist.c +scripts/kconfig/lxdialog/dialog.h --> libs/lxdialog/dialog.h +scripts/kconfig/lxdialog/inputbox.c --> libs/lxdialog/inputbox.c +scripts/kconfig/lxdialog/menubox.c --> libs/lxdialog/menubox.c +scripts/kconfig/lxdialog/textbox.c --> libs/lxdialog/textbox.c +scripts/kconfig/lxdialog/util.c --> libs/lxdialog/util.c +scripts/kconfig/lxdialog/yesno.c --> libs/lxdialog/yesno.c +scripts/kconfig/confdata.c --> libs/parser/confdata.c +scripts/kconfig/expr.c --> libs/parser/expr.c +scripts/kconfig/expr.h --> libs/parser/expr.h +scripts/kconfig/zconf.gperf --> libs/parser/hconf.gperf +scripts/kconfig/zconf.l --> libs/parser/lconf.l +scripts/kconfig/lkc.h --> libs/parser/lkc.h +scripts/kconfig/lkc_proto.h --> libs/parser/lkc_proto.h +scripts/kconfig/menu.c --> libs/parser/menu.c +scripts/kconfig/symbol.c --> libs/parser/symbol.c +scripts/kconfig/util.c --> libs/parser/util.c +scripts/kconfig/zconf.y --> libs/parser/yconf.y +scripts/config --> utils/kconfig-tweak +scripts/diffconfig --> utils/kconfig-diff +scripts/kconfig/merge_config.sh --> utils/kconfig-merge +scripts/kconfig/streamline_config.pl --> utils/kconfig-streamline +scripts/kconfig/kxgettext.c --> utils/kconfig-gettext.c +Documentation/kbuild/kconfig-language.txt --> docs/kconfig-language.txt +Documentation/kbuild/kconfig.txt --> docs/kconfig.txt diff --git a/scripts/ksync.sh b/scripts/ksync.sh index e45b38e..74aad8c 100755 --- a/scripts/ksync.sh +++ b/scripts/ksync.sh @@ -37,7 +37,7 @@ printf "%d.%d.%d%s %s %s\n%s\n" \ "${kf_version}" \ >.version -exec ] + +Diffconfig is a simple utility for comparing two .config files. +Using standard diff to compare .config files often includes extraneous and +distracting information. This utility produces sorted output with only the +changes in configuration values between the two files. + +Added and removed items are shown with a leading plus or minus, respectively. +Changed items show the old and new values on a single line. + +If -m is specified, then output will be in "merge" style, which has the +changed and new values in kernel config option format. + +If no config files are specified, .config and .config.old are used. + +Example usage: + $ diffconfig .config config-with-some-changes +-EXT2_FS_XATTR n +-EXT2_FS_XIP n + CRAMFS n -> y + EXT2_FS y -> n + LOG_BUF_SHIFT 14 -> 16 + PRINTK_TIME n -> y +""" + sys.exit(0) + +# returns a dictionary of name/value pairs for config items in the file +def readconfig(config_file): + d = {} + for line in config_file: + line = line[:-1] + if line[:7] == "CONFIG_": + name, val = line[7:].split("=", 1) + d[name] = val + if line[-11:] == " is not set": + d[line[9:-11]] = "n" + return d + +def print_config(op, config, value, new_value): + global merge_style + + if merge_style: + if new_value: + if new_value=="n": + print "# CONFIG_%s is not set" % config + else: + print "CONFIG_%s=%s" % (config, new_value) + else: + if op=="-": + print "-%s %s" % (config, value) + elif op=="+": + print "+%s %s" % (config, new_value) + else: + print " %s %s -> %s" % (config, value, new_value) + +def main(): + global merge_style + + # parse command line args + if ("-h" in sys.argv or "--help" in sys.argv): + usage() + + merge_style = 0 + if "-m" in sys.argv: + merge_style = 1 + sys.argv.remove("-m") + + argc = len(sys.argv) + if not (argc==1 or argc == 3): + print "Error: incorrect number of arguments or unrecognized option" + usage() + + if argc == 1: + # if no filenames given, assume .config and .config.old + build_dir="" + if os.environ.has_key("KBUILD_OUTPUT"): + build_dir = os.environ["KBUILD_OUTPUT"]+"/" + + configa_filename = build_dir + ".config.old" + configb_filename = build_dir + ".config" + else: + configa_filename = sys.argv[1] + configb_filename = sys.argv[2] + + a = readconfig(file(configa_filename)) + b = readconfig(file(configb_filename)) + + # print items in a but not b (accumulate, sort and print) + old = [] + for config in a: + if config not in b: + old.append(config) + old.sort() + for config in old: + print_config("-", config, a[config], None) + del a[config] + + # print items that changed (accumulate, sort, and print) + changed = [] + for config in a: + if a[config] != b[config]: + changed.append(config) + else: + del b[config] + changed.sort() + for config in changed: + print_config("->", config, a[config], b[config]) + del b[config] + + # now print items in b but not in a + # (items from b that were in a were removed above) + new = b.keys() + new.sort() + for config in new: + print_config("+", config, None, b[config]) + +main() diff --git a/utils/kconfig-gettext.c b/utils/kconfig-gettext.c new file mode 100644 index 0000000..2858738 --- /dev/null +++ b/utils/kconfig-gettext.c @@ -0,0 +1,235 @@ +/* + * Arnaldo Carvalho de Melo , 2005 + * + * Released under the terms of the GNU GPL v2.0 + */ + +#include +#include + +#include "lkc.h" + +static char *escape(const char* text, char *bf, int len) +{ + char *bfp = bf; + int multiline = strchr(text, '\n') != NULL; + int eol = 0; + int textlen = strlen(text); + + if ((textlen > 0) && (text[textlen-1] == '\n')) + eol = 1; + + *bfp++ = '"'; + --len; + + if (multiline) { + *bfp++ = '"'; + *bfp++ = '\n'; + *bfp++ = '"'; + len -= 3; + } + + while (*text != '\0' && len > 1) { + if (*text == '"') + *bfp++ = '\\'; + else if (*text == '\n') { + *bfp++ = '\\'; + *bfp++ = 'n'; + *bfp++ = '"'; + *bfp++ = '\n'; + *bfp++ = '"'; + len -= 5; + ++text; + goto next; + } + else if (*text == '\\') { + *bfp++ = '\\'; + len--; + } + *bfp++ = *text++; +next: + --len; + } + + if (multiline && eol) + bfp -= 3; + + *bfp++ = '"'; + *bfp = '\0'; + + return bf; +} + +struct file_line { + struct file_line *next; + const char *file; + int lineno; +}; + +static struct file_line *file_line__new(const char *file, int lineno) +{ + struct file_line *self = malloc(sizeof(*self)); + + if (self == NULL) + goto out; + + self->file = file; + self->lineno = lineno; + self->next = NULL; +out: + return self; +} + +struct message { + const char *msg; + const char *option; + struct message *next; + struct file_line *files; +}; + +static struct message *message__list; + +static struct message *message__new(const char *msg, char *option, + const char *file, int lineno) +{ + struct message *self = malloc(sizeof(*self)); + + if (self == NULL) + goto out; + + self->files = file_line__new(file, lineno); + if (self->files == NULL) + goto out_fail; + + self->msg = strdup(msg); + if (self->msg == NULL) + goto out_fail_msg; + + self->option = option; + self->next = NULL; +out: + return self; +out_fail_msg: + free(self->files); +out_fail: + free(self); + self = NULL; + goto out; +} + +static struct message *mesage__find(const char *msg) +{ + struct message *m = message__list; + + while (m != NULL) { + if (strcmp(m->msg, msg) == 0) + break; + m = m->next; + } + + return m; +} + +static int message__add_file_line(struct message *self, const char *file, + int lineno) +{ + int rc = -1; + struct file_line *fl = file_line__new(file, lineno); + + if (fl == NULL) + goto out; + + fl->next = self->files; + self->files = fl; + rc = 0; +out: + return rc; +} + +static int message__add(const char *msg, char *option, const char *file, + int lineno) +{ + int rc = 0; + char bf[16384]; + char *escaped = escape(msg, bf, sizeof(bf)); + struct message *m = mesage__find(escaped); + + if (m != NULL) + rc = message__add_file_line(m, file, lineno); + else { + m = message__new(escaped, option, file, lineno); + + if (m != NULL) { + m->next = message__list; + message__list = m; + } else + rc = -1; + } + return rc; +} + +static void menu_build_message_list(struct menu *menu) +{ + struct menu *child; + + message__add(menu_get_prompt(menu), NULL, + menu->file == NULL ? "Root Menu" : menu->file->name, + menu->lineno); + + if (menu->sym != NULL && menu_has_help(menu)) + message__add(menu_get_help(menu), menu->sym->name, + menu->file == NULL ? "Root Menu" : menu->file->name, + menu->lineno); + + for (child = menu->list; child != NULL; child = child->next) + if (child->prompt != NULL) + menu_build_message_list(child); +} + +static void message__print_file_lineno(struct message *self) +{ + struct file_line *fl = self->files; + + putchar('\n'); + if (self->option != NULL) + printf("# %s:00000\n", self->option); + + printf("#: %s:%d", fl->file, fl->lineno); + fl = fl->next; + + while (fl != NULL) { + printf(", %s:%d", fl->file, fl->lineno); + fl = fl->next; + } + + putchar('\n'); +} + +static void message__print_gettext_msgid_msgstr(struct message *self) +{ + message__print_file_lineno(self); + + printf("msgid %s\n" + "msgstr \"\"\n", self->msg); +} + +static void menu__xgettext(void) +{ + struct message *m = message__list; + + while (m != NULL) { + /* skip empty lines ("") */ + if (strlen(m->msg) > sizeof("\"\"")) + message__print_gettext_msgid_msgstr(m); + m = m->next; + } +} + +int main(int ac, char **av) +{ + conf_parse(av[1]); + + menu_build_message_list(menu_get_root_menu(NULL)); + menu__xgettext(); + return 0; +} diff --git a/utils/kconfig-merge b/utils/kconfig-merge new file mode 100755 index 0000000..974d5cb --- /dev/null +++ b/utils/kconfig-merge @@ -0,0 +1,130 @@ +#!/bin/sh +# merge_config.sh - Takes a list of config fragment values, and merges +# them one by one. Provides warnings on overridden values, and specified +# values that did not make it to the resulting .config file (due to missed +# dependencies or config symbol removal). +# +# Portions reused from kconf_check and generate_cfg: +# http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/kconf_check +# http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/generate_cfg +# +# Copyright (c) 2009-2010 Wind River Systems, Inc. +# Copyright 2011 Linaro +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. + +clean_up() { + rm -f $TMP_FILE + exit +} +trap clean_up HUP INT TERM + +usage() { + echo "Usage: $0 [OPTIONS] [CONFIG [...]]" + echo " -h display this help text" + echo " -m only merge the fragments, do not execute the make command" + echo " -n use allnoconfig instead of alldefconfig" + echo " -r list redundant entries when merging fragments" +} + +MAKE=true +ALLTARGET=alldefconfig +WARNREDUN=false + +while true; do + case $1 in + "-n") + ALLTARGET=allnoconfig + shift + continue + ;; + "-m") + MAKE=false + shift + continue + ;; + "-h") + usage + exit + ;; + "-r") + WARNREDUN=true + shift + continue + ;; + *) + break + ;; + esac +done + +INITFILE=$1 +shift; + +MERGE_LIST=$* +SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" +TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) + +echo "Using $INITFILE as base" +cat $INITFILE > $TMP_FILE + +# Merge files, printing warnings on overrided values +for MERGE_FILE in $MERGE_LIST ; do + echo "Merging $MERGE_FILE" + CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) + + for CFG in $CFG_LIST ; do + grep -q -w $CFG $TMP_FILE + if [ $? -eq 0 ] ; then + PREV_VAL=$(grep -w $CFG $TMP_FILE) + NEW_VAL=$(grep -w $CFG $MERGE_FILE) + if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then + echo Value of $CFG is redefined by fragment $MERGE_FILE: + echo Previous value: $PREV_VAL + echo New value: $NEW_VAL + echo + elif [ "$WARNREDUN" = "true" ]; then + echo Value of $CFG is redundant by fragment $MERGE_FILE: + fi + sed -i "/$CFG[ =]/d" $TMP_FILE + fi + done + cat $MERGE_FILE >> $TMP_FILE +done + +if [ "$MAKE" = "false" ]; then + cp $TMP_FILE .config + echo "#" + echo "# merged configuration written to .config (needs make)" + echo "#" + clean_up + exit +fi + +# Use the merged file as the starting point for: +# alldefconfig: Fills in any missing symbols with Kconfig default +# allnoconfig: Fills in any missing symbols with # CONFIG_* is not set +make KCONFIG_ALLCONFIG=$TMP_FILE $ALLTARGET + + +# Check all specified config values took (might have missed-dependency issues) +for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do + + REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) + ACTUAL_VAL=$(grep -w -e "$CFG" .config) + if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then + echo "Value requested for $CFG not in final .config" + echo "Requested value: $REQUESTED_VAL" + echo "Actual value: $ACTUAL_VAL" + echo "" + fi +done + +clean_up diff --git a/utils/kconfig-streamline b/utils/kconfig-streamline new file mode 100755 index 0000000..bccf07d --- /dev/null +++ b/utils/kconfig-streamline @@ -0,0 +1,495 @@ +#!/usr/bin/perl -w +# +# Copyright 2005-2009 - Steven Rostedt +# Licensed under the terms of the GNU GPL License version 2 +# +# It's simple enough to figure out how this works. +# If not, then you can ask me at stripconfig@goodmis.org +# +# What it does? +# +# If you have installed a Linux kernel from a distribution +# that turns on way too many modules than you need, and +# you only want the modules you use, then this program +# is perfect for you. +# +# It gives you the ability to turn off all the modules that are +# not loaded on your system. +# +# Howto: +# +# 1. Boot up the kernel that you want to stream line the config on. +# 2. Change directory to the directory holding the source of the +# kernel that you just booted. +# 3. Copy the configuraton file to this directory as .config +# 4. Have all your devices that you need modules for connected and +# operational (make sure that their corresponding modules are loaded) +# 5. Run this script redirecting the output to some other file +# like config_strip. +# 6. Back up your old config (if you want too). +# 7. copy the config_strip file to .config +# 8. Run "make oldconfig" +# +# Now your kernel is ready to be built with only the modules that +# are loaded. +# +# Here's what I did with my Debian distribution. +# +# cd /usr/src/linux-2.6.10 +# cp /boot/config-2.6.10-1-686-smp .config +# ~/bin/streamline_config > config_strip +# mv .config config_sav +# mv config_strip .config +# make oldconfig +# +use strict; +use Getopt::Long; + +my $config = ".config"; + +my $uname = `uname -r`; +chomp $uname; + +my @searchconfigs = ( + { + "file" => ".config", + "exec" => "cat", + }, + { + "file" => "/proc/config.gz", + "exec" => "zcat", + }, + { + "file" => "/boot/config-$uname", + "exec" => "cat", + }, + { + "file" => "/boot/vmlinuz-$uname", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "vmlinux", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "/lib/modules/$uname/kernel/kernel/configs.ko", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "kernel/configs.ko", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "kernel/configs.o", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, +); + +sub find_config { + foreach my $conf (@searchconfigs) { + my $file = $conf->{"file"}; + + next if ( ! -f "$file"); + + if (defined($conf->{"test"})) { + `$conf->{"test"} $conf->{"file"} 2>/dev/null`; + next if ($?); + } + + my $exec = $conf->{"exec"}; + + print STDERR "using config: '$file'\n"; + + open(CIN, "$exec $file |") || die "Failed to run $exec $file"; + return; + } + die "No config file found"; +} + +find_config; + +# Parse options +my $localmodconfig = 0; +my $localyesconfig = 0; + +GetOptions("localmodconfig" => \$localmodconfig, + "localyesconfig" => \$localyesconfig); + +# Get the build source and top level Kconfig file (passed in) +my $ksource = $ARGV[0]; +my $kconfig = $ARGV[1]; +my $lsmod_file = $ENV{'LSMOD'}; + +my @makefiles = `find $ksource -name Makefile 2>/dev/null`; +chomp @makefiles; + +my %depends; +my %selects; +my %prompts; +my %objects; +my $var; +my $iflevel = 0; +my @ifdeps; + +# prevent recursion +my %read_kconfigs; + +sub read_kconfig { + my ($kconfig) = @_; + + my $state = "NONE"; + my $config; + my @kconfigs; + + my $cont = 0; + my $line; + + my $source = "$ksource/$kconfig"; + my $last_source = ""; + + # Check for any environment variables used + while ($source =~ /\$(\w+)/ && $last_source ne $source) { + my $env = $1; + $last_source = $source; + $source =~ s/\$$env/$ENV{$env}/; + } + + open(KIN, "$source") || die "Can't open $kconfig"; + while () { + chomp; + + # Make sure that lines ending with \ continue + if ($cont) { + $_ = $line . " " . $_; + } + + if (s/\\$//) { + $cont = 1; + $line = $_; + next; + } + + $cont = 0; + + # collect any Kconfig sources + if (/^source\s*"(.*)"/) { + $kconfigs[$#kconfigs+1] = $1; + } + + # configs found + if (/^\s*(menu)?config\s+(\S+)\s*$/) { + $state = "NEW"; + $config = $2; + + for (my $i = 0; $i < $iflevel; $i++) { + if ($i) { + $depends{$config} .= " " . $ifdeps[$i]; + } else { + $depends{$config} = $ifdeps[$i]; + } + $state = "DEP"; + } + + # collect the depends for the config + } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { + $state = "DEP"; + $depends{$config} = $1; + } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { + $depends{$config} .= " " . $1; + + # Get the configs that select this config + } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { + if (defined($selects{$1})) { + $selects{$1} .= " " . $config; + } else { + $selects{$1} = $config; + } + + # configs without prompts must be selected + } elsif ($state ne "NONE" && /^\s*tristate\s\S/) { + # note if the config has a prompt + $prompts{$config} = 1; + + # Check for if statements + } elsif (/^if\s+(.*\S)\s*$/) { + my $deps = $1; + # remove beginning and ending non text + $deps =~ s/^[^a-zA-Z0-9_]*//; + $deps =~ s/[^a-zA-Z0-9_]*$//; + + my @deps = split /[^a-zA-Z0-9_]+/, $deps; + + $ifdeps[$iflevel++] = join ':', @deps; + + } elsif (/^endif/) { + + $iflevel-- if ($iflevel); + + # stop on "help" + } elsif (/^\s*help\s*$/) { + $state = "NONE"; + } + } + close(KIN); + + # read in any configs that were found. + foreach $kconfig (@kconfigs) { + if (!defined($read_kconfigs{$kconfig})) { + $read_kconfigs{$kconfig} = 1; + read_kconfig($kconfig); + } + } +} + +if ($kconfig) { + read_kconfig($kconfig); +} + +sub convert_vars { + my ($line, %vars) = @_; + + my $process = ""; + + while ($line =~ s/^(.*?)(\$\((.*?)\))//) { + my $start = $1; + my $variable = $2; + my $var = $3; + + if (defined($vars{$var})) { + $process .= $start . $vars{$var}; + } else { + $process .= $start . $variable; + } + } + + $process .= $line; + + return $process; +} + +# Read all Makefiles to map the configs to the objects +foreach my $makefile (@makefiles) { + + my $line = ""; + my %make_vars; + + open(MIN,$makefile) || die "Can't open $makefile"; + while () { + # if this line ends with a backslash, continue + chomp; + if (/^(.*)\\$/) { + $line .= $1; + next; + } + + $line .= $_; + $_ = $line; + $line = ""; + + my $objs; + + $_ = convert_vars($_, %make_vars); + + # collect objects after obj-$(CONFIG_FOO_BAR) + if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) { + $var = $1; + $objs = $2; + + # check if variables are set + } elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) { + $make_vars{$1} = $2; + } + if (defined($objs)) { + foreach my $obj (split /\s+/,$objs) { + $obj =~ s/-/_/g; + if ($obj =~ /(.*)\.o$/) { + # Objects may be enabled by more than one config. + # Store configs in an array. + my @arr; + + if (defined($objects{$1})) { + @arr = @{$objects{$1}}; + } + + $arr[$#arr+1] = $var; + + # The objects have a hash mapping to a reference + # of an array of configs. + $objects{$1} = \@arr; + } + } + } + } + close(MIN); +} + +my %modules; + +if (defined($lsmod_file)) { + if ( ! -f $lsmod_file) { + if ( -f $ENV{'objtree'}."/".$lsmod_file) { + $lsmod_file = $ENV{'objtree'}."/".$lsmod_file; + } else { + die "$lsmod_file not found"; + } + } + if ( -x $lsmod_file) { + # the file is executable, run it + open(LIN, "$lsmod_file|"); + } else { + # Just read the contents + open(LIN, "$lsmod_file"); + } +} else { + + # see what modules are loaded on this system + my $lsmod; + + foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { + if ( -x "$dir/lsmod" ) { + $lsmod = "$dir/lsmod"; + last; + } +} + if (!defined($lsmod)) { + # try just the path + $lsmod = "lsmod"; + } + + open(LIN,"$lsmod|") || die "Can not call lsmod with $lsmod"; +} + +while () { + next if (/^Module/); # Skip the first line. + if (/^(\S+)/) { + $modules{$1} = 1; + } +} +close (LIN); + +# add to the configs hash all configs that are needed to enable +# a loaded module. +my %configs; +foreach my $module (keys(%modules)) { + if (defined($objects{$module})) { + my @arr = @{$objects{$module}}; + foreach my $conf (@arr) { + $configs{$conf} = $module; + } + } else { + # Most likely, someone has a custom (binary?) module loaded. + print STDERR "$module config not found!!\n"; + } +} + +my $valid = "A-Za-z_0-9"; +my $repeat = 1; + +# +# Note, we do not care about operands (like: &&, ||, !) we want to add any +# config that is in the depend list of another config. This script does +# not enable configs that are not already enabled. If we come across a +# config A that depends on !B, we can still add B to the list of depends +# to keep on. If A was on in the original config, B would not have been +# and B would not be turned on by this script. +# +sub parse_config_dep_select +{ + my ($p) = @_; + + while ($p =~ /[$valid]/) { + + if ($p =~ /^[^$valid]*([$valid]+)/) { + my $conf = "CONFIG_" . $1; + + $p =~ s/^[^$valid]*[$valid]+//; + + if (!defined($configs{$conf})) { + # We must make sure that this config has its + # dependencies met. + $repeat = 1; # do again + $configs{$conf} = 1; + } + } else { + die "this should never happen"; + } + } +} + +while ($repeat) { + $repeat = 0; + + foreach my $config (keys %configs) { + $config =~ s/^CONFIG_//; + + if (defined($depends{$config})) { + # This config has dependencies. Make sure they are also included + parse_config_dep_select $depends{$config}; + } + + if (defined($prompts{$config}) || !defined($selects{$config})) { + next; + } + + # config has no prompt and must be selected. + parse_config_dep_select $selects{$config}; + } +} + +my %setconfigs; + +# Finally, read the .config file and turn off any module enabled that +# we could not find a reason to keep enabled. +while() { + + if (/CONFIG_IKCONFIG/) { + if (/# CONFIG_IKCONFIG is not set/) { + # enable IKCONFIG at least as a module + print "CONFIG_IKCONFIG=m\n"; + # don't ask about PROC + print "# CONFIG_IKCONFIG_PROC is not set\n"; + } else { + print; + } + next; + } + + if (/^(CONFIG.*)=(m|y)/) { + if (defined($configs{$1})) { + if ($localyesconfig) { + $setconfigs{$1} = 'y'; + } else { + $setconfigs{$1} = $2; + } + } elsif ($2 eq "m") { + print "# $1 is not set\n"; + next; + } + } + print; +} +close(CIN); + +# Integrity check, make sure all modules that we want enabled do +# indeed have their configs set. +loop: +foreach my $module (keys(%modules)) { + if (defined($objects{$module})) { + my @arr = @{$objects{$module}}; + foreach my $conf (@arr) { + if (defined($setconfigs{$conf})) { + next loop; + } + } + print STDERR "module $module did not have configs"; + foreach my $conf (@arr) { + print STDERR " " , $conf; + } + print STDERR "\n"; + } +} diff --git a/utils/kconfig-tweak b/utils/kconfig-tweak new file mode 100755 index 0000000..a7c7c4b --- /dev/null +++ b/utils/kconfig-tweak @@ -0,0 +1,156 @@ +#!/bin/bash +# Manipulate options in a .config file from the command line + +usage() { + cat >&2 <>"$FN" + fi +} + +if [ "$1" = "--file" ]; then + FN="$2" + if [ "$FN" = "" ] ; then + usage + fi + shift 2 +else + FN=.config +fi + +if [ "$1" = "" ] ; then + usage +fi + +while [ "$1" != "" ] ; do + CMD="$1" + shift + case "$CMD" in + --refresh) + ;; + --*-after) + checkarg "$1" + A=$ARG + checkarg "$2" + B=$ARG + shift 2 + ;; + -*) + checkarg "$1" + shift + ;; + esac + case "$CMD" in + --enable|-e) + set_var "CONFIG_$ARG" "CONFIG_$ARG=y" + ;; + + --disable|-d) + set_var "CONFIG_$ARG" "# CONFIG_$ARG is not set" + ;; + + --module|-m) + set_var "CONFIG_$ARG" "CONFIG_$ARG=m" + ;; + + --set-str) + set_var "CONFIG_$ARG" "CONFIG_$ARG=\"$1\"" + shift + ;; + + --set-val) + set_var "CONFIG_$ARG" "CONFIG_$ARG=$1" + shift + ;; + + --state|-s) + if grep -q "# CONFIG_$ARG is not set" $FN ; then + echo n + else + V="$(grep "^CONFIG_$ARG=" $FN)" + if [ $? != 0 ] ; then + echo undef + else + V="${V/CONFIG_$ARG=/}" + V="${V/\"/}" + echo "$V" + fi + fi + ;; + + --enable-after|-E) + set_var "CONFIG_$B" "CONFIG_$B=y" "CONFIG_$A" + ;; + + --disable-after|-D) + set_var "CONFIG_$B" "# CONFIG_$B is not set" "CONFIG_$A" + ;; + + --module-after|-M) + set_var "CONFIG_$B" "CONFIG_$B=m" "CONFIG_$A" + ;; + + # undocumented because it ignores --file (fixme) + --refresh) + yes "" | make oldconfig + ;; + + *) + usage + ;; + esac +done +