build2 Kconfig ModuleRevision 0.4.0-a.0.fcb7ec1133e1, June 2025
This revision of the document describes the build2
Kconfig module 0.4.X series.
Copyright © 2020-2025 the build2 authors.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GPLv2 license.
Table of Contents
Preface
This document describes the build2 Kconfig module. It starts
with an introduction to the Linux kernel configuration system (Kconfig) and
the build2 Kconfig module. The next chapter expands on that and
describes the integration of Kconfig into the build2
configuration model in more detail.
The remainder of the document serves as a guide to the Kconfig language
with examples based on the kconfig-hello
package. Besides this guide, see also the official Kconfig
Language and Kconfig
Macro Language documentation as well as the Kconfig
Tips and Best Practices from the Zephyr project.
1 Introduction
This chapter provides a brief overview of the Linux kernel configuration
system (Kconfig) and the functionality provided by the build2
Kconfig module. Its aim is to show how everything fits and works together
based on a customary "Hello, World!" example.
1.1 What is Kconfig?
Kconfig is the configuration system of the Linux kernel. Over the years it has evolved into a sophisticated variability modeling language and a toolset that are used by the Linux kernel to manage over ten thousand configuration options. It is also increasingly being used by other projects that need to manage complex configurations.
The Kconfig system consists of the following main parts:
- The configuration definition language.
- The configuration management tools.
- The configuration values format.
The configuration definition language, or the Kconfig language for
short, defines a hierarchy of menus containing configuration options as well
as relationships between them. Traditionally, configuration definitions are
stored in files called Kconfig (with a capital K).
Here is a simple configuration containing two options:
config FANCY
bool "Fancy options"
help
Enable more fancy configuration options.
config GREETING
string "Custom greeting"
default "Hello"
depends on FANCY
help
Custom string to use as a greeting.
While the examples in this document assume a UNIX-like operation system, they should work with minimal modifications on Windows.
To create and manage configurations, the Kconfig system includes a number
of tools called configurators. The most prominent of those are
kconfig-conf which provides a terminal-based
question-and-answer configuration method, kconfig-mconf which
provides a terminal-based menu configuration method based on a curses
library, and kconfig-qconf which provides a graphical
configuration method based on Qt. The kconfig-conf configurator
also provides a number of non-interactive configuration methods (default,
random, etc), support for updating old configurations to new definitions
(both interactively and non), as well as other configuration management
facilities (creation of default configurations, etc).
Given the above configuration definition saved in the
Kconfig file, we can run one of the configurators to create a
new configuration. For example:
$ kconfig-conf Kconfig * * Main menu * Fancy options (FANCY) [N/y/?] (NEW) y Custom greeting (GREETING) [Hello] (NEW) Hi # # configuration written to .config #
The configuration values are saved into a file that is
traditionally called .config though this naming convention is
not as universal as for the definition file (Kconfig). If we
examine the .config file produced by the above command, we will
see the following:
# # Automatically generated file; DO NOT EDIT. # Main menu # CONFIG_FANCY=y CONFIG_GREETING="Hi"
The Kconfig system is best suited for complex configuration requirements where user input is needed at least in some situations (for example, new platforms, custom/optimized configurations, etc). Some of its more advanced features include:
- String, integer, and choice configuration options in addition to boolean.
- Direct (
depends on) and reverse (select,imply) option relationships. - Grouping into sub-menus and multi-file definitions
(
source). - Make-like macro substitution in the definition language.
- Sophisticated set of tools for managing configurations.
1.2 What is build2 Kconfig
module?
The build2 Kconfig module provides the ability to use the
Linux kernel configuration system to configure build2 projects.
Specifically, it integrates the execution of one of the Kconfig
configurators into the build2 configure
meta-operation and loads the resulting configuration file presenting its
values as kconfig.* Buildfile variables. We can then use these
kconfig.* values to make decisions in buildfiles,
testscripts, and/or propagate them to our source code, similar
to config.* values (Project
Configuration).
As an example, let's see what it takes to add the Kconfig configuration
shown in the previous section to a simple build2 project. As a
first step, let's create the libhello library using bdep-new(1):
$ bdep new -l c++ -t lib --no-init libhello $ cd libhello
Next we copy the Kconfig definition file from the previous
section into the libhello/build/ subdirectory:
$ cp ../Kconfig build/
Finally, we edit libhello/build/bootstrap.build and load the
kconfig module. Here is what the new
bootstrap.build could look like:
project = libhello using version using config using kconfig using test using install using dist
The kconfig module is part of the standard pre-installed
build2 modules and no extra integration steps are required
other than the using directive in
bootstrap.build.
Now if we configure our project, we will see the familiar prompt:
$ b configure kconfig build/config.kconfig.new * * libhello 0.1.0-a.0.19700101000000 * Fancy options (FANCY) [N/y/?] (NEW) y Custom greeting (GREETING) [Hello] (NEW) Hi save build/config.build mv build/config.kconfig.new build/config.kconfig
From other diagnostics we can gather that the configuration file was
saved as build/config.kconfig. The reason
for first saving it as config.kconfig.new is explained in the
next chapter. We can confirm that its contents are similar to what we
have already seen:
$ cat build/config.kconfig # # Automatically generated file; DO NOT EDIT. # libhello 0.1.0-a.0.19700101000000 # CONFIG_FANCY=y CONFIG_GREETING="Hi"
The only difference in this file (as well as in the above prompt) is the
replacement of Main menu with libhello
0.1.0-a.0.19700101000000. As the name suggests, this is the title of
the main menu which is the root of the Kconfig menu hierarchy. Customarily,
it is set to the project name and version which the kconfig
module does automatically. However, it can also be set to a custom value
with the kconfig.kconfig.title variable, as discussed
later.
By default the kconfig module uses the terminal-based
question-and-answer configurator. It's a conservative choice that will work
in most circumstances and is built into the module, so the presence of the
kconfig-conf executable is not required. However, we can use
the config.kconfig variable to select a different configurator.
For example, we can reconfigure our project using the graphical
kconfig-qconf configurator This requires the
presence of the kconfig-qconf executable:
$ b configure config.kconfig=qconf
The CONFIG_* values from the configuration file are made
available as kconfig.<project>.* variables in
buildfiles with the configuration option name converted to the
lower case. For example, we can examine our values by adding the following
info directives at the beginning of
libhello/buildfile:
info "fancy: $kconfig.libhello.fancy" info "greeting: $kconfig.libhello.greeting"
If we now update our libhello project, we should see the
following output:
$ b libhello/buildfile:1:1: info: fancy: true libhello/buildfile:2:1: info: greeting: Hi ...
The Kconfig configuration is also reported at a sufficiently high verbosity level (Configuration Report). For example:
$ b configure -v kconfig libhello@/tmp/libhello/ fancy true greeting Hi
The configuration values (fancy and greeting)
used in this example are the same as what's shown in Project
Configuration and the same mechanisms for post-processing and
propagating configuration values apply here; in most examples from that
chapter you can simply replace config.libhello.* with
kconfig.libhello.*.
Note, however, that if a non-bool option is disabled (for example,
because its dependencies are unsatisfied), then the corresponding
kconfig.* variable will be null. At the same time,
the in
module treats a null substitution as an error unless a
fallback value is specified with the in.null variable. As a
result, if non-bool kconfig.* variables are used in the
.in file substitutions, then it is a good idea to specify the
fallback, for example:
h{config}: in{config}
{
# Instruct the in rule to substitute null with empty.
#
in.null = ''
}
See kconfig-hello for a
complete example that uses these mechanisms.
Analogous to configure, the standard disfigure
meta-operation removes the Kconfig configuration, or, more precisely, moves
it to config.kconfig.old. For example:
$ b disfigure mv build/config.kconfig build/config.kconfig.old rm build/config.build
And that's pretty much all we have to do to integrate Kconfig-based
configuration management into our project. One last touch would be to add
config.kconfig to build/.gitignore, next to
config.build:
/config.build /config.kconfig* ...
We've used a wildcard after config.kconfig to also ignore
intermediate config.kconfig.new files (discussed later) as well
as the config.kconfig.old file where Kconfig configurators
traditionally save the previous configuration.
The next chapter, Interface and Functionality,
provides more details on the functionality offered by the
kconfig module, including the available configurators,
customization points, etc. For an introduction to the Kconfig language that
also covers relevant build2 integration aspects, refer to Kconfig Language.
2 Interface and Functionality
This chapter provides a more detailed discussion of the
kconfig module's interface and functionality including its
integration with the config module's configuration process as
well as the customization points available to projects that use Kconfig.
2.1 Configuration Methods
As we have seen in the introduction, the config.kconfig
variable can be used to select an alternative configurator, such as
mconf or qconf. This variables also controls a few
other aspects of producing new or updating an existing configuration which
together we will call a configuration method. It has the following
overall structure:
[(new|old)-](def|ask|reask|mconf|qconf|env)
[...]
The optional first component controls the reuse of existing
config.kconfig. If new is specified, then the
configuration is created from scratch (with existing
config.kconfig, if exists, saved as
config.kconfig.old). If old is specified, then the
configuration is created based on existing config.kconfig (with
what "based" means determined by the second component). In this case, it's
an error for there to be no existing config.kconfig. If the
first component is omitted, then existing config.kconfig is
reused if present (old semantics) and created from scratch
otherwise (new semantics).
Given a configuration option definition in the Kconfig file, its value can come from the following sources:
- Existing
config.kconfigfile. - Default configuration file.
- Default value from the
Kconfigfile.
A configuration option that does not have a value in existing
config.kconfig is referred to as a newly-defined
configuration option. Naturally, if config.kconfig does not
exist or is not used (because of the new first component), then
all options are newly-defined.
The second component determines the configurator and its mode and has the following possible values:
def [file]- Set newly-defined configuration options to values from
fileif specified and to their default values fromKconfigotherwise (if some options are missing infile, they are set to default values as well). To reset all the configuration options, usenew-def. ask [file]- Ask for values of only newly-defined configuration options. For default
answers use values from
fileif specified and default values fromKconfigotherwise.Note that if
config.kconfigdoes not exist or is not used (new-ask) then this method is equivalent toreask. reask [file]- Ask for values of all the configuration options. For default answers use
values from
config.kconfigif exists, fromfileif specified, and default values fromKconfigotherwise. mconf- Present all the configuration options in a menu interface. For default
answers, use values from
config.kconfigif exists and default values fromKconfigotherwise. qconf- Present all the configuration options in a graphical interface. For
default answers, use values from
config.kconfigif exists and default values fromKconfigotherwise. env prog [args]- Run
progin the configuration environment (KCONFIG_CONFIG, etc) passing theKconfigfile as the last argument. For example:config.kconfig="env kconfig-conf --savedefconfig defconfig.kconfig"
The def, ask, and reask methods
are implemented as builtins and do not require the presence of the
kconfig-conf executable.
If no configuration method is specified with config.kconfig,
then ask is used by default. However, a project may specify a
different default configuration method as discussed in the next section.
Mapping for some of the kconfig-conf options to the above
methods:
--oldconfig ask --oldaskconfig reask --olddefconfig def --alldefconfig new-def --defconfig <file> new-def <file>
Note that the following methods have no kconfig-conf
equivalents:
old-def <file> [re]ask <file>
Another useful application of the env method is the
generation of random configurations with the kconfig-conf
--randconfig mode. For example:
$ b configure config.kconfig="env kconfig-conf -s --randconfig" kconfig build/config.kconfig.new KCONFIG_SEED=0xD6A72753 save build/config.build mv build/config.kconfig.new build/config.kconfig
This can be used to automatically try various configurations, for example, by continuously configuring and testing the project in a loop This example is UNIX-specific:
$ while \ b configure config.kconfig="env kconfig-conf -s --randconfig" && \ b test; do :; done
As can be seen on the previous listing, in the --randconfig
mode, kconfig-conf prints the seed that it used to generate the
configuration. This seed can be passed back to kconfig-conf as
an environment variable in order to recreate the same random configuration.
For example:
$ KCONFIG_SEED=0xD6A72753 \ b configure config.kconfig="env kconfig-conf -s --randconfig"
Another useful --randconfig environment variable is
KCONFIG_ALLCONFIG which can be used to specify a configuration
file containing a subset of options that must be set to specific rather than
random values.
2.2 Configuring and Loading
As mentioned briefly in the introduction, kconfig acts as a
second-level configuration mechanism to the builtin support in the form of
config.* variables and the config module. In
particular, the kconfig module hooks into the
configure and disfigure meta-operations of the
config module providing an integrated configuration process. It
is also possible to use the config.* variables (as well as
other Buildfile variables) as inputs to the kconfig
configuration. This chapter provides more details on how this is achieved
and the available customization points.
To understand how kconfig fits in, we begin with an overview
of the builtin configuration process, that is, what happens when we execute
the configure meta-operation. While the config
module is loaded in bootstrap.build, the
config.build file (if exists) is loaded as a first step of
loading root.build (more precisely, config.build
is loaded before any bootstrapped module is initialized, which happens prior
to loading root.build). After that, root.build and
the rest of the project are loaded as usual. In particular, during this
stage, root.build or any other buildfile can
examine the config.* variables (as loaded from
config.build and/or specified as command line overrides) and
cause this stage to fail (for example, using the assert
directive) if any values are deemed invalid. If, however, loading of the
project succeeds, the config module saves the new
config.build file which completes the configure
meta-operation.
The important point about this process is that the new configuration is
saved as the last step, after successfully loading the project. And the
kconfig module attempts to provide the second-level
configuration semantics that is consistent with this behavior. Specifically,
while the kconfig module must also be loaded (bootstrapped) in
bootstrap.build, it also delays loading
config.kconfig until later. However, unlike the
config module, by default, kconfig loads its
configuration after root.build. This semantics was chosen to
allow the first-level configuration as well as any other information made
available by modules loaded in root.build to influence the
Kconfig configuration. However, we can also load config.kconfig
at any point in root.build by explicitly loading (initializing)
the kconfig module. For example, continuing with the
libhello project from the previous chapter, we could have
something like this in our root.build:
using cxx using kconfig if ($kconfig.libhello.fancy && $cxx.target.class == 'windows') fail "have to keep it basic on Windows"
Similar to the config behavior, the kconfig
module also saves the configuration only after the project has successfully
been loaded. Achieving this semantics, however, is not as straightforward as
in the config module because the configuration must also be
made available during the project loading, as discussed above. To implement
this, kconfig first saves the configuration to a temporary
file, config.kconfig.new, and then renames it to
config.kconfig at the end. Specifically, the
kconfig module performs the following steps during
configure:
bootstrap.build- Register the post-
configurecallback with theconfigmodule. root.build- Run the configurator saving the result to
config.kconfig.new. configure- In post-
configurerenameconfig.kconfig.newtoconfig.kconfig.
When not configuring, the kconfig module simply loads
config.kconfig and verifies it is up-to-date with definitions
in Kconfig. If that's not the case, for example, because we've
added or removed a configuration option, then kconfig fails
suggesting that we reconfigure the project.
As mentioned in the previous section, a project may specify the default
configuration method that will be used if not explicitly specified with
config.kconfig. More precisely, the project may set any of the
kconfig.kconfig.{configure,reconfigure,retryconfigure}
variables to select the default method for creating new, updating existing,
and trying to fix previously created/updated configuration,
respectively.
To elaborate, the kconfig.kconfig.configure method is used
when configuring a project from scratch, without existing
config.kconfig, while kconfig.kconfig.reconfigure
is used while reconfiguring a project with existing
config.kconfig. The kconfig.kconfig.retryconfigure
method is used when reconfiguring a project with existing
config.kconfig.new, which normally means that the previous
(re)configuration attempt has failed or was interrupted. The default values
for these variables are reask, ask, and
reask, respectively.
Setting kconfig.kconfig.retryconfigure to a method that does
not allow the user to adjust every configuration option may result in an
invalid configuration that can only be fixed by first disfiguring the
project.
As an example, if we wanted our project to use the default values from
Kconfig and only use interactive configuration if explicitly
requested by the user (or if the default configuration turned out to be
invalid), we could add the following to our root.build before
loading kconfig:
kconfig.kconfig.configure = new-def kconfig.kconfig.reconfigure = old-def using kconfig
Provided this makes sense for your project, it's a good idea to make the default configuration method non-interactive. This will allow you to use the CI service and, if desired, publish your project to a package repository. While interactive default configuration may make sense for an end-product kind of projects, for reusable components such as libraries a non-interactive default that enables most of the functionality is probably the best choice. See Project Configuration for background.
What happens if we try to build our project without
config.kconfig? By default kconfig fails
suggesting that we configure the project. However, this behavior can be
altered with the kconfig.kconfig.transient variable. Setting it
to ask (which is the default), disables the ability to use
transient configurations. But in the above project it would make sense to
also use default values for transient configurations, for example:
kconfig.kconfig.configure = new-def kconfig.kconfig.reconfigure = old-def kconfig.kconfig.transient = def using kconfig
Besides the default values from Kconfig files, another
common source of default values are default configurations. This
method becomes more appropriate when we have multiple sets of default
values, for instance, one per target platform. As an example, let's convert
the above project to use the default configuration files in the
defconfig-platform.kconfig form where
platform is the target class as supplied by the
cxx.target.class variable (linux,
windows, macos, etc). Here are the changes to
root.build:
using cxx defconfig = $src_root/build/defconfig-$(cxx.target.class).kconfig kconfig.kconfig.configure = new-def $defconfig kconfig.kconfig.reconfigure = old-def $defconfig kconfig.kconfig.transient = def $defconfig using kconfig
The build/Kconfig file and files that it sources
(transitively) as well as build/defconfig*.kconfig are
automatically added to the distribution and need not be explicitly mentioned
as prerequisites in buildfiles.
While any Kconfig configuration file can serve as a default
configuration, normally a minimal version is produced using
kconfig-conf --savedefconfig. Given a suitably configured
project, we can extract the corresponding default configuration using the
env method:
$ b configure config.kconfig=\ "env kconfig-conf --savedefconfig defconfig-linux.kconfig"
We can also do it manually given just the configuration file, for example:
$ KCONFIG_CONFIG=config.kconfig \ kconfig-conf --savedefconfig defconfig-linux.kconfig Kconfig
If your Kconfig definition file relies on external inputs
(as discussed next), then with the manual extraction you will also need to
manually supply such inputs via environment variables.
2.3 External Kconfig Macro Variables
Selecting the default configuration based on the target platform as shown
in the previous section is one example of using information from the
first-level configuration and/or modules loaded before kconfig
to adjust the Kconfig configuration. It is, however, also possible to modify
the Kconfig definition file itself based on such information by
setting external Kconfig macro variables.
The Kconfig language includes a macro variable facility that can be used for textual substitution (see Macro Language for details). As an example, let's try to improve on our previous attempt to only allow fancy options in certain cases. To recap, this is what we did:
using cxx using kconfig if ($kconfig.libhello.fancy && $cxx.target.class == 'windows') fail "have to keep it basic on Windows"
Ideally, instead of allowing the user to select the FANCY
option and then complaining that it can't be selected for certain platforms,
we would want to make it impossible to select it in the first place when
configuring for such platforms. As a first step, let's introduce a Kconfig
macro variable and make the FANCY option depend on its
value:
ENABLE_FANCY := y
config FANCY
bool "Fancy options"
depends on $(ENABLE_FANCY)
help
Enable more fancy configuration options.
...
With this change we can now enable/disable the fancy options by adjusting
the ENABLE_FANCY Kconfig macro variable. The next step is to
somehow set it from outside the Kconfig file. With the
kconfig module we can do that by simply setting the
corresponding Kconfig.* variable (with a capital
K) in our buildfile. If
invoking one of the configurators directly, then such variables are set via
the environment. In our example, let's remove the
ENABLE_FANCY assignment from Kconfig and rewrite
root.build as follows:
using cxx Kconfig.ENABLE_FANCY = ($cxx.target.class != 'windows') using kconfig
Kconfig.* values of type bool are automatically
converted from Buildfile true/false to Kconfig
y/n. Other value types are passed to Kconfig by
converting to string.
The Kconfig macro variables can be used in many contexts, for example, in default values. However, such dynamically-changing Kconfig definitions become hard to reason about and can lead to surprises. As a result, it's probably wise to limit the use of external variables to disabling options and menus rather than altering their definitions.
A macro substitution referencing a variable that is not set inside the
Kconfig file nor via the Kconfig.* Buildfile
variable is an error. The only builtin variable set automatically by the
kconfig module is SRC_ROOT which contains the
project's source root directory (the same as the src_root
Buildfile variable). It is normally used to source (Source) additional Kconfig files, for
example:
source "$(SRC_ROOT)/libhello/Kconfig"
3 Kconfig Language
Kconfig is a line-oriented language. That is, a construct ends at the end
of the line unless escaped with line continuation (trailing \).
The # character starts a comment with everything from this
character until the end of the line ignored. This character and other
special characters (quotes, $, etc) can be escaped with a
backslash.
Kconfig has single-quoted (') and double-quoted
(") strings with identical semantics. Inside strings, all
characters except the closing quote and $ (macro substitution)
are treated literally. For example, the following two Kconfig strings are
the same:
"foo \"bar\" \$(baz)" 'foo "bar" \$(baz)'
A Kconfig file starts with zero or more macro variable
assignments (Macro Language) followed by zero or
more Kconfig definitions which may source (Source) other Kconfig files. Each
definition starts with a keyword. For example:
# This is a comment.
DEFAULT_GREETING := Hello
config GREETING
string "Custom greeting"
default "$(DEFAULT_GREETING)"
source "$(SRC_ROOT)/Kconfig"
The following synopsis lists all the available Kconfig definitions with
the subsequent sections explaining their semantics using examples from the
kconfig-hello
package. For additional background and details see also the official Kconfig
Language and Kconfig
Macro Language documentation as well as the Kconfig
Tips and Best Practices from the Zephyr project.
config symbol
type [prompt [if
expr]]
prompt prompt [if
expr]
default value [if
expr]
range integer
integer [if expr]
depends on expr
select symbol [if
expr]
imply symbol [if
expr]
help
text
if expr
...
endif
menu prompt
visible if expr
depends on expr
...
endmenu
menuconfig symbol
...
choice [symbol]
optional
default symbol [if
expr]
...
...
endchoice
comment prompt
depends on expr
source path
type = bool | string | int |
hex | tristate
value = (y|n) | string |
integer | (y|m|n)
string = "text" |
'text'
integer = dec-integer | 0xhex-integer
prompt = string
path = string
term = symbol | value
expr = term
|
term = term
|
term != term
|
term <
term |
term > term
|
term <=
term |
term >= term
|
( expr )
|
! expr
|
expr &&
expr |
expr ||
expr
3.1 Option (config)
config symbol
type [prompt [if
expr]]
prompt prompt [if
expr]
default value [if
expr]
range integer
integer [if expr]
depends on expr
select symbol [if
expr]
imply symbol [if
expr]
help
text
if expr
...
endif
type = bool | string | int |
hex | tristate
value = (y|n) | string |
integer | (y|m|n)
string = "text" |
'text'
integer = dec-integer | 0xhex-integer
prompt = string
term = symbol | value
expr = term
|
term = term
|
term != term
|
term <
term |
term > term
|
term <=
term |
term >= term
|
( expr )
|
! expr
|
expr &&
expr |
expr ||
expr
The central part of Kconfig is the configuration option definition
with the rest of the language is mostly serving to organize options into
sub-menus. A simple Kconfig file may consist of just option
definitions which all become entries of the implicitly-defined main menu
(discussed in the next section).
The option definition starts with the config keyword
followed by the option name, which in the Kconfig language is called a
symbol. For example:
config IO
bool "IO support"
help
Enable stdin/stdout input/output. Note that if this option
is disabled, then you won't see any output.
Other Kconfig documentation often uses the term symbol to mean the configuration option, not just its name.
The name is traditionally spelled in upper case and is the same name that
will end up in the configuration file but prefixed with CONFIG_
and as a Buildfile variable but converted into lower case and prefixed with
kconfig.<project>..
Following the config keyword and the name we have a number
of lines that define the option's attributes. They are traditionally
indented by 8 spaces (or an equivalent TAB). While none of the attributes
are mandatory, a definition will normally include at least the type and
usually also the prompt and help, as in the above example.
A number of attributes support the trailing
if expr condition. If specified, the attribute only
applies if the expression evaluates to true (Expressions). Such attributes can also be
specified multiple times. For example:
config GREETING_TEXT
string "Custom greeting" if GREETING_CUSTOM
default "Hello" if GREETING_HELLO
default "Hi" if GREETING_HI
default "Howdy" if GREETING_HOWDY
help
Custom string to use as a greeting.
In this example, the GREETING_TEXT option will only be
visible if the GREETING_CUSTOM option is selected and the
default value is chosen based on which GREETING_H* option is
selected.
3.1.1 Prompt and Help
config symbol
type [prompt [if
expr]]
prompt prompt [if
expr]
help
text
string = "text" |
'text'
prompt = string
The configuration option prompt is a short text that describes the option to the user while the option help provides a more detailed description. For example:
config IO
bool
prompt "IO support"
help
Enable stdin/stdout input/output. Note that if this option
is disabled, then you won't see any output.
If an option has a visible prompt (that is, the prompt is not disabled
with if expr) and its dependencies are satisfied
(Dependencies), then the option is presented
to the user for customization. For example:
$ b configure
IO support (IO) [N/y/?] (NEW) ?
CONFIG_IO:
Enable stdin/stdout input/output. Note that if this option
is disabled, then you won't see any output.
Symbol: IO [=n]
Type : bool
Defined at kconfig-hello/build/Kconfig:18
Prompt: IO support
Location:
-> Basic options
The option prompt can be specified with the prompt attribute
as in the above example or it can be combined with the type attribute for
brevity. For example:
config IO
bool "IO support"
...
This shorter version is customarily preferred unless selecting between
several prompts with if expr. In both versions the
prompt text can be specified using either single or double quotes.
The option help often contains several lines of text and is specified
indented (customarily with 2 spaces) relative to the line that contains the
help keyword. The help text ends at the line that has a smaller
indentation than the first line of the help text.
While an option with an invisible prompt cannot be modified by the user,
it can still be modified by other options through reverse dependencies and
its value is accessible via the corresponding kconfig.*
variable. An option with an absent prompt that is selected through such
reverse dependencies is called a helper option. See Helper Options for more information on their
use-cases.
3.1.2 Type, Default Value, and Range
config symbol
type [prompt [if
expr]]
default value [if
expr]
range integer
integer [if expr]
type = bool | string | int |
hex | tristate
value = (y|n) | string |
integer | (y|m|n)
string = "text" |
'text'
integer = dec-integer | 0xhex-integer
Configuration option type can be bool (boolean),
string, int (decimal integer), hex
(hexadecimal integer), and tristate:
bool- True or false state. Values of this type are spelled as
yorn, for example:config FOO bool default yWhen converted to the
kconfig.*variables, such values have theboolBuildfile type. string- Text string. Values of this type are spelled using either single or
double quotes, for example:
config FOO string default "foo"When converted to the
kconfig.*variables, such values have thestringBuildfile type. int- Signed 64-bit decimal integer. Values of this type are spelled as a
sequence of decimal digits, for example:
config FOO int default 123When converted to the
kconfig.*variables, such values have theint64Buildfile type. hex- Unsigned 64-bit hexadecimal integer. Values of this type are spelled as
a sequence of hexadecimal digits prefixed with
0x, for example:config FOO hex default 0x1ab2c3d4When converted to the
kconfig.*variables, such values have theuint64Buildfile type. tristate- Like
boolbut with an extra state (m) used to express modularity. See Modularity Support for details on this functionality.
The kconfig.* variables are overridable which means, similar
to the first-level configuration, we can temporarily tweak the Kconfig
configuration (as seen by buildfiles) without reconfiguring the
project. For example:
$ b kconfig.hello.io=false
Note, however, that such changes do not go through the usual Kconfig processing which, in particular, means no option dependency resolution is performed. As a result, care must be taken not to end up with an invalid configuration.
The default value for a configuration option can be specified with the
default attribute. For example:
config PUNCT
string "End of greeting punctuation"
default "!"
help
Character for punctuating the end of the greeting sentence.
This value will be used as the suggested answer in interactive
configurations methods and as a fallback in non-interactive ones (see Configuration Methods for details). If no
default value is specified, n is assumed for bool
and tristate and empty string for string while
there is no assumed default for int and hex.
While int and hex options without default
values are valid, creating a configuration in a way that would require
default values (for example with the config.kconfig=def method)
is an error.
Options of type int and hex can also specify
the expected value range with the range attribute (both ends
are inclusive). If specified, the user will not be allowed to enter a value
that is out of this range. For example:
config NAME_ASK_MAX
int "Max times to ask for name"
default 5
range 1 10
help
Maximum number of times to ask for the name to greet.
3.1.3 Dependencies
config symbol
depends on expr
if expr
...
endif
The depends on attribute is used to specify a
dependency of one option on another. Collectively, dependencies determine
what configurations are valid. For example:
config IO
bool "IO support"
config NAME_ASK
bool "Ask for name"
depends on IO
If an option's dependency is not satisfied, then the option becomes
disabled: the user is not prompted for its value and its default
value is not used. For bool and tristate, the
disabled option is set to n. For other types, the disabled
option's value is not set and the corresponding kconfig.*
variable is null.
We use the term enabled/disabled when we refer to the
option's state based on its dependencies and visible/invisible
– based on its prompt. An option is only presented to the user for
customization if it is both enabled and visible. If a bool
option is set to y, we call it selected.
The depends on attribute can also be used to specify a
dependency on an expression involving more than one option or non-boolean
options (see Expressions for details). For
example:
config IO
bool "IO support"
config RETRY
int "Max times to retry"
config NAME_ASK
bool "Ask for name"
depends on IO && RETRY != 0
Specifying multiple depends on attributes is equivalent
to specifying their expressions with a single depends on
attribute combined with &&. For example, this variant
is equivalent to the above:
config NAME_ASK
bool "Ask for name"
depends on IO
depends on RETRY != 0
If we have multiple options with the same dependency, then instead of
repeating the depends on attribute for each of them we can
use the if-block for a more succinct result. For example:
config IO
bool "IO support"
if IO
config NAME_ASK
bool "Ask for name"
config TRACE
bool "Trace execution"
endif
The semantics of the if-block is equivalent to specifying an
explicit depends on attribute with the
if-expression for each entry until endif.
3.1.4 Reverse Dependencies
config symbol
select symbol [if
expr]
imply symbol [if
expr]
A reverse dependency is used to select an option from another option. For example:
config IO
bool "IO support"
config NAME_ASK
bool "Ask for name"
select IO
In this example, if NAME_ASK is set to y, then
IO is forced to y as well.
Reverse dependencies can only be used with bool and
tristate options and there are two flavors: strong and
weak.
A strong reverse dependency is specified with the select
attribute. It forces the option specified after the select
keyword to y whenever the option containing this attribute is
set to y (for tristate options, the same logic
applies for m). And by forces we mean just that: it
disregards unsatisfied dependencies and user selection.
Note that this forceful nature of strong reverse dependencies often leads
to puzzling configuration issues. For example, a user may be trying to
unsuccessfully disable a feature without realizing that it is forced by
another, seemingly unrelated option. Such issues can be very frustrating and
time-consuming to figure out and, as a result, the use of reverse
dependencies on user-visible options is not recommended. Using
select on invisible options, however, is a useful technique as
described in Helper Options.
A weak reverse dependency is specified with the imply
attribute. As the name suggests, it does not force but merely recommends.
The other option can still be set to n by the user or if any of
its dependencies are unsatisfied. For example:
config IO
bool "IO support"
default y
imply NAME_ASK
config NAME_ASK
bool "Ask for name"
In this example, if the user selects y for IO,
then the prompt for NAME_ASK will also have y as
the default answer. However, the user can still disable
NAME_ASK by answering n. Similarly, if configuring
non-interactively using the default values
(config.kconfig=def), then NAME_ASK will be set to
y because IO is set to y (because of
its default y attribute).
3.1.5 Expressions
value = (y|n) |
string | integer | (y|m|n)
string = "text" |
'text'
integer = dec-integer | 0xhex-integer
term = symbol | value
expr = term
|
term = term
|
term != term
|
term <
term |
term > term
|
term <=
term |
term >= term
|
( expr )
|
! expr
|
expr &&
expr |
expr ||
expr
Kconfig expressions are used in a number of option attributes to
determine visibility, establish dependencies, and to enable default values.
And as we will see in later sections, they are also used for similar
purposes in other Kconfig definitions. The result of evaluating an
expression is boolean y (true) or n (false).
More precisely, Kconfig expressions use the tristate logic with the extra
m state used to represent modularity. For the evaluation
purposes, the m state is equivalent to y if
modules are enabled. See Modularity Support for
details.
Expression alternatives in the above production are listed in the
decreasing order of precedence. Values in expressions are spelled as in the
default attribute (Type,
Default Value, and Range).
A terminal expression consisting of a symbol evaluates to true if the
corresponding option is of type bool (or tristate)
and is y (or m and modules are enabled). In this
context options of all other types always evaluate to n.
A terminal expression consisting of a value evaluates to true if it is
either y or "y" (or m or
"m" and modules are enabled). For example See External Kconfig Macro
Variables for a more realistic example:
ENABLE_FANCY := y
config IO
bool "IO support"
config FANCY
bool "Fancy options"
depends on IO
depends on $(ENABLE_FANCY)
Terminals (symbol or value) can be compared for being equal/unequal less/greater, and less-or-equal/greater-or-equal. Finally, sub-expression can be grouped with parenthesis, negated, and combined with logical AND and OR. For example:
FALLBACK_NAME := ...
config IO
bool "IO support"
config RETRY
int "Max times to retry"
config NAME_ASK
bool "Ask for name"
depends on IO && (RETRY != 0 || "$(FALLBACK_NAME)" = "")
3.2 Menu (menu)
menu prompt
visible if expr
depends on expr
...
endmenu
menuconfig symbol
...
Menus are used to organize options into a tree-like hierarchy as an aid to the user. Normally a menu would contain related options. If a menu contains a large number of options, then some of them can be organized into sub-menus and so on.
The menu definition starts with the menu keyword followed by
the menu prompt. Similar to an option, a menu may specify a number of
attributes on the following lines. After the menu definition and before the
matching endmenu keyword, any option, sub-menu, etc., all
belong to this menu and are collectively called menu entries. For
example:
menu "Basic options"
config IO
bool "IO support"
help
Enable stdin/stdout input/output. Note that if this option
is disabled, then you won't see any output.
config PUNCT
string "End of greeting punctuation"
default "!"
help
Character for punctuating the end of the greeting sentence.
endmenu
Similar to option prompts, menu prompts are presented to the user during option customization. For example:
$ b configure * * Basic options * IO support (IO) [N/y/?] (NEW) y End of greeting punctuation (PUNCT) [!] (NEW) !!!
The menu visibility can be controlled with the
visible if attribute. If its expression evaluates to
false, then neither the menu itself nor any of its entries are presented to
the user. For example:
menu "Fancy options"
visible if IO
...
endmenu
Menu visibility is the extension of the option prompt visibility in that an option that belongs to an invisible menu has the same semantics as if it had an invisible prompt (Prompt and Help).
Another attribute of a menu definition is depends on.
Specifying this attribute is equivalent to specifying it for every option
that belongs to this menu, recursively (Dependencies).
The Kconfig menu hierarchy always starts with an implicitly-defined main
menu. While it is possible to customize its prompt in the
Kconfig file using the mainmenu definition,
customarily it is set to the project name and version which the
kconfig module does automatically. It can also be customized by
setting the kconfig.kconfig.title variable in
root.build before loading the kconfig module.
Specifying mainmenu in the Kconfig file is not
recommended when used with build2 because there can only be one
such definition thus making the result non-composable. And there are plans
for the kconfig module to automatically aggregate Kconfig
configurations of multiple projects into a single configurator
invocation.
When organizing options into menus we often encounter a pattern where a configuration option enables a menu, for example:
config FANCY
bool "Fancy options"
help
Enable more fancy configuration options.
menu "Fancy options"
depends on FANCY
config GREETING
string "Custom greeting"
help
Custom string to use as a greeting.
config NAME_ASK
bool "Ask for name"
help
Ask for the name to greet if it is unspecified on the
command line.
endmenu
Regardless of how we structure this (option outside or inside the menu),
the user interface will have a separate entry for the option and the menu
while what we want here is to combine them. To achieve this we use the
menuconfig hybrid menu/option. For example:
menuconfig FANCY
bool "Fancy options"
help
Enable more fancy configuration options.
if FANCY
config GREETING
string "Custom greeting"
...
config NAME_ASK
bool "Ask for name"
...
endif
The menuconfig definition has the same semantics and
attributes as config but additionally establishes a sub-menu
and treats all the following entries (options, menus) that have a dependency
on its symbols as sub-menu entries until encountering the first entry
without such a dependency. The common approach to establish such a
dependency is to use the if-block as in the example above.
If you are wondering why menuconfig does not use an explicit
end marker similar to endmenu, you are not alone. It is
probably a remnant of the automatic menu generation described next.
Even if we didn't use menuconfig in the above example,
Kconfig would analyze the dependency relationship and generate a menu-like
structure automatically. Specifically, all the immediately following entries
that have a dependency on the preceding option are treated as its
sub-entries and displayed as belonging to this option. What "displayed as
belonging" means, exactly, depends on the configurator and in some it may be
indistinguishable from menuconfig.
3.3 Choice (choice)
choice [symbol]
optional
default symbol [if
expr]
...
...
endchoice
Choices are used to restrict the selection to the at most one option from a set. In a way, they can be viewed as a variant of the menu concept but where instead of all the options the user can select only one.
The choice definition starts with the choice keyword
optionally followed by the choice name. Similar to options and menus, a
choice may specify a number of attributes on the following lines. After the
choice definition and before the matching endchoice keyword
comes a number of options (normally two or more) collectively called
choice options. Choice options can only be of type bool
and tristate. For example:
choice
prompt "Greeting"
default GREETING_HELLO
help
String to use as a greeting.
config GREETING_HELLO
bool "\"Hello\""
select GREETING_BUILTIN
config GREETING_HI
bool "\"Hi\""
select GREETING_BUILTIN
config GREETING_HOWDY
bool "\"Howdy\""
select GREETING_BUILTIN
config GREETING_CUSTOM
bool "Custom greeting"
endchoice
Given the above choice, the user could be presented with the following interface:
$ b configure Greeting > 1. "Hello" (GREETING_HELLO) (NEW) 2. "Hi" (GREETING_HI) (NEW) 3. "Howdy" (GREETING_HOWDY) (NEW) 4. Custom greeting (GREETING_CUSTOM) (NEW) choice[1-4?]:
Choices with tristate options allow selecting multiple
options provided they are all set to m. See Modularity Support for details.
Two commonly used choice attributes are default and
optional. The default attribute is used to specify
the default selection as shown in the example above. The
optional attribute makes the choice optional allowing the user
not to select any of the choice options.
A non-optional choice without a default value will currently result in an
invalid configuration if configuring non-interactively using the default
values (config.kconfig=def). As a result, it is recommended to
always specify default values for non-optional choices.
A choice definition can specify any of the other configuration option attributes, however, not all of them make sense in all situations. In practice, there are two common patterns of choice usage: a simple choice without a name and an optional choice with a name. Here is the overall structure of the first pattern (which is also used in the above example):
choice
prompt "Prompt text"
default DEFAULT_OPTION
...
endchoice
In the second pattern, the optional choice is given a name that is used as a helper (Helper Options) to determine whether any of the choice options were selected. Such a choice may or may not have the default value. Here is its overall structure:
choice CHOICE_NAME
bool "Prompt text"
optional
default DEFAULT_OPTION
...
endchoice
And here is a concrete example of such a choice:
choice NAME_FALLBACK
bool "Name fallback"
optional
help
Fallback name to use if it is unspecified on the command
line.
config NAME_ASK
bool "Ask for name"
help
Ask for the name to greet if it is unspecified on the
command line.
config NAME_DEF
bool "Use default name"
help
Use the default name to greet if it is unspecified on the
command line.
endchoice
At the Buildfile level we can then use
kconfig.<project>.name_fallback to determine if any of the
choice options were selected, for example:
if $kconfig.hello.name_fallback
{
if $kconfig.hello.name_ask
...
if $kconfig.hello.name_def
...
}
3.4 Comment (comment)
comment prompt
depends on expr
A comment is used to add a notice to the user during configuration. It is also written into the resulting configuration file.
The comment definition starts with the comment keyword
followed by the comment prompt (text). For example:
comment "IO disabled, no output will be shown"
depends on !IO
Similar to other entries, a comment may specify a number of attributes on
the following lines. Currently the only valid comment attribute is
depends on which can be used to make a comment
conditional, as shown in the example above.
3.5 Source (source)
source path
path = string
The source definition is used to source (include) one
Kconfig file into another. It starts with the
source keyword followed by the path string.
For example, if you would like your Kconfig file to reside
in the root directory of your project (which is customary in several
projects that use Kconfig, including the Linux kernel), then you can place
the following line in your build/Kconfig and then write the
rest of the definitions in the root Kconfig:
source "$(SRC_ROOT)/Kconfig"
As mentioned in External Kconfig Macro
Variables, SRC_ROOT is the pre-defined variable that
contains the project's source root directory (the same as
src_root in buildfiles). It should normally be
used as a base for all your source definitions.
While we can specify a relative path to source, the historic Kconfig
semantics is to first try to open such a path relative to the current
working directory. Since build2 does not assume any particular
current working directory, the use of absolute paths based on
SRC_ROOT is strongly recommended.
Note also that on Windows all Kconfig paths use forward slashes as
directory separators, including the SRC_ROOT macro variable.
You should also use the forward slashes when forming paths based on
SRC_ROOT, as in the above example.
As another example, consider the following Kconfig fragment
which is commonly misunderstood:
if IO source "$(SRC_ROOT)/build/Kconfig-io" endif
This is not a conditional inclusion. Rather, it is an unconditional
inclusion with all the definitions inside Kconfig-io now
depending on IO (Dependencies).
There is no conditional inclusion in Kconfig nor, more generally, any
ability to conditionally exclude a fragment of the Kconfig
file. The closest we can get is probably a conditional selection of the file
to source based on the external macro variable. For example, in our
root.build we could have the following fragment:
using cxx Kconfig.PLATFORM = $cxx.target.class using kconfig
And then in the Kconfig file write the following which would
include Kconfig-linux, Kconfig-windows, etc.,
depending on the platform we are targeting:
source "$(SRC_ROOT)/build/Kconfig-$(PLATFORM)"
Note also that if you are using this technique, then you will need to
explicitly mention such Kconfig-* files as prerequsites in a
buildfile in order for them to be included into the
distribution. For example, in your root buildfile you could
have:
./: ... build/file{Kconfig-*}
3.6 Macro Language
The Kconfig language provides support for make-like macro
substitution. Conceptually, there are two languages layered one on top of
the other: the bottom layer is the macro language that performs plain
textual substitutions. The result is then used as input to the top layer,
which is the Kconfig definition language. For example:
DEFAULT_GREETING := Hey there
config GREETING
string "Custom greeting"
default "$(DEFAULT_GREETING)"
After the macro substitution, the top layer will see:
config GREETING
string "Custom greeting"
default "Hey there"
Macro substitutions can appear in pretty much any context, including prompts, default values, expressions, and so on. It is, however, important to keep in mind that macro variable names and option names/symbols operate in different languages. In particular, while a macro variable can contain an option name (symbol) it cannot contain an "expansion" (that is, a value) of an option. For example, the following does not make sense:
GREETING_VALUE = $(GREETING)
config GREETING
string "Custom greeting"
default "Hello"
While this conceptual model is helpful as an understanding aid, this is not exactly how the implementation works and there are some restrictions. Specifically, Kconfig keywords cannot be the result of the macro substitution nor can substitutions span multiple Kconfig tokens. Refer to the official Kconfig Macro Language documentation for details.
Macro variables can only be assigned at the beginning of a
Kconfig file before any Kconfig definitions (options, menus,
etc). Similar to make, there is no need to quote values in a
macro variable assignment unless we want the value to contain literal
quotes. For example, this version is equivalent to the above:
DEFAULT_GREETING := "Hey there"
config GREETING
string "Custom greeting"
default $(DEFAULT_GREETING)
During substitution, the corresponding value is first looked up in the
variable assignments of the Kconfig file. If not found, then
the value is looked up in the Kconfig.* Buildfile variables
with SRC_ROOT being the only pre-defined variable (see External Kconfig Macro Variables for
details). An undefined variable substitution is an error.
For example, instead of setting DEFAULT_GREETING in the
Kconfig file as above, we could set it from
root.build:
Kconfig.DEFAULT_GREETING = '"Hey there"' using kconfig
As another example, we can pass the platform we are targeting as a macro variable:
using cxx Kconfig.PLATFORM = $cxx.target.class using kconfig
And then use it in Kconfig to conditionally enable options,
choose their default values, and so on:
config IO
bool "IO support"
depends on "$(PLATFORM)" != "windows"
config GREETING
string "Custom greeting"
default "Hey" if "$(PLATFORM)" = "linux"
default "Hello"
comment "Targeting $(PLATFORM)"
Note also that due to the two-layer textual substitution semantics all variable references are always substituted. For example:
config GREETING
string "Custom greeting"
default $(DEFAULT_GREETING_IO) if IO
default $(DEFAULT_GREETING) if !IO
In this example, both DEFAULT_GREETING and
DEFAULT_GREETING_IO must always be defined regardless of which
default value is (later) used.
Similar to make, Kconfig supports both simple and
recursively-expanding variables with the latter used as a building block to
support functions. For details, refer to the official Kconfig
Macro Language documentation.
The use of the builtin shell function in the context of
build2 is not recommended since it will most likely result in
portability issues and poor performance.
3.7 Helper Options
An option without a prompt or with a prompt that is disabled by if
expr is invisible to the user. However, such an option can
still take on a default value or be set by select and
imply (Reverse Dependencies)
with the result still usable inside the Kconfig file, for
example, for other option's dependencies, as well as accessible outside
through the kconfig.* Buildfile variables. Such options are
called helper options. For example:
choice
prompt "Greeting"
default GREETING_HELLO
config GREETING_HELLO
bool "\"Hello\""
select GREETING_BUILTIN
config GREETING_HI
bool "\"Hi\""
select GREETING_BUILTIN
config GREETING_HOWDY
bool "\"Howdy\""
select GREETING_BUILTIN
config GREETING_CUSTOM
bool "Custom greeting"
endchoice
config GREETING_BUILTIN
bool
In this example GREETING_BUILTIN is a helper option that is
set to true when one of the builtin greeting strings is selected. It can
then be used as a dependency for another option, for example:
config PUNCT
string "End of greeting punctuation"
default "!"
depends on !GREETING_BUILTIN
help
Character for punctuating the end of the custom greeting
sentence.
Continuing with the above example, here is another option that becomes a helper if we are using one of the builtin greeting strings:
config GREETING_TEXT
string "Custom greeting" if GREETING_CUSTOM
default "Hello" if GREETING_HELLO
default "Hi" if GREETING_HI
default "Howdy" if GREETING_HOWDY
help
Custom string to use as a greeting.
The idea here is that now we have an option that contains the greeting
string in both the builtin and custom cases. As a result, instead of having
to write something like this in our buildfile:
if $kconfig.hello.greeting_builtin
{
if $kconfig.hello.greeting_hello
greeting = 'Hello'
elif $kconfig.hello.greeting_hi
greeting = 'Hi'
elif $kconfig.hello.greeting_howdy
greeting = 'Howdy'
else
fail 'unhandled builtin greeting'
}
else
greeting = $kconfig.hello.greeting_text
We can just have:
greeting = $kconfig.hello.greeting_text
3.8 Modularity Support
The Kconfig language provides support for configuration options that
besides being selected (y) or not (n) can also be
selected as a module (m).
While it may be tempting to try to re-purpose this support for something similar but not quite the same, modularity in Kconfig is fairly purpose-built for the Linux kernel needs and straying too far from its intended semantics will likely result in a poor fit.
The central part of this functionality is the tristate type
which, in addition to the bool's y and
n states, has the third m state. When converted to
the kconfig.* variables, tristate is mapped to the
string Buildfile type with the true,
false, and module possible values.
The availability of this third state is also gated by the
specially-designated bool option that determines whether
overall modules support is enabled. Similarly, in expressions (Expressions) m is equivalent to
y only if modules are enabled. For example:
config MODULES
bool "Modules support"
modules
config IO
tristate "IO support"
In the above example, MODULES is designated as the modules
option with the modules attribute. If we answer y
to MODULES, then for IO we will be able to choose
between y, m, and n. However, if
MODULES is n, then our choice for IO
will be between y and n:
$ b configure Modules support (MODULES) [Y/n/?] (NEW) y IO support (IO) [N/m/y/?] (NEW) $ b configure Modules support (MODULES) [Y/n/?] (NEW) n IO support (IO) [N/y/?] (NEW)
If we want to unconditionally enable modules in our project, then we can
make the MODULES option prompt-less with y
default, for example:
config MODULES
bool
default y
modules
Only one configuration option can be designated as the module option. This makes it difficult to compose project configuration that use this functionality.
Besides normal options, tristate can also be used in
choices. Such a choice allows the user to select only one option as
y but more than one as m (again, provided modules
are enabled). For example:
choice
prompt "Name fallback"
config NAME_ASK
tristate "Ask for name"
help
Ask for the name to greet if it is unspecified on the
command line.
config NAME_DEF
tristate "Use default name"
help
Use the default name to greet if it is unspecified on the
command line.
endchoice
3.9 Backwards Compatibility
It is typical and well supported by Kconfig to reuse an old configuration when upgrading to a new version of the project (see Configuration Methods for details). As a result, when evolving a project that uses Kconfig, it makes sense to keep backwards compatibility in mind.
Besides a full old configuration, users of our project can also
keep minimal default configurations produced with kconfig-conf
--savedefconfig. Unlike the full configuration which contains all the
values, default configurations only contain values that differ from the
defaults. Based on this understanding, these changes normally lead to
reasonable backwards compatibility:
- Adding new or removing/renaming existing options.
- Moving options around or organizing them into sub-menus.
- Changing dependencies and visibility of existing options, menus, etc.
- Changing prompt or help of existing options, menus, etc.
In contrast, these changes should normally be avoided:
- Changing type of existing options.
- Changing default value or range of existing options.
- Removing existing options from non-optional choices that do not specify a default value.