Giter Club home page Giter Club logo

kconfiglib's People

Contributors

carlescufi avatar cdornsife avatar dywisor avatar fpemud avatar jsitnicki avatar philipc avatar pinkfluid avatar rfrail3 avatar romavis avatar sebastianboe avatar tgorochowik avatar ulfalizer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kconfiglib's Issues

Defaults are not honored?

Consider the following Kconfig file.
Kconfig.txt

As per https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt,

  • default value: "default" ["if" ]
    A config option can have any number of default values. If multiple
    default values are visible, only the first defined one is active.
    Default values are not limited to the menu entry where they are
    defined. This means the default can be defined somewhere else or be
    overridden by an earlier definition.
    The default value is only assigned to the config symbol if no other
    value was set by the user (via the input prompt above). If an input
    prompt is visible the default value is presented to the user and can
    be overridden by him.
    Optionally, dependencies only for this default value can be added with
    "if"

Now with a .config file such as:
config-orig.txt

running oldconfig, ends up with the following result:
config-gen.txt

menuconfig doesn't aggregate choices with the same symbol name

Example Kconfig:

choice TEST
    prompt "test"

    config A
        bool "A"

    config B
        bool "B"
endchoice

choice TEST
    prompt "more symbols"
    config C
        bool "C"
endchoice

I'm not sure if this is intended behavior or a bug, but oldconfig and menuconfig show the above choices rather differently.

oldconfig aggregates the two choices into a single selection prompt:

$ ~/.local/bin/oldconfig
test (defined at Kconfig:1)
> 1. A (A)
  2. B (B)
  3. C (C)

While menuconfig shows two distinct selection groups:

(top menu)

    test (A)  --->
    more symbols (A)  --->

Note that the "more symbols" choice group doesn't have a symbol named "A", yet its shown above.

kconfig validation

Hello,

Is it possible to use this project for the purpose of validation of option dependencies in linux kernel config? if yes, could you please point to some specific doc/code where I could start. TIA.

A symbol is missing in inherited dependencies

Hi,

The documentation for the referenced field of the Symbol class says that it includes dependencies inherited from surrounding menus and if's.. However when I look at the value of the referenced field for COMEDI_NI_USB6501 (source), I don't see the USB symbol there:

> print(kconf.syms['COMEDI_NI_USB6501'].referenced)
set([<symbol COMEDI_USB_DRIVERS, tristate, "Comedi USB drivers", value m, user value m, visibility m, direct deps m, drivers/staging/comedi/Kconfig:1183>, <symbol COMEDI, tristate, "Data acquisition support (comedi)", value m, user value m, visibility y, direct deps y, drivers/staging/comedi/Kconfig:1>, <symbol STAGING, bool, "Staging drivers", value y, user value y, visibility y, direct deps y, drivers/staging/Kconfig:1>])

COMEDI_NI_USB6501 depends on COMEDI_USB_DRIVERS through an if, and COMEDI_USB_DRIVERS in turns depends on USB through a depends on. So AFAIU USB should be in referenced.

Is this a bug or there's something I misunderstand?

Thanks!

Tentative request: Add themeing support to menuconfig

This is my last request, I promise :)

It would be nice if it was possible to change the color scheme of menuconfig. I'm not exactly sure what would be the best way to do it, but here are a couple options that come to mind:

  • environment variable
  • command line
  • config file
  • comments in the kconfig file

The first 3 are self explanatory. The last option, could be something like Vim modeline that allows settings things like TAB size from the Kconfig file comments, for example:

# $menuconfig: separator=bold_black_on_yellow,standout
# $menuconfig: frame=black_on_yellow,standout;style=black on white;...

config TEST
     bool "A"
...

The above color definition syntax is somewhat loosely resembling python blessings (https://github.com/erikrose/blessings). The definition after "," is the 4th column for _style().

If there's no plans for this whatsoever, please close the issue :)

need a new interface "get_depends_on_symbols"

Hi, I'm continuing my project fpemud-kernelmanager.

Now, I need to get the menuconfig structure, eg:

[fpemud-workstation]# cat /usr/src/linux/fs/ext2/Kconfig
config EXT2_FS
    tristate "Second extended fs support"
      ...
config EXT2_FS_XATTR
    bool "Ext2 extended attributes"
    depends on EXT2_FS
      ...
config EXT2_FS_POSIX_ACL
    bool "Ext2 POSIX Access Control Lists"
    depends on EXT2_FS_XATTR
      ...
config EXT2_FS_SECURITY
    bool "Ext2 Security Labels"
    depends on EXT2_FS_XATTR
      ...
config EXT2_FS_XIP
    bool "Ext2 execute in place support"
    depends on EXT2_FS && MMU
      ...

The corresponding menu structure is:

<M> Second extended fs support
[*]   Ext2 extended attributes
[*]     Ext2 POSIX Access Control Lists
[*]     Ext2 Security Labels
[*]   Ext2 execute in place support

I think I can get the this info by "depends on" expression: symbol is a child if it depends on another symbol above.
Currently, there's only "get_referenced_symbols" & "get_selected_symbols" interface, maybe we should add a new interface "get_depends_on_symbols"?

What do you think? I'm reading the relevant code, any hint on how to implement?

Running script without Makefile patch?

Is it possible to run a script without the Makefile patch? I want to use Kconfiglib to automate some processes on a variety of cross-compiled kernels, so I would prefer to avoid having to patch all of them.

My goal is to be able to figure out all of the Kconfig options that also need to be set in order for some specific option to be set. For example, if I want to set CONFIG_DM_THIN_PROVISIONING, then I want a script that tells me that I also need to set CONFIG_MD and CONFIG_BLK_DEV_DM.

If you can help me figure that out, I will be eternally grateful.

Testsuite error

I'm trying Kconfiglib on 3.2.51.

I'm getting the following output:

Testing tristate comparisons...
Testing string literal (constant symbol) lexing...
Traceback (most recent call last):
File "/home/user/Kconfiglib-master/testsuite.py", line 1992, in
run_tests()
File "/home/user/Kconfiglib-master/testsuite.py", line 81, in run_tests
run_selftests()
File "/home/user/Kconfiglib-master/testsuite.py", line 165, in run_selftests
c = kconfiglib.Config("Kconfiglib/tests/empty")
File "/home/user/Kconfiglib-master/kconfiglib.py", line 214, in init
self.top_block = self._parse_file(filename, None, None, None)
File "/home/user/Kconfiglib-master/kconfiglib.py", line 918, in _parse_file
line_feeder = _FileFeed(_get_lines(filename), filename)
File "/home/user/Kconfiglib-master/kconfiglib.py", line 3700, in _get_lines
with open(filename, "r") as f:
IOError: [Errno 2] No such file or directory: 'Kconfiglib/tests/empty'

Speeding up Kconfig parsing (caching)

Loading Kconfigs took about 4-5s, with this quick & dirty pickle trick I halved that:

import pickle, sys
import kconfiglib

cache_file = 'picked-kconfig'
try:
    conf = pickle.load(open(cache_file, 'rb'))
except:
    sys.setrecursionlimit(100000)
    conf = kconfiglib.Config()
    pickle.dump(conf, open(cache_file, 'wb'))

The resulting "picked-kconfig" is 8.8M for Linux v4.2-rc5. It can probably be further improved by setting appropriate __getstate__ and __setstate__ magic methods, but for me this was already a nice speed boost for testing purposes.

Is this something you have considered before?

Doesn't support help in the menuconfig.

Very useful work for making a cross platform menuconfig.Thanks.
A little issue, when press 'h' key in the menuconfig dialog, there is no help window pop up.
Do you have plan to add this feature?

Can't set value

Hello!
I'm trying to use your lib for modifying some configs. My input data is: Kconfig of Linux 3.14 and allconfig config created by this kernel. When I'm trying to change some values such as AUDIT(from 2 to 0) it doesn't change as well as other parts of config. I tried to go into the code and found out, that AUDIT value is invalidated, but doesn't change after all. It seems like some dependence is blocking it, so is it possible to find out what dependence is blocking set_value() method to change other values?
Also can you explain how your library works with incorrect .config files(incomplete in particular)?

Thanks.

Failure in testsuit, any hint?

I managed to finish the testsuit of kconfiglib, test 2 and test 5 failed.
I think the next step should be doing the failed test manually and inspect the difference in ".confg" and "._config".
is there any better idea?

test log:

fpemud-workstation linux-test # PYTHONPATH=scripts/kconfig python scripts/kconfig/kconfigtest.py
Loading Config instances for all architectures...
Resetting all architecture Config instances prior to next test...
Test if our allnoconfig implementation generates the same .config as 'make allnoconfig', for all architectures
  sh64          OK
  c6x           OK
  arm           OK
  frv           OK
  i386          OK
  x86_64        OK
  cris          OK
  m32r          OK
  ia64          OK
  m68k          OK
  mips          OK
  s390          OK
  tile          OK
  alpha         OK
  avr32         OK
  score         OK
  sparc32       OK
  sparc64       OK
  unicore32     OK
  blackfin      OK
  mn10300       OK
  parisc        OK
  hexagon       OK
  openrisc      OK
  xtensa        OK
  microblaze    OK
  powerpc       OK

Resetting all architecture Config instances prior to next test...
Test if kconfiglib generates the same configuration as 'conf' without a .config, for each architecture
  sh64          FAIL
  c6x           FAIL
  arm           FAIL
  frv           FAIL
  i386          FAIL
  x86_64        FAIL
  cris          FAIL
  m32r          FAIL
  ia64          FAIL
  m68k          FAIL
  mips          FAIL
  s390          FAIL
  tile          FAIL
  alpha         FAIL
  avr32         FAIL
  score         FAIL
  sparc32       FAIL
  sparc64       FAIL
  unicore32     FAIL
  blackfin      FAIL
  mn10300       FAIL
  parisc        FAIL
  hexagon       FAIL
  openrisc      FAIL
  xtensa        FAIL
  microblaze    FAIL
  powerpc       FAIL

Resetting all architecture Config instances prior to next test...
Test if our allyesconfig implementation generates the same .config as 'make allyesconfig', for all architectures
  sh64          OK
  c6x           OK
  arm           OK
  frv           OK
  i386          OK
  x86_64        OK
  cris          OK
  m32r          OK
  ia64          OK
  m68k          OK
  mips          OK
  s390          OK
  tile          OK
  alpha         OK
  avr32         OK
  score         OK
  sparc32       OK
  sparc64       OK
  unicore32     OK
  blackfin      OK
  mn10300       OK
  parisc        OK
  hexagon       OK
  openrisc      OK
  xtensa        OK
  microblaze    OK
  powerpc       OK

Resetting all architecture Config instances prior to next test...
Call all public methods on all symbols, menus, choices and comments (nearly all public methods: some are hard to test like this, but are exercised by other tests) for all architectures to make sure we never crash or hang
  For sh64...
  For c6x...
  For arm...
  For frv...
  For i386...
  For x86_64...
  For cris...
  For m32r...
  For ia64...
  For m68k...
  For mips...
  For s390...
  For tile...
  For alpha...
  For avr32...
  For score...
  For sparc32...
  For sparc64...
  For unicore32...
  For blackfin...
  For mn10300...
  For parisc...
  For hexagon...
  For openrisc...
  For xtensa...
  For microblaze...
  For powerpc...

Resetting all architecture Config instances prior to next test...
Test if kconfiglib generates the same .config as conf for each architecture/defconfig pair (this takes two hours on a Core [email protected] GHz system)
  sh64          with arch/sh/configs/ecovec24-romimage_defconfig                  FAIL
  sh64          with arch/sh/configs/se7721_defconfig                             FAIL
  sh64          with arch/sh/configs/ecovec24_defconfig                           FAIL
...
  x86_64        with arch/sh/configs/ecovec24-romimage_defconfig                  FAIL
  x86_64        with arch/sh/configs/se7721_defconfig                             FAIL
  x86_64        with arch/sh/configs/ecovec24_defconfig                           FAIL
...

Support new 'imply' keyword

With the v4.10 Linux Kernel (and commit 237e3ad0f195d8fd34f1299e45f04793832a16fc) a new "imply" keyword has been added. Quoting from the commit message:

The "imply" keyword is a weak version of "select" where the target
config symbol can still be turned off, avoiding those pitfalls that come
with the "select" keyword.

This is useful e.g. with multiple drivers that want to indicate their
ability to hook into a secondary subsystem while allowing the user to
configure that subsystem out without also having to unset these drivers.

Dependencies for choice symbols

Hi!

I think it will be very handful to parse dependencies not only from enclosing menus and ifs, but for choice options from their parents too. For example:

choice CHOICE
        default SYMBOL1
	prompt "CHOICE"

config SYMBOL1
	default n
	bool "SYMBOL1"

config SYMBOL2
	default n
	bool "SYMBOL2"

endchoice

SYMBOL1 and SYMBOL2 are dependent on CHOICE, so it will be very useful to have possibility to get this dependency by the API method or just from deserializied string option info (like "Additional dependencies from enclosing menus and ifs:" section).

Is it hard feature to implement? Thank you.

Feature Request: Add to PyPi

Hi,

it would be pretty neat to see this lib in PyPI - the Python Package Index. This allows everyone to install it using pip, Python software to install it as a dependency and Linux distros to more easily package it.

Failing compatibility tests

Verify that Kconfiglib generates the same .config as 'make alldefconfig', for each architecture

...
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_IRQ_POLL is not set
+CONFIG_MPILIB=y
+CONFIG_OID_REGISTRY=y
+# CONFIG_SG_SPLIT is not set
+CONFIG_SG_POOL=y
+CONFIG_ARCH_HAS_SG_CHAIN=y
+CONFIG_SBITMAP=y
+# CONFIG_STRING_SELFTEST is not set
sparc with arch/sparc/configs/sparc32_defconfig FAIL

on linux-4.15-rc3

command python3 Kconfiglib/testsuite.py

Lack of proper menuconfig support

Consider File systems / Native language support path. Despite it's a symbol it behaves exactly like menu. I still can use symbol.dep to get all descendants, but there's inconsistency, e.g. symbol.get_parent() of any child would return "File systems" menu node instead "Native language support". Would be cool to see some class like class MenuConfig(Symbol, Menu).

menuconfig cannot startup

When start up the menuconfig, something goes wrong.Here is the trace-back:

Using existing configuration './.config' as base
Traceback (most recent call last):
File "/usr/lib/python3.6/curses/init.py", line 78, in wrapper
cbreak()
_curses.error: cbreak() returned ERR

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "../../scripts/kconfig/menuconfig.py", line 3038, in
_main()
File "../../scripts/kconfig/menuconfig.py", line 601, in _main
menuconfig(standard_kconfig())
File "../../scripts/kconfig/menuconfig.py", line 680, in menuconfig
print(curses.wrapper(_menuconfig))
File "/usr/lib/python3.6/curses/init.py", line 100, in wrapper
nocbreak()
_curses.error: nocbreak() returned ERR
make[2]: *** [menuconfig] Error 1
make[1]: *** [menuconfig] Error 2

Some hints:
1,if just input "make menuconfig", it works, if add any other words in the command line,
like "make menuconfig V=1", it went wrong, very strange.
2, have tried some terminal, like xterm, sakura, the problem is the same. So I upgrade the
Ubuntu from 1604 to 1804(not reinstalled 1804, just upgraded the system from ubuntu's app).
the problem still exists. There maybe something wrong with my terminal, but don't know the real cause;

menuconfig.py doesn't handle LC_CTYPE identically with Python2 and 3

Version:

12.4.0

System:

debian 10

Description:

When launching menuconfig.py with Python2, I get:
Note: Your environment is configured to use ASCII. To avoid Unicode issues, LC_CTYPE was changed from the C locale to the C.UTF-8 locale.
While with Python3, I do not get that.

Locale settings:

LANG=fr_FR.UTF-8
LANGUAGE=
LC_CTYPE="fr_FR.UTF-8"
LC_NUMERIC="fr_FR.UTF-8"
LC_TIME="fr_FR.UTF-8"
LC_COLLATE="fr_FR.UTF-8"
LC_MONETARY="fr_FR.UTF-8"
LC_MESSAGES="fr_FR.UTF-8"
LC_PAPER="fr_FR.UTF-8"
LC_NAME="fr_FR.UTF-8"
LC_ADDRESS="fr_FR.UTF-8"
LC_TELEPHONE="fr_FR.UTF-8"
LC_MEASUREMENT="fr_FR.UTF-8"
LC_IDENTIFICATION="fr_FR.UTF-8"
LC_ALL=

More info:

The documentation for the Python2 locale module tells to call locale.setlocale(locale.LC_ALL,'') to get the user's settings. If tried the following with Python2:

>>> import locale
>>> locale.setlocale(locale.LC_CTYPE)
'C'
>>> locale.setlocale(locale.LC_ALL,'')
'fr_FR.UTF-8'
>>> locale.setlocale(locale.LC_CTYPE)
'fr_FR.UTF-8'

uname breaks windows script usage

register_special_symbol(STRING, "UNAME_RELEASE", os.uname()[2])
might be better off with something like the following perhaps?

@@ -165,7 +165,10 @@ class Config(object):
         self.m = register_special_symbol(TRISTATE, "m", "m")
         self.y = register_special_symbol(TRISTATE, "y", "y")
         # DEFCONFIG_LIST uses this
-        register_special_symbol(STRING, "UNAME_RELEASE", os.uname()[2])
+        try:
+            register_special_symbol(STRING, "UNAME_RELEASE", os.uname()[2])
+        except Exception as ex:
+            register_special_symbol(STRING, "UNAME_RELEASE", "unknown")

         # The symbol with "option defconfig_list" set, containing a list of
         # default .config files

how to merge multiple Kconfig(absolute path) by `source "${var}"`

I want to merge three Kconfig file to one,

  • root Kconfig(abs path: /home/aaa/Kconfig):
mainmenu "C/CPP CMake project framework Kconfig configuration"
menu "Components configuration"
	source "$(SUB_KCONFIGS)"
endmenu
  • Kconfig 1(abs path: /home/aaa/abcd/Kconfig):
...
  • Kconfig 2(abs path: /root/aaa/abcd/Kconfig):
...

and I want to merge Kconfig 2 and Kconfig 1 to root Kconfig like this way

cd /home/aaa/
export SUB_KCONFIGS="/home/aaa/abcd/Kconfig /root/aaa/abcd/Kconfig"
menuconfig

but it's not work, maybe because of this code:

Kconfiglib/kconfiglib.py

Lines 2846 to 2856 in f1e6f32

pattern = join(dirname(self._filename), pattern)
# - glob() doesn't support globbing relative to a directory, so
# we need to prepend $srctree to 'pattern'. Use join()
# instead of '+' so that an absolute path in 'pattern' is
# preserved.
#
# - Sort the glob results to ensure a consistent ordering of
# Kconfig symbols, which indirectly ensures a consistent
# ordering in e.g. .config files
filenames = sorted(iglob(join(self._srctree_prefix, pattern)))

for temporary use, I changed code to

filenames = pattern.split(" ")
if not os.path.exists(filenames[0]):
    filenames = sorted(iglob( join(self._srctree_prefix, pattern) ))

but can you tell me what's the right way to merge these three kconfig files?

best regards!

Dependency loop issue

I use Kconfiglib to configure my project, but found problems. I didn't find anything wrong with the Kconfig file. I don't know if there is a problem with the dependency loop detection logic of the library.Please take a look, thank you!

Attach log below:

Dependency loop

RT_USING_DFS (defined at ....\components\dfs\Kconfig:3), with definition...

config RT_USING_DFS
bool
prompt "Using device virtual file system"
default "y"
select RT_USING_MUTEX
help
The device file system is a light weight virtual file system.

(select-related dependencies: (RT_USING_SPI_MSD && RT_USING_SPI) || (SAL_USING_POSIX && RT_USING_SAL))

...depends on SAL_USING_POSIX (defined at ....\components\net\Kconfig:28), with definition...

config SAL_USING_POSIX
bool
prompt "Enable BSD socket operated by file system API" if RT_USING_SAL
default "y" if RT_USING_POSIX && RT_USING_SAL
default "n" if RT_USING_SAL
select RT_USING_DFS if RT_USING_SAL
select RT_USING_LIBC if RT_USING_SAL
select RT_USING_POSIX if RT_USING_SAL
depends on RT_USING_SAL
help
Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.

...depends on RT_USING_POSIX (defined at ....\components\libc\Kconfig:12), with definition...

config RT_USING_POSIX
bool
prompt "Enable POSIX layer for poll/select, stdin etc" if RT_USING_LIBC && RT_USING_DFS
default "y" if RT_USING_LIBC && RT_USING_DFS
select RT_USING_DFS_DEVFS if RT_USING_LIBC && RT_USING_DFS
depends on RT_USING_LIBC && RT_USING_DFS

(select-related dependencies: SAL_USING_POSIX && RT_USING_SAL)

...depends again on RT_USING_DFS (defined at ....\components\dfs\Kconfig:3):

FYI: I created project pylkc as an alternative to Kconfiglib

I have encountered bug again when I use Kconfiglib to operate Linux-3.17, so I create a new project fpemud/pylkc.
pylkc provides the same function as Kconfiglib (with different API) and the implementation is way much simpler and more maintainable by reusing the C code in "LINUX_SRC_DIR/scripts/kconfig". I also expect it to be more accurate and have less bugs for the same reason. pylkc also has its limitations, which is elaborated in README.
It has not been completed yet, but can already serve my project fpemud-kernelmanger well enough.

Documentation for kconfig_filenames is misleading

The documentation for kconfig_filenames states that:

  A list with the filenames of all Kconfig files included in the
  configuration, relative to $srctree (or relative to the current directory
  if $srctree isn't set).

which lead me to believe that all paths were relative to srctree, e.g. that some kind of path conversion was done for absolute paths. But in fact 'kconfig_filenames' contains both absolute paths and paths relative to srctree.

menuconfig won't write new config symbol to .config if just quit the menuconfig dialog.

Test steps:
1, there is an old .config
2,change some Kconfig and add a new config symbol(default maybe yes or no)
3, open menuconfig, do nothing, press 'ESC' to quit the dialog, menuconfig will not let you select
"save or no", just quit anyway.
4,menuconfig left the .config to original one, even it find the new config symbol.

This is not work the same way like kernel. With this case, the kernel will find the changes and override the old one with new symbol.

But if you do anything in the dialog, e.g. toggle the new symbol on/off, menuconfig will find this change and override the old one(if you select "save" option).

FileNotFoundError: [Errno 2] No such file or directory: 'Kconfig'

I wonder if argparse could not be used to pass some parameters (at least for the already restricted python3).
right now when I try to run executable, I mostly get:
FileNotFoundError: [Errno 2] No such file or directory: 'Kconfig'

And the 2nd step of the getting started was not helpful for me, as I wanted to analyze the kernel's config

1.Install the library and the utilities. Use pip3 if you want to use the terminal menuconfig.

2. Write Kconfig files that describe the available configuration options.

Looking further in the documentation, I saw that I could set $srctree (I had KCONFIG_CONFIG already set) which I did but now I have:

Traceback (most recent call last):
  File "./genconfig.py", line 89, in <module>
    main()
  File "./genconfig.py", line 77, in main
    kconf = kconfiglib.Kconfig(args.kconfig_filename)
  File "/home/teto/Kconfiglib/kconfiglib.py", line 973, in __init__
    self._parse_block(None, self.top_node, self.top_node)
  File "/home/teto/Kconfiglib/kconfiglib.py", line 2647, in _parse_block
    prev = self._parse_block(None, parent, prev)
  File "/home/teto/Kconfiglib/kconfiglib.py", line 2647, in _parse_block
    prev = self._parse_block(None, parent, prev)
  File "/home/teto/Kconfiglib/kconfiglib.py", line 2645, in _parse_block
    os.path.relpath(filename, self.srctree))
  File "/home/teto/Kconfiglib/kconfiglib.py", line 1880, in _enter_file
    for name, linenr in self._include_path)))
kconfiglib.KconfigError: 
arch/Kconfig:10: Recursive 'source' of 'arch/Kconfig' detected. Check that environment variables are set correctly.
Include path:
Kconfig:12
init/Kconfig:1756
arch/Kconfig:10

I want to use Kconfiglib to be able to find the dependencies of a specific setting and enable them automatically. Like enabling VIRTIO_NET should enable VIRTIO, right now I do it manually. Is this something I could do with kconfiglib ? (or any other way ?)

base_dir doesn't work, os.chdir is still required

Traceback (most recent call last):
  File "kc3.py", line 24, in <module>
    conf = Config(base_dir='/usr/src/linux')
  File "/home/neumond/.python/kconfiglib.py", line 218, in __init__
    self.top_block = self._parse_file(filename, None, None, None)
  File "/home/neumond/.python/kconfiglib.py", line 604, in _parse_file
    return self._parse_block(_FileFeed(filename), None, parent, deps,
  File "/home/neumond/.python/kconfiglib.py", line 3111, in __init__
    with open(filename, "r") as f:
FileNotFoundError: [Errno 2] No such file or directory: 'Kconfig'

make -p instead patching makefile

This should print all env variables from makefile. It will require writing standalone parser for LANG= make -p output. Don't know how nicely this will work under different make systems though. Possible complexity is in recursive makefile system: every makefile can set its own variables, some investigation needed to know whether this affects result.

couldn't farse enviroment variable, such as "$BSP_DIR"

Kconfiglib couldn't farse enviroment variable, such as "$BSP_DIR".

config $BSP_DIR
string
option env="BSP_ROOT"
default "."

config $RTT_DIR
string
option env="RTT_ROOT"
default "../.."

report error:
KconfigError: Kconfig:3: couldn't parse 'config $BSP_DIR': missing end parenthesis in macro expansion:
File "D:\work\RT-Thread\git\weety\rt-thread\bsp\stm32f4xx-HAL\SConstruct", line 36:
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
File "D:\work\RT-Thread\git\weety\rt-thread\tools\building.py", line 350:
pyconfig(Rtt_Root)
File "D:\work\RT-Thread\git\weety\rt-thread\tools\menuconfig.py", line 191:
pymenuconfig.main(['--kconfig', 'Kconfig', '--config', '.config'])
File "D:\work\RT-Thread\git\weety\rt-thread\tools\pymenuconfig.py", line 1094:
kconf = kconfiglib.Kconfig(filename=kconfig_path)
File "D:\work\RT-Thread\git\weety\rt-thread\tools\kconfiglib.py", line 757:
self._parse_block(None, self.top_node, self.top_node)
File "D:\work\RT-Thread\git\weety\rt-thread\tools\kconfiglib.py", line 2174:
while self._has_tokens or self._next_line():
File "D:\work\RT-Thread\git\weety\rt-thread\tools\kconfiglib.py", line 1578:
self._tokens = self._tokenize(self._line)
File "D:\work\RT-Thread\git\weety\rt-thread\tools\kconfiglib.py", line 1769:
s, end_i = self._expand_macro(s, i, ())
File "D:\work\RT-Thread\git\weety\rt-thread\tools\kconfiglib.py", line 2031:
self._parse_error("missing end parenthesis in macro expansion")
File "D:\work\RT-Thread\git\weety\rt-thread\tools\kconfiglib.py", line 2967:
"{}couldn't parse '{}': {}".format(loc, self._line.rstrip(), msg))

permit PYTHONCMD=ipython

Just stumbled on this library and am starting to explore; looks nice! One thing is, if you changed the patch to scripts/kconfig/Makefile so that it read like this, then users could use iscriptconfig with PYTHONCMD=ipython (or ipython2).

iscriptconfig:
...
c = kconfiglib.Config(sys.argv[4 if "$(PYTHONCMD)".startswith("ipython
") else 1]); \
...

Kconfig preprocessor: couldn't parse 'default $(shell ...

Hi,

when I run Kconfiglib on v4.18-rc4 upstream kernel, I get:

init/Kconfig:16: couldn't parse ' default $(shell,$(srctree)/scripts/gcc-version.sh -p $(CC) | sed 's/^0*//') if CC_IS_GCC': macro expanded to blank string

It looks like a tiny expansion issue in the new Kconfig preprocessor.

Best regards,
Jakub

"Not a git repository" when installing on clean machine.

I was trying to install Kconfiglib on a clean machine and here was the sequence of events.

$ git clone git://github.com/ulfalizer/Kconfiglib.git
Cloning into 'Kconfiglib'...
remote: Counting objects: 1756, done.
remote: Total 1756 (delta 0), reused 0 (delta 0), pack-reused 1756
Receiving objects: 100% (1756/1756), 560.51 KiB | 703.00 KiB/s, done.
Resolving deltas: 100% (1091/1091), done.
Checking connectivity... done.
$ git am Kconfiglib/makefile.patch
fatal: Not a git repository (or any of the parent directories): .git

Clearly this is not intended.

So I tried git init on the same directory:

$ git init .
Initialized empty Git repository in /home/test/
$ git am Kconfiglib/makefile.patch
Applying: Kconfiglib scripts/kconfig/Makefile patch.
error: scripts/kconfig/Makefile: does not exist in index
Patch failed at 0001 Kconfiglib scripts/kconfig/Makefile patch.
The copy of the patch that failed is found in:
   /home/test/.git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

What am I missing here?

Mismatching if/endif handling is weak

This report comes from Zephyr, with version of kconfiglib used there (Zephyr master e1e12ba0c6eeb41bea72ea242195306a69b8b013).

So, I was moving around/adding more "if" directives, and so happens that I added "endif", but (turned out) that missed to add corresponding "if". What I got is rather confusing error message:

$ zephyr-make menuconfig
mkdir -p outdir/qemu_x86 && cmake -DBOARD=qemu_x86 -Boutdir/qemu_x86 -H.
-- Selected BOARD qemu_x86
Zephyr version: 1.13.99
Parsing Kconfig tree in /home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/Kconfig
Traceback (most recent call last):
  File "/home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/scripts/kconfig/kconfig.py", line 210, in <module>
    main()
  File "/home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/scripts/kconfig/kconfig.py", line 44, in main
    kconf = Kconfig(args.kconfig_root, warn_to_stderr=False)
  File "/home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/scripts/kconfig/kconfiglib.py", line 836, in __init__
    self._parse_block(None, self.top_node, self.top_node)
  File "/home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/scripts/kconfig/kconfiglib.py", line 2377, in _parse_block
    prev = self._parse_block(None, parent, prev)
  File "/home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/scripts/kconfig/kconfiglib.py", line 2377, in _parse_block
    prev = self._parse_block(None, parent, prev)
  File "/home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/scripts/kconfig/kconfiglib.py", line 2416, in _parse_block
    self._parse_block(_T_ENDMENU, node, node)
  File "/home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/scripts/kconfig/kconfiglib.py", line 2377, in _parse_block
    prev = self._parse_block(None, parent, prev)
  File "/home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/scripts/kconfig/kconfiglib.py", line 2483, in _parse_block
    self._parse_error("unrecognized construct")
  File "/home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/scripts/kconfig/kconfiglib.py", line 3104, in _parse_error
    "{}couldn't parse '{}': {}".format(loc, self._line.rstrip(), msg))
kconfiglib.KconfigError: lib/posix/Kconfig:88: couldn't parse 'endif # POSIX_API': unrecognized construct
CMake Error at /home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/cmake/kconfig.cmake:158 (message):
  command failed with return code: 1
Call Stack (most recent call first):
  /home/pfalcon/projects-3rdparty/Embedded/Zephyr/zephyr/cmake/app/boilerplate.cmake:257 (include)
  CMakeLists.txt:2 (include)

As you may imagine, first motion is "huh, maybe it doesn't support comments on the same line after endif?". Grepping around Zephyr codebase shows they're used, and removing the comment still leads to the same couldn't parse 'endif': unrecognized construct error. That's pretty confusing if a standard keyword is "unrecognized". Would be nice if it reported "endif without corresponding if" of something.

LICENSE.txt not in Pypi tarball

The README says:

See LICENSE.txt. SPDX license identifiers are used in the source code.

But this file isn't in the tarball on pypi.

hi first example I tried failed

hi
first example I tried failed (Example 5: print a tree of all items in the configuration.)
failed for both linux-3.10.79 and linux-4.0.4

python py/print.config.tree.py /linux-3.10.79/arch/x86/configs/x86_64_defconfig

/linux-3.10.79/arch/x86/configs/x86_64_defconfig:1:
Traceback (most recent call last):
File "py/print.config.tree.py", line 20, in
conf = kconfiglib.Config(sys.argv[1])
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 214, in init
self.top_block = self._parse_file(filename, None, None, None)
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 919, in _parse_file
return self._parse_block(line_feeder, None, parent, deps, visible_if_deps, res)
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 972, in _parse_block
tokens = self._tokenize(line, False, filename, linenr)
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 639, in _tokenize
_tokenization_error(s, len(s), filename, linenr)
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 3782, in _tokenization_error
" " * vis_index + "^\n"))
kconfiglib.Kconfig_Syntax_Error: Error during tokenization at location indicated by caret.

CONFIG_EXPERIMENTAL=y
^

python py/print.config.tree.py /linux-4.0.4/arch/x86/configs/x86_64_defconfig

/linux-4.0.4/arch/x86/configs/x86_64_defconfig:1:
Traceback (most recent call last):
File "py/print.config.tree.py", line 20, in
conf = kconfiglib.Config(sys.argv[1])
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 214, in init
self.top_block = self._parse_file(filename, None, None, None)
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 919, in _parse_file
return self._parse_block(line_feeder, None, parent, deps, visible_if_deps, res)
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 972, in _parse_block
tokens = self._tokenize(line, False, filename, linenr)
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 639, in _tokenize
_tokenization_error(s, len(s), filename, linenr)
File "/usr/lib/python2.7/site-packages/kconfiglib.py", line 3782, in _tokenization_error
" " * vis_index + "^\n"))
kconfiglib.Kconfig_Syntax_Error: Error during tokenization at location indicated by caret.

CONFIG_EXPERIMENTAL=y
^

Issues when using kconfiglib

I can get the infomation like below:
menu "Kernel hacking" use get_title()
config PRINTK_TIME use get_name()
comment "Frame buffer hardware drivers" use get_text()

the PRINTK_TIME's prompt is "Show timing information on printks"
There seems no direct interface to get this prompt.

so I want to add "get_prompt" function to class Symbol and class Choice.
do you think it's appropriate?

Is there plan for add python version fixdep?

Currently the genconfig --sync-dep just generates the header for the config symbols, is there plan to implement the function that change the autoconf.h to these files in the dependency file?
If my understanding wrong please correct me.

defconfig example wrong?

Hi,

when I try to do something similar to the defconfig example, it seems to emit config options incorrectly for me:

~/packages/linux (HEAD detached from v4.4.67) cat tester.py 
import sys

import kconfiglib

config = kconfiglib.Config(sys.argv[1])
config.load_config(config.get_defconfig_filename())

print(config.get_symbol("BPF_SYSCALL").get_value())
~/packages/linux (HEAD detached from v4.4.67) make scriptconfig SCRIPT=./tester.py
warning: the value "m" is invalid for BATTERY_BQ27XXX_I2C, which has type bool. Assignment ignored.
warning: the value "m" is invalid for MFD_AXP20X, which has type bool. Assignment ignored.
warning: the value "m" is invalid for WILC1000_SDIO, which has type bool. Assignment ignored.
warning: the value "m" is invalid for WILC1000_SPI, which has type bool. Assignment ignored.
y
~/packages/linux (HEAD detached from v4.4.67) make defconfig
*** Default configuration is based on 'x86_64_defconfig'
#
# configuration written to .config
#
~/packages/linux (HEAD detached from v4.4.67) grep BPF_SYSCALL .config
# CONFIG_BPF_SYSCALL is not set

I must be missing something, but I'm not sure what :)

confusion about symbol X86_EXTENDED_PLATFORM

In /usr/src/linux/arch/x86/Kconfig, there's two config X86_EXTENDED_PLATFORM

if X86_32
config X86_EXTENDED_PLATFORM
    bool "Support for extended (non-PC) x86 platforms"
    default y
    ---help---
    ...
endif

if X86_64
config X86_EXTENDED_PLATFORM
    bool "Support for extended (non-PC) x86 platforms"
    default y
    ---help---
    ...
endif

I wrote a test in https://github.com/fpemud/fpemud-kernelmanager/blob/master/test/kcfgtest

...
# function:
if sys.argv[1] == "show_duplicate_name":
    print "test1:"
    for sym in conf.get_symbols():
        if sym.get_name() == "X86_EXTENDED_PLATFORM":
            print "sym X86_EXTENDED_PLATFORM: %s"%(sym.get_visibility())
    print ""

    print "test2:"
    mnu = None
    for m in conf.get_menus():
        if m.get_title() == "Processor type and features":
            mnu = m
            break
    assert mnu is not None

    for i in mnu.get_items():
        try:
            if i.get_name() == "X86_EXTENDED_PLATFORM":
                print "sym X86_EXTENDED_PLATFORM: %s, %s"%(sym.get_visibility(), i.is_symbol())
        except:
            pass

The test result shows:

fpemud@fpemud-notebook ~/workspace/fpemud-kernelmanager/test $ ./kcfgtest show_duplicate_name
test1:
sym X86_EXTENDED_PLATFORM: y

test2:
sym X86_EXTENDED_PLATFORM: y, True
sym X86_EXTENDED_PLATFORM: y, True

It is out of my expectation, I think:

  1. both test1 and test2 should show 2 lines of X86_EXTENDED_PLATFORM
  2. one line should have visibility "y" and the other should have visibility "n"

Is it a bug of Kconfiglib?

Proposal: support relative path in 'source' statement

Hi,

I'm working on a project where build configuration system is implemented entirely in Python with Kconfiglib at its center. That way, we don't have to use any of Linux kernel Kconfig/Kbuild code, which has certain benefits. In our situation it's tempting to extend Kconfiglib with new features beyond what's offered by Linux kernel, and one such extension that may be useful for someone else is the support for relative paths in source directive.

Imagine the following directory structure:

Project
|
+--Kconfig
+--src
   +--Kconfig
   |
   +--SubSystem1
   |  +--Kconfig
   |  |
   |  +--ModuleA
   |  |  +--Kconfig
   |  |
   |  +--ModuleB
   |     +--Kconfig   
   |
   +--SubSystem2
      +--Kconfig
      |
      +--ModuleC
      |  +--Kconfig
      |
      +--ModuleD
         +--Kconfig

Here, Kconfig file in SubSystem1 sources Kconfig file from ModuleA, and to do this one writes:

source "src/SubSystem1/ModuleA/Kconfig"

Complete path from project root needs to be specified, which is error-prone and creates difficulties when for some reason one wants to rename/move SubSystem1 directory, as paths should be modified in all Kconfig files under affected directory. Sometimes Kconfig files are nested more deeply than in my example, so it becomes even worse.

The proposal is to add support for relative paths in source directive, so that path relative to directory of currently processed Kconfig file can be specified instead of path relative to project root:

source "ModuleA/Kconfig"

Obviously, this mode of source directive interpretation is not compatible with Linux kernel tools. I see two ways how this can be enabled without breaking existing code:

  1. Add optional argument to Kconfig constructor:

    def __init__(self, filename="Kconfig", warn=True, source_uses_relative_paths=False):
    

    This doesn't change Kconfig language, but in many other aspects it's ugly:

    • If such Kconfig infrastructure is by mistake used with Linux kernel tools, cryptic error messages would be rised about non-existing files. Or, even worse, if relative path specified in Kconfig file nested deep inside project directory tree exists in project root, then Linux tools may interpret configuration incorrectly without issuing warnings of any kind..
    • The support for new constructor argument needs to be implemented in all tools based on Kconfiglib that you want to use in your configuration system
    • It's implicit: you can't immediately tell by looking into Kconfig files which kind of paths is used
  2. Add new Kconfig language statement, for example rsource:

    rsource "ModuleA/Kconfig"
    

    Pros:

    • The new statement explicitly tells user that relative path is used instead of standard behavior
    • Linux kernel tools would fail with clean syntax error about unknown token if used by mistake to parse your Kconfig files, so there should be no silent bugs
    • source and rsource can be intermixed in Kconfig files if needed

    Cons:

    • It's possible to have a conflict in future if Linux kernel devs introduce rsource statement in kernel tools. Not sure about right way to prevent this...

I personally prefer the rsource variant (sure, new directive name is subject to discussion).
If you find this feature useful, please let me know and I will prepare a pull request.

Thanks,
Roman

kernel v4.18 added new kconfig fefatures

Hi,

Started using this standalone library for some sanity kconfig checks for the kernel. Noticed in v4.18 a whole bunch of new features were added that are not here yet.

For starters, scripts/Kconfig.include has new unsupported token := and then all the shell scripting stuff.
Finally the embedded use of environment variables see $(SRCARCH) in Kconfig.

There is a lot there to implement, not sure if that is something planned or not.

Thanks for this tool!

Cheers,
Don

Duplicate rsource

Say you have two files

#foo.Kconfig
config FOO
    bool "Foo"
if FOO
    rsource bar.Kconfig
endif
if !FOO
    rsource bar.Kconfig
endif

and

#bar.Kconfig
choice BAR
    prompt "BAR"
    config BAR1
        bool "BAR1"
    config BAR2
        bool "BAR2"
endchoice

No matter if FOO is y or n, the BAR menu looks like this

(X) BAR1
( ) BAR2
(X) BAR1
( ) BAR2

And if I choose a BAR2

( ) BAR1
(X) BAR2
( ) BAR1
(X) BAR2

This might seem contrived, but sometimes it's useful to be able to present a menu one place in one context and in another place in another context.

I don't know if this affects other source commands as well.

Unexpected behaviour when loading fragments

Hi,

pretty sure this is a bug, but it is not easy to be certain with Kconfig ;)

Lowering a value in a fragment doesn't seem to work.

Steps to reproduce:

cd Kconfiglib/examples
git remote add sebo_remote https://github.com/SebastianBoe/Kconfiglib
git fetch --all
git checkout 34327f56891e2a6583df6d03144042084fca07a8
python merge_config.py Kconfig merged conf1 && cat merged 

Actual output:

sebo@mach:~/repos/kconfiglib_zephyr/examples$ python merge_config.py Kconfig merged conf1 && cat merged 
conf1:2: warning: BAR (defined at Kconfig:9) set more than once. Old value: "y", new value: "n".
warning: BAR (defined at Kconfig:9) was assigned the value "n" but got the value "y" -- check dependencies
# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)
# CONFIG_FOO is not set
CONFIG_BAR=y

Expected output:

sebo@mach:~/repos/kconfiglib_zephyr/examples$ python merge_config.py Kconfig merged conf1 && cat merged 
conf1:2: warning: BAR (defined at Kconfig:9) set more than once. Old value: "y", new value: "n".
# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)
CONFIG_FOO=y
# CONFIG_BAR is not set

Interestingly, removing CONFIG_BAR=y will give the expected behaviour, which leads me to believe one can not lower config values in fragments, which is unexpected as the warning states it is getting the new value.

PS: SebastianBoe@34327f5

License information

Is it possible to know under what license Kconfiglib is released?

Could you add to the sources the COPYING or LICENSE file according to the license you choose?

TIA,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.