build2
Kconfig ModuleRevision 0.3.0
, June 2024
This revision of the document describes the build2
Kconfig module 0.3.X
series.
Copyright © 2020-2023 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.kconfig
file. - Default configuration file.
- Default value from the
Kconfig
file.
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
file
if specified and to their default values fromKconfig
otherwise (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
file
if specified and default values fromKconfig
otherwise.Note that if
config.kconfig
does 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.kconfig
if exists, fromfile
if specified, and default values fromKconfig
otherwise. mconf
- Present all the configuration options in a menu interface. For default
answers, use values from
config.kconfig
if exists and default values fromKconfig
otherwise. qconf
- Present all the configuration options in a graphical interface. For
default answers, use values from
config.kconfig
if exists and default values fromKconfig
otherwise. env prog [args]
- Run
prog
in the configuration environment (KCONFIG_CONFIG
, etc) passing theKconfig
file 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-
configure
callback with theconfig
module. root.build
- Run the configurator saving the result to
config.kconfig.new
. configure
- In post-
configure
renameconfig.kconfig.new
toconfig.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
y
orn
, for example:config FOO bool default y
When converted to the
kconfig.*
variables, such values have thebool
Buildfile 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 thestring
Buildfile 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 123
When converted to the
kconfig.*
variables, such values have theint64
Buildfile 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 0x1ab2c3d4
When converted to the
kconfig.*
variables, such values have theuint64
Buildfile type. tristate
- Like
bool
but 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.