ulfalizer / kconfiglib Goto Github PK
View Code? Open in Web Editor NEWA flexible Python 2/3 Kconfig implementation and library
License: ISC License
A flexible Python 2/3 Kconfig implementation and library
License: ISC License
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
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.
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.
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!
There's a typo in _FileFeed.peek_next()
(line 3128 3135), which causes it to raise an Exception when dealing with line continuation - res
should be line
.
Didn't feel like forking and creating a pull-req for this minor change, so here's a patch at gist.github.com
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:
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 :)
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?
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.
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'
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?
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?
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.
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
...
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.
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.
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.
I see you have completed a wave of fix, awesome.
I have merge your new code to my fork, the test is passed and i'm using it.
I finally write a README for my project, you can go and see it: https://github.com/fpemud/fpemud-kernelmanager
Additionally, I have 2 feature request.
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
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)
.
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;
12.4.0
debian 10
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.
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=
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'
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
hi
there is no "make oldconfig" in examples.
"make oldconfig" is sorta critical for something.
I want to merge three Kconfig
file to one,
/home/aaa/Kconfig
):mainmenu "C/CPP CMake project framework Kconfig configuration"
menu "Components configuration"
source "$(SUB_KCONFIGS)"
endmenu
/home/aaa/abcd/Kconfig
):...
/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:
Lines 2846 to 2856 in f1e6f32
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!
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:
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):
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.
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.
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).
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 ?)
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'
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.
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))
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]); \
...
Hi,
when I run Kconfiglib on v4.18-rc4 upstream kernel, I get:
init/Kconfig:16: couldn't parse ' default
It looks like a tiny expansion issue in the new Kconfig preprocessor.
Best regards,
Jakub
I think you're spending too much time on kconfiglib. You should come chat with us instead.
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?
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.
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 (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
^
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?
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.
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 :)
Trailing comments in Kconfig fragments is legal (supported by conf), but breaks kconfiglib.
E.g.
CONFIG_FOO=3 # bla bla
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:
Is it a bug of Kconfiglib?
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:
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:
Add new Kconfig language statement, for example rsource
:
rsource "ModuleA/Kconfig"
Pros:
source
and rsource
can be intermixed in Kconfig files if neededCons:
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
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
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.
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.
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,
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.