summaryrefslogtreecommitdiff
path: root/README.rst
blob: 6ae8926c5ed8adb6b1b2e8a34a62c36100f64f48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
Kconfiglib
==========

A Python library for doing stuff with `Kconfig <https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt>`_-based
configuration systems. Can extract information, query and set symbol values,
and read and write ``.config`` files. Highly compatible with the
``scripts/kconfig/*conf`` utilities in the kernel, usually invoked via make
targets such as ``menuconfig`` and ``defconfig``.

Supports both Python 2 and Python 3 without modification, and should also run
on non-\*nix platforms

.. contents:: Table of contents
   :backlinks: none

Installation
------------

Installation with pip
~~~~~~~~~~~~~~~~~~~~~

Kconfiglib is available on `PyPI <https://pypi.python.org/pypi/kconfiglib/>`_ and can be
installed with e.g.

.. code::

    $ pip(3) install kconfiglib --user

All releases have a corresponding tag in the git repository, e.g. ``v1.0.3``.
`Semantic versioning <http://semver.org/>`_ is used.

Installation for the Linux kernel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

After installing with ``pip(3)``, apply ``makefile.patch``
by running e.g. the following commands in the kernel root:

.. code:: sh

    $ wget https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch
    $ git am makefile.patch

If you do not wish to install anything, the following manual approach will work as well:

.. code:: sh

    $ git clone git://github.com/ulfalizer/Kconfiglib.git  
    $ git am Kconfiglib/makefile.patch

(Warning: The directory name ``Kconfiglib/`` is significant in this case, because it's added to ``PYTHONPATH`` by the new targets in ``makefile.patch``.)

In addition to creating a handy interface, the make targets created by the
patch (``scriptconfig`` and ``iscriptconfig``) are needed to pick up environment
variables set in the kernel makefiles and later referenced in the Kconfig files
(``ARCH``, ``SRCARCH``, and ``KERNELVERSION`` as of Linux v4.14.0-rc1).
The documentation explains how the make targets are used. The compatibility
tests in the test suite also needs them.

Please tell me if the patch does not apply. It should be trivial to apply
manually, as it's just a block of text that needs to be inserted near the other
``*conf:`` targets.

Manual installation
~~~~~~~~~~~~~~~~~~~

The entire library is contained in
`kconfiglib.py <https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_.
Just drop it somewhere.

Documentation
-------------

The (extensive) documentation is generated by running the following command in the same
directory as `kconfiglib.py <https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_:

.. code:: sh

    $ pydoc kconfiglib

For HTML output, use

.. code:: sh

    $ pydoc -w kconfiglib
    
You could also browse the docstrings directly in
`kconfiglib.py <https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_.

Please tell me if something is unclear to you or can be explained better. The Kconfig
language has some dark corners.

Examples
--------

* The `examples/ <https://github.com/ulfalizer/Kconfiglib/tree/master/examples>`_ directory contains simple example scripts. See the documentation for how to run them.

* `genboardscfg.py <http://git.denx.de/?p=u-boot.git;a=blob;f=tools/genboardscfg.py;hb=HEAD>`_ from `Das U-Boot <http://www.denx.de/wiki/U-Boot>`_ generates some sort of legacy board database by pulling information from a newly added Kconfig-based configuration system (as far as I understand it :).

* `gen-manual-lists.py <https://git.busybox.net/buildroot/tree/support/scripts/gen-manual-lists.py?id=5676a2deea896f38123b99781da0a612865adeb0>`_ generated listings for an appendix in the `Buildroot <https://buildroot.org>`_ manual. (The listing has since been removed.)

* `SConf <https://github.com/CoryXie/SConf>`_ builds an interactive configuration interface (like ``menuconfig``) on top of Kconfiglib, for use e.g. with `SCons <scons.org>`_.

* `kconfig-diff.py <https://gist.github.com/dubiousjim/5638961>`_ -- a script by `dubiousjim <https://github.com/dubiousjim>`_ that compares kernel configurations.

* Originally, Kconfiglib was used in chapter 4 of my `master's thesis <http://liu.diva-portal.org/smash/get/diva2:473038/FULLTEXT01.pdf>`_ to automatically generate a "minimal" kernel for a given system. Parts of it bother me a bit now, but that's how it goes with old work.
 
Test suite
----------

The test suite is run with

.. code::

    $ python(3) Kconfiglib/testsuite.py

It must be run from the top-level kernel directory, and requires that the git repository has
been cloned into it and ``makefile.patch`` applied.

**NOTE: Some tests currently overwrite .config in the kernel root, so make sure to back it up.**

The test suite consists of a set of selftests and a set of compatibility tests that
compare (character for character) configurations generated by Kconfiglib with
configurations generated by ``scripts/kconfig/conf`` for a number of cases. You
might want to use the "speedy" option; see
`testsuite.py <https://github.com/ulfalizer/Kconfiglib/blob/master/testsuite.py>`_.

The test suite might fail for a few configurations for kernels older than April 2016,
when a fix was added to Kconfig that's also mirrored in Kconfiglib
(see `this commit <https://github.com/ulfalizer/Kconfiglib/commit/35ea8d5f1d63bdc9f8642f5ce4445e8f7c914385>`_).
This is harmless, and only counts as a fail since the test suite compares literal
output from the kconfig version that's bundled with the kernel.

Kconfiglib is much faster than the test suite would indicate. Most of the time
is spent waiting around for ``make`` or the C utilities. Adding some multiprocessing
to the test suite would make sense.

Notes
-----

* **Useful information can be extracted from internal data structures.** The
  expression format is pretty simple for example: ``A && B && (!C || D == 3)`` is
  represented as the tuple structure
  ``(_AND, A, (_AND, B, (_OR, (_NOT, C), (_EQUAL, D, 3))))``; see the
  ``Config._parse_expr()`` docstring.

  It's hard to come up with good APIs for dealing with expressions given how
  general they are, so feel free to look at them directly if none of the
  exposed APIs will suffice (modifying them is dangerous though, because it
  breaks dependency tracking). Maybe I'll officially document the expression
  format and add a bunch of accessors later. The internal format is unlikely
  to change in either case, and would probably be returned directly.

  If you come up with some good generally-usable APIs involving
  expressions, please tell me. Make sure they also make sense for expressions
  involving ``||`` (or) and ``!`` (not).

* Kconfiglib works well with `PyPy <http://pypy.org>`_. It gives a nice speedup
  over CPython when batch processing a large number of configurations (like
  the test suite does).

* Kconfiglib assumes the modules symbol is ``MODULES`` and will warn if
  ``option modules`` is set on some other symbol. Let me know if this is a
  problem for you. Adding proper ``option modules`` support should be pretty
  easy.

* At least two things make it awkward to replicate a ``menuconfig``-like
  interface in Kconfiglib at the moment (but see
  `SConf <https://github.com/CoryXie/SConf>`_, as mentioned above).

  * There are no good APIs for figuring out what other symbols change in value
    when the value of some symbol is changed, to allow for "live" updates
    in the configuration interface. The simplest workaround is to refetch the
    value of each currently visible symbol every time a symbol value is
    changed.

  * ``menuconfig`` sometimes creates cosmetic menus implicitly by looking at
    dependencies. For example, a list of symbols where all symbols depend on
    the first symbol creates a cosmetic menu rooted at the first symbol.
    Recreating such menus is awkward.

    There is already basic support internally though, because it's needed to
    get obscure ``choice`` behavior right. See ``_determine_actual_symbols()`` and
    its helper ``_has_auto_menu_dep_on()``.

* Using `__slots__ <https://docs.python.org/3.1/reference/datamodel.html#slots>`_
  on classes would speed things up a bit and save memory. It'd remove some
  flexibility though.

* `fpemud <https://github.com/fpemud>`_ has put together
  `Python bindings <https://github.com/fpemud/pylkc>`_ to internal functions in the C
  implementation. This is an alternative to Kconfiglib's all-Python approach.

* The test suite failures (should be the only ones) for the following Blackfin
  defconfigs on e.g. Linux 3.7.0-rc8 are due to
  `a bug in the C implementation <https://lkml.org/lkml/2012/12/5/458>`_:

  * ``arch/blackfin/configs/CM-BF537U_defconfig``
  * ``arch/blackfin/configs/BF548-EZKIT_defconfig``
  * ``arch/blackfin/configs/BF527-EZKIT_defconfig``
  * ``arch/blackfin/configs/BF527-EZKIT-V2_defconfig``
  * ``arch/blackfin/configs/TCM-BF537_defconfig``

Thanks
------

Thanks to `Philip Craig <https://github.com/philipc>`_ for adding
support for the ``allnoconfig_y`` option and fixing an obscure issue
with ``comment``\s inside ``choice``\s (that didn't affect correctness but
made outputs differ). ``allnoconfig_y`` is used to force certain symbols
to ``y`` during ``make allnoconfig`` to improve coverage.