← Documents Documentation/kbuild/kconfig-language.rst GitHub 원문 ↗

Linux 6.18.37 · Kbuild

Kconfig Language

Kconfig symbol 속성, tristate dependency, menu 문법, 권장 idiom, recursive dependency 한계와 semantics·SAT 연구를 설명합니다.

Source pathDocumentation/kbuild/kconfig-language.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

kconfig-language.rst:1-811

Kconfig는 `n/m/y` tristate logic으로 symbol의 visibility와 허용 범위를 계산합니다. `depends on`은 상한, `select`는 dependency를 우회하는 강제 하한, `imply`는 사용자가 낮출 수 있는 약한 하한이므로 목적에 맞게 구분해야 합니다.

Kconfig 설계 핵심
영역원칙
Default대부분 `n`, 기존 동작 유지에만 제한적 `y/m`
Reverse dependency`select`는 prompt·dependency 없는 내부 symbol에 제한
CapabilityArchitecture는 `HAVE_*`를 select, 사용자 option은 depends
Compile coverage실행 안전성을 지키며 `|| COMPILE_TEST`
Optional moduleBuilt-in → loadable 조합을 `BAR || !BAR`로 차단
Recursion불필요한 edge 제거 또는 select/depends semantics 통일

문서 전체에서 반복되는 안전한 작성 원칙입니다.

Symbol visibility
Parent menu visibilitySymbol `depends on` expressionPrompt의 optional `if`Expression이 `m` 또는 `y`인지 판정Visible하면 사용자 입력, 아니면 default/select로만 값 결정

Tree와 expression이 함께 최종 표시 여부를 결정합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ================
2 Kconfig Language
3 ================
4
5 Introduction
6 ------------
7
8 The configuration database is a collection of configuration options
9 organized in a tree structure::
10
11 +- Code maturity level options
12 | +- Prompt for development and/or incomplete code/drivers
13 +- General setup
14 | +- Networking support
15 | +- System V IPC
16 | +- BSD Process Accounting
17 | +- Sysctl support
18 +- Loadable module support
19 | +- Enable loadable module support
20 | +- Set version information on all module symbols
21 | +- Kernel module loader
22 +- ...
23
24 Every entry has its own dependencies. These dependencies are used
25 to determine the visibility of an entry. Any child entry is only
26 visible if its parent entry is also visible.
27
28 Menu entries
29 ------------
30
31 Most entries define a config option; all other entries help to organize
32 them. A single configuration option is defined like this::
33
34 config MODVERSIONS
35 bool "Set version information on all module symbols"
36 depends on MODULES
37 help
38 Usually, modules have to be recompiled whenever you switch to a new
39 kernel. ...
40
41 Every line starts with a key word and can be followed by multiple
42 arguments. "config" starts a new config entry. The following lines
43 define attributes for this config option. Attributes can be the type of
44 the config option, input prompt, dependencies, help text and default
45 values. A config option can be defined multiple times with the same
46 name, but every definition can have only a single input prompt and the
47 type must not conflict.
48
49 Menu attributes
50 ---------------
51
52 A menu entry can have a number of attributes. Not all of them are
53 applicable everywhere (see syntax).
54
55 - type definition: "bool"/"tristate"/"string"/"hex"/"int"
56
57 Every config option must have a type. There are only two basic types:
58 tristate and string; the other types are based on these two. The type
59 definition optionally accepts an input prompt, so these two examples
60 are equivalent::
61
62 bool "Networking support"
63
64 and::
65
66 bool
67 prompt "Networking support"
68
69 - input prompt: "prompt" <prompt> ["if" <expr>]
70
71 Every menu entry can have at most one prompt, which is used to display
72 to the user. Optionally dependencies only for this prompt can be added
73 with "if". If a prompt is not present, the config option is a non-visible
74 symbol, meaning its value cannot be directly changed by the user (such as
75 altering the value in ``.config``) and the option will not appear in any
76 config menus. Its value can only be set via "default" and "select" (see
77 below).
78
79 - default value: "default" <expr> ["if" <expr>]
80
81 A config option can have any number of default values. If multiple
82 default values are visible, only the first defined one is active.
83 Default values are not limited to the menu entry where they are
84 defined. This means the default can be defined somewhere else or be
85 overridden by an earlier definition.
86 The default value is only assigned to the config symbol if no other
87 value was set by the user (via the input prompt above). If an input
88 prompt is visible the default value is presented to the user and can
89 be overridden by him.
90 Optionally, dependencies only for this default value can be added with
91 "if".
92
93 The default value deliberately defaults to 'n' in order to avoid bloating the
94 build. With few exceptions, new config options should not change this. The
95 intent is for "make oldconfig" to add as little as possible to the config from
96 release to release.
97
98 Note:
99 Things that merit "default y/m" include:
100
101 a) A new Kconfig option for something that used to always be built
102 should be "default y".
103
104 b) A new gatekeeping Kconfig option that hides/shows other Kconfig
105 options (but does not generate any code of its own), should be
106 "default y" so people will see those other options.
107
108 c) Sub-driver behavior or similar options for a driver that is
109 "default n". This allows you to provide sane defaults.
110
111 d) Hardware or infrastructure that everybody expects, such as CONFIG_NET
112 or CONFIG_BLOCK. These are rare exceptions.
113
114 - type definition + default value::
115
116 "def_bool"/"def_tristate" <expr> ["if" <expr>]
117
118 This is a shorthand notation for a type definition plus a value.
119 Optionally dependencies for this default value can be added with "if".
120
121 - dependencies: "depends on" <expr>
122
123 This defines a dependency for this menu entry. If multiple
124 dependencies are defined, they are connected with '&&'. Dependencies
125 are applied to all other options within this menu entry (which also
126 accept an "if" expression), so these two examples are equivalent::
127
128 bool "foo" if BAR
129 default y if BAR
130
131 and::
132
133 depends on BAR
134 bool "foo"
135 default y
136
137 - reverse dependencies: "select" <symbol> ["if" <expr>]
138
139 While normal dependencies reduce the upper limit of a symbol (see
140 below), reverse dependencies can be used to force a lower limit of
141 another symbol. The value of the current menu symbol is used as the
142 minimal value <symbol> can be set to. If <symbol> is selected multiple
143 times, the limit is set to the largest selection.
144 Reverse dependencies can only be used with boolean or tristate
145 symbols.
146
147 Note:
148 select should be used with care. select will force
149 a symbol to a value without visiting the dependencies.
150 By abusing select you are able to select a symbol FOO even
151 if FOO depends on BAR that is not set.
152 In general use select only for non-visible symbols
153 (no prompts anywhere) and for symbols with no dependencies.
154 That will limit the usefulness but on the other hand avoid
155 the illegal configurations all over.
156
157 If "select" <symbol> is followed by "if" <expr>, <symbol> will be
158 selected by the logical AND of the value of the current menu symbol
159 and <expr>. This means, the lower limit can be downgraded due to the
160 presence of "if" <expr>. This behavior may seem weird, but we rely on
161 it. (The future of this behavior is undecided.)
162
163 - weak reverse dependencies: "imply" <symbol> ["if" <expr>]
164
165 This is similar to "select" as it enforces a lower limit on another
166 symbol except that the "implied" symbol's value may still be set to n
167 from a direct dependency or with a visible prompt.
168
169 Given the following example::
170
171 config FOO
172 tristate "foo"
173 imply BAZ
174
175 config BAZ
176 tristate "baz"
177 depends on BAR
178
179 The following values are possible:
180
181 === === ============= ==============
182 FOO BAR BAZ's default choice for BAZ
183 === === ============= ==============
184 n y n N/m/y
185 m y m M/y/n
186 y y y Y/m/n
187 n m n N/m
188 m m m M/n
189 y m m M/n
190 y n * N
191 === === ============= ==============
192
193 This is useful e.g. with multiple drivers that want to indicate their
194 ability to hook into a secondary subsystem while allowing the user to
195 configure that subsystem out without also having to unset these drivers.
196
197 Note: If the feature provided by BAZ is highly desirable for FOO,
198 FOO should imply not only BAZ, but also its dependency BAR::
199
200 config FOO
201 tristate "foo"
202 imply BAR
203 imply BAZ
204
205 Note: If "imply" <symbol> is followed by "if" <expr>, the default of <symbol>
206 will be the logical AND of the value of the current menu symbol and <expr>.
207 (The future of this behavior is undecided.)
208
209 - limiting menu display: "visible if" <expr>
210
211 This attribute is only applicable to menu blocks, if the condition is
212 false, the menu block is not displayed to the user (the symbols
213 contained there can still be selected by other symbols, though). It is
214 similar to a conditional "prompt" attribute for individual menu
215 entries. Default value of "visible" is true.
216
217 - numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
218
219 This allows to limit the range of possible input values for int
220 and hex symbols. The user can only input a value which is larger than
221 or equal to the first symbol and smaller than or equal to the second
222 symbol.
223
224 - help text: "help"
225
226 This defines a help text. The end of the help text is determined by
227 the indentation level, this means it ends at the first line which has
228 a smaller indentation than the first line of the help text.
229
230 - module attribute: "modules"
231 This declares the symbol to be used as the MODULES symbol, which
232 enables the third modular state for all config symbols.
233 At most one symbol may have the "modules" option set.
234
235 - transitional attribute: "transitional"
236 This declares the symbol as transitional, meaning it should be processed
237 during configuration but omitted from newly written .config files.
238 Transitional symbols are useful for backward compatibility during config
239 option migrations - they allow olddefconfig to process existing .config
240 files while ensuring the old option doesn't appear in new configurations.
241
242 A transitional symbol:
243 - Has no prompt (is not visible to users in menus)
244 - Is processed normally during configuration (values are read and used)
245 - Can be referenced in default expressions of other symbols
246 - Is not written to new .config files
247 - Cannot have any other properties (it is a pass-through option)
248
249 Example migration from OLD_NAME to NEW_NAME::
250
251 config NEW_NAME
252 bool "New option name"
253 default OLD_NAME
254 help
255 This replaces the old CONFIG_OLD_NAME option.
256
257 config OLD_NAME
258 bool
259 transitional
260 help
261 Transitional config for OLD_NAME to NEW_NAME migration.
262
263 With this setup, existing .config files with "CONFIG_OLD_NAME=y" will
264 result in "CONFIG_NEW_NAME=y" being set, while CONFIG_OLD_NAME will be
265 omitted from newly written .config files.
266
267 Menu dependencies
268 -----------------
269
270 Dependencies define the visibility of a menu entry and can also reduce
271 the input range of tristate symbols. The tristate logic used in the
272 expressions uses one more state than normal boolean logic to express the
273 module state. Dependency expressions have the following syntax::
274
275 <expr> ::= <symbol> (1)
276 <symbol> '=' <symbol> (2)
277 <symbol> '!=' <symbol> (3)
278 <symbol1> '<' <symbol2> (4)
279 <symbol1> '>' <symbol2> (4)
280 <symbol1> '<=' <symbol2> (4)
281 <symbol1> '>=' <symbol2> (4)
282 '(' <expr> ')' (5)
283 '!' <expr> (6)
284 <expr> '&&' <expr> (7)
285 <expr> '||' <expr> (8)
286
287 Expressions are listed in decreasing order of precedence.
288
289 (1) Convert the symbol into an expression. Boolean and tristate symbols
290 are simply converted into the respective expression values. All
291 other symbol types result in 'n'.
292 (2) If the values of both symbols are equal, it returns 'y',
293 otherwise 'n'.
294 (3) If the values of both symbols are equal, it returns 'n',
295 otherwise 'y'.
296 (4) If value of <symbol1> is respectively lower, greater, lower-or-equal,
297 or greater-or-equal than value of <symbol2>, it returns 'y',
298 otherwise 'n'.
299 (5) Returns the value of the expression. Used to override precedence.
300 (6) Returns the result of (2-/expr/).
301 (7) Returns the result of min(/expr/, /expr/).
302 (8) Returns the result of max(/expr/, /expr/).
303
304 An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
305 respectively for calculations). A menu entry becomes visible when its
306 expression evaluates to 'm' or 'y'.
307
308 There are two types of symbols: constant and non-constant symbols.
309 Non-constant symbols are the most common ones and are defined with the
310 'config' statement. Non-constant symbols consist entirely of alphanumeric
311 characters or underscores.
312 Constant symbols are only part of expressions. Constant symbols are
313 always surrounded by single or double quotes. Within the quote, any
314 other character is allowed and the quotes can be escaped using '\'.
315
316 Menu structure
317 --------------
318
319 The position of a menu entry in the tree is determined in two ways. First
320 it can be specified explicitly::
321
322 menu "Network device support"
323 depends on NET
324
325 config NETDEVICES
326 ...
327
328 endmenu
329
330 All entries within the "menu" ... "endmenu" block become a submenu of
331 "Network device support". All subentries inherit the dependencies from
332 the menu entry, e.g. this means the dependency "NET" is added to the
333 dependency list of the config option NETDEVICES.
334
335 The other way to generate the menu structure is done by analyzing the
336 dependencies. If a menu entry somehow depends on the previous entry, it
337 can be made a submenu of it. First, the previous (parent) symbol must
338 be part of the dependency list and then one of these two conditions
339 must be true:
340
341 - the child entry must become invisible, if the parent is set to 'n'
342 - the child entry must only be visible, if the parent is visible::
343
344 config MODULES
345 bool "Enable loadable module support"
346
347 config MODVERSIONS
348 bool "Set version information on all module symbols"
349 depends on MODULES
350
351 comment "module support disabled"
352 depends on !MODULES
353
354 MODVERSIONS directly depends on MODULES, this means it's only visible if
355 MODULES is different from 'n'. The comment on the other hand is only
356 visible when MODULES is set to 'n'.
357
358
359 Kconfig syntax
360 --------------
361
362 The configuration file describes a series of menu entries, where every
363 line starts with a keyword (except help texts). The following keywords
364 end a menu entry:
365
366 - config
367 - menuconfig
368 - choice/endchoice
369 - comment
370 - menu/endmenu
371 - if/endif
372 - source
373
374 The first five also start the definition of a menu entry.
375
376 config::
377
378 "config" <symbol>
379 <config options>
380
381 This defines a config symbol <symbol> and accepts any of above
382 attributes as options.
383
384 menuconfig::
385
386 "menuconfig" <symbol>
387 <config options>
388
389 This is similar to the simple config entry above, but it also gives a
390 hint to front ends, that all suboptions should be displayed as a
391 separate list of options. To make sure all the suboptions will really
392 show up under the menuconfig entry and not outside of it, every item
393 from the <config options> list must depend on the menuconfig symbol.
394 In practice, this is achieved by using one of the next two constructs::
395
396 (1):
397 menuconfig M
398 if M
399 config C1
400 config C2
401 endif
402
403 (2):
404 menuconfig M
405 config C1
406 depends on M
407 config C2
408 depends on M
409
410 In the following examples (3) and (4), C1 and C2 still have the M
411 dependency, but will not appear under menuconfig M anymore, because
412 of C0, which doesn't depend on M::
413
414 (3):
415 menuconfig M
416 config C0
417 if M
418 config C1
419 config C2
420 endif
421
422 (4):
423 menuconfig M
424 config C0
425 config C1
426 depends on M
427 config C2
428 depends on M
429
430 choices::
431
432 "choice"
433 <choice options>
434 <choice block>
435 "endchoice"
436
437 This defines a choice group and accepts "prompt", "default", "depends on", and
438 "help" attributes as options.
439
440 A choice only allows a single config entry to be selected.
441
442 comment::
443
444 "comment" <prompt>
445 <comment options>
446
447 This defines a comment which is displayed to the user during the
448 configuration process and is also echoed to the output files. The only
449 possible options are dependencies.
450
451 menu::
452
453 "menu" <prompt>
454 <menu options>
455 <menu block>
456 "endmenu"
457
458 This defines a menu block, see "Menu structure" above for more
459 information. The only possible options are dependencies and "visible"
460 attributes.
461
462 if::
463
464 "if" <expr>
465 <if block>
466 "endif"
467
468 This defines an if block. The dependency expression <expr> is appended
469 to all enclosed menu entries.
470
471 source::
472
473 "source" <prompt>
474
475 This reads the specified configuration file. This file is always parsed.
476
477 mainmenu::
478
479 "mainmenu" <prompt>
480
481 This sets the config program's title bar if the config program chooses
482 to use it. It should be placed at the top of the configuration, before any
483 other statement.
484
485 '#' Kconfig source file comment:
486
487 An unquoted '#' character anywhere in a source file line indicates
488 the beginning of a source file comment. The remainder of that line
489 is a comment.
490
491
492 Kconfig hints
493 -------------
494 This is a collection of Kconfig tips, most of which aren't obvious at
495 first glance and most of which have become idioms in several Kconfig
496 files.
497
498 Adding common features and make the usage configurable
499 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
500 It is a common idiom to implement a feature/functionality that are
501 relevant for some architectures but not all.
502 The recommended way to do so is to use a config variable named HAVE_*
503 that is defined in a common Kconfig file and selected by the relevant
504 architectures.
505 An example is the generic IOMAP functionality.
506
507 We would in lib/Kconfig see::
508
509 # Generic IOMAP is used to ...
510 config HAVE_GENERIC_IOMAP
511
512 config GENERIC_IOMAP
513 depends on HAVE_GENERIC_IOMAP && FOO
514
515 And in lib/Makefile we would see::
516
517 obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
518
519 For each architecture using the generic IOMAP functionality we would see::
520
521 config X86
522 select ...
523 select HAVE_GENERIC_IOMAP
524 select ...
525
526 Note: we use the existing config option and avoid creating a new
527 config variable to select HAVE_GENERIC_IOMAP.
528
529 Note: the use of the internal config variable HAVE_GENERIC_IOMAP, it is
530 introduced to overcome the limitation of select which will force a
531 config option to 'y' no matter the dependencies.
532 The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the
533 situation where select forces a symbol equals to 'y'.
534
535 Adding features that need compiler support
536 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
537
538 There are several features that need compiler support. The recommended way
539 to describe the dependency on the compiler feature is to use "depends on"
540 followed by a test macro::
541
542 config STACKPROTECTOR
543 bool "Stack Protector buffer overflow detection"
544 depends on $(cc-option,-fstack-protector)
545 ...
546
547 If you need to expose a compiler capability to makefiles and/or C source files,
548 `CC_HAS_` is the recommended prefix for the config option::
549
550 config CC_HAS_FOO
551 def_bool $(success,$(srctree)/scripts/cc-check-foo.sh $(CC))
552
553 Build as module only
554 ~~~~~~~~~~~~~~~~~~~~
555 To restrict a component build to module-only, qualify its config symbol
556 with "depends on m". E.g.::
557
558 config FOO
559 depends on BAR && m
560
561 limits FOO to module (=m) or disabled (=n).
562
563 Compile-testing
564 ~~~~~~~~~~~~~~~
565 If a config symbol has a dependency, but the code controlled by the config
566 symbol can still be compiled if the dependency is not met, it is encouraged to
567 increase build coverage by adding an "|| COMPILE_TEST" clause to the
568 dependency. This is especially useful for drivers for more exotic hardware, as
569 it allows continuous-integration systems to compile-test the code on a more
570 common system, and detect bugs that way.
571 Note that compile-tested code should avoid crashing when run on a system where
572 the dependency is not met.
573
574 Architecture and platform dependencies
575 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
576 Due to the presence of stubs, most drivers can now be compiled on most
577 architectures. However, this does not mean it makes sense to have all drivers
578 available everywhere, as the actual hardware may only exist on specific
579 architectures and platforms. This is especially true for on-SoC IP cores,
580 which may be limited to a specific vendor or SoC family.
581
582 To prevent asking the user about drivers that cannot be used on the system(s)
583 the user is compiling a kernel for, and if it makes sense, config symbols
584 controlling the compilation of a driver should contain proper dependencies,
585 limiting the visibility of the symbol to (a superset of) the platform(s) the
586 driver can be used on. The dependency can be an architecture (e.g. ARM) or
587 platform (e.g. ARCH_OMAP4) dependency. This makes life simpler not only for
588 distro config owners, but also for every single developer or user who
589 configures a kernel.
590
591 Such a dependency can be relaxed by combining it with the compile-testing rule
592 above, leading to:
593
594 config FOO
595 bool "Support for foo hardware"
596 depends on ARCH_FOO_VENDOR || COMPILE_TEST
597
598 Optional dependencies
599 ~~~~~~~~~~~~~~~~~~~~~
600
601 Some drivers are able to optionally use a feature from another module
602 or build cleanly with that module disabled, but cause a link failure
603 when trying to use that loadable module from a built-in driver.
604
605 The most common way to express this optional dependency in Kconfig logic
606 uses the slightly counterintuitive::
607
608 config FOO
609 tristate "Support for foo hardware"
610 depends on BAR || !BAR
611
612 This means that there is either a dependency on BAR that disallows
613 the combination of FOO=y with BAR=m, or BAR is completely disabled. The BAR
614 module must provide all the stubs for !BAR case.
615
616 For a more formalized approach if there are multiple drivers that have
617 the same dependency, a helper symbol can be used, like::
618
619 config FOO
620 tristate "Support for foo hardware"
621 depends on BAR_OPTIONAL
622
623 config BAR_OPTIONAL
624 def_tristate BAR || !BAR
625
626 Much less favorable way to express optional dependency is IS_REACHABLE() within
627 the module code, useful for example when the module BAR does not provide
628 !BAR stubs::
629
630 foo_init()
631 {
632 if (IS_REACHABLE(CONFIG_BAR))
633 bar_register(&foo);
634 ...
635 }
636
637 IS_REACHABLE() is generally discouraged, because the code will be silently
638 discarded, when CONFIG_BAR=m and this code is built-in. This is not what users
639 usually expect when enabling BAR as module.
640
641 Kconfig recursive dependency limitations
642 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
643
644 If you've hit the Kconfig error: "recursive dependency detected" you've run
645 into a recursive dependency issue with Kconfig, a recursive dependency can be
646 summarized as a circular dependency. The kconfig tools need to ensure that
647 Kconfig files comply with specified configuration requirements. In order to do
648 that kconfig must determine the values that are possible for all Kconfig
649 symbols, this is currently not possible if there is a circular relation
650 between two or more Kconfig symbols. For more details refer to the "Simple
651 Kconfig recursive issue" subsection below. Kconfig does not do recursive
652 dependency resolution; this has a few implications for Kconfig file writers.
653 We'll first explain why this issues exists and then provide an example
654 technical limitation which this brings upon Kconfig developers. Eager
655 developers wishing to try to address this limitation should read the next
656 subsections.
657
658 Simple Kconfig recursive issue
659 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
660
661 Read: Documentation/kbuild/Kconfig.recursion-issue-01
662
663 Test with::
664
665 make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig
666
667 Cumulative Kconfig recursive issue
668 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
669
670 Read: Documentation/kbuild/Kconfig.recursion-issue-02
671
672 Test with::
673
674 make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
675
676 Practical solutions to kconfig recursive issue
677 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
678
679 Developers who run into the recursive Kconfig issue have two options
680 at their disposal. We document them below and also provide a list of
681 historical issues resolved through these different solutions.
682
683 a) Remove any superfluous "select FOO" or "depends on FOO"
684 b) Match dependency semantics:
685
686 b1) Swap all "select FOO" to "depends on FOO" or,
687
688 b2) Swap all "depends on FOO" to "select FOO"
689
690 The resolution to a) can be tested with the sample Kconfig file
691 Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
692 of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already
693 since CORE_BELL_A depends on CORE. At times it may not be possible to remove
694 some dependency criteria, for such cases you can work with solution b).
695
696 The two different resolutions for b) can be tested in the sample Kconfig file
697 Documentation/kbuild/Kconfig.recursion-issue-02.
698
699 Below is a list of examples of prior fixes for these types of recursive issues;
700 all errors appear to involve one or more "select" statements and one or more
701 "depends on".
702
703 ============ ===================================
704 commit fix
705 ============ ===================================
706 06b718c01208 select A -> depends on A
707 c22eacfe82f9 depends on A -> depends on B
708 6a91e854442c select A -> depends on A
709 118c565a8f2e select A -> select B
710 f004e5594705 select A -> depends on A
711 c7861f37b4c6 depends on A -> (null)
712 80c69915e5fb select A -> (null) (1)
713 c2218e26c0d0 select A -> depends on A (1)
714 d6ae99d04e1c select A -> depends on A
715 95ca19cf8cbf select A -> depends on A
716 8f057d7bca54 depends on A -> (null)
717 8f057d7bca54 depends on A -> select A
718 a0701f04846e select A -> depends on A
719 0c8b92f7f259 depends on A -> (null)
720 e4e9e0540928 select A -> depends on A (2)
721 7453ea886e87 depends on A > (null) (1)
722 7b1fff7e4fdf select A -> depends on A
723 86c747d2a4f0 select A -> depends on A
724 d9f9ab51e55e select A -> depends on A
725 0c51a4d8abd6 depends on A -> select A (3)
726 e98062ed6dc4 select A -> depends on A (3)
727 91e5d284a7f1 select A -> (null)
728 ============ ===================================
729
730 (1) Partial (or no) quote of error.
731 (2) That seems to be the gist of that fix.
732 (3) Same error.
733
734 Future kconfig work
735 ~~~~~~~~~~~~~~~~~~~
736
737 Work on kconfig is welcomed on both areas of clarifying semantics and on
738 evaluating the use of a full SAT solver for it. A full SAT solver can be
739 desirable to enable more complex dependency mappings and / or queries,
740 for instance one possible use case for a SAT solver could be that of handling
741 the current known recursive dependency issues. It is not known if this would
742 address such issues but such evaluation is desirable. If support for a full SAT
743 solver proves too complex or that it cannot address recursive dependency issues
744 Kconfig should have at least clear and well defined semantics which also
745 addresses and documents limitations or requirements such as the ones dealing
746 with recursive dependencies.
747
748 Further work on both of these areas is welcomed on Kconfig. We elaborate
749 on both of these in the next two subsections.
750
751 Semantics of Kconfig
752 ~~~~~~~~~~~~~~~~~~~~
753
754 The use of Kconfig is broad, Linux is now only one of Kconfig's users:
755 one study has completed a broad analysis of Kconfig use in 12 projects [0]_.
756 Despite its widespread use, and although this document does a reasonable job
757 in documenting basic Kconfig syntax a more precise definition of Kconfig
758 semantics is welcomed. One project deduced Kconfig semantics through
759 the use of the xconfig configurator [1]_. Work should be done to confirm if
760 the deduced semantics matches our intended Kconfig design goals.
761 Another project formalized a denotational semantics of a core subset of
762 the Kconfig language [10]_.
763
764 Having well defined semantics can be useful for tools for practical
765 evaluation of dependencies, for instance one such case was work to
766 express in boolean abstraction of the inferred semantics of Kconfig to
767 translate Kconfig logic into boolean formulas and run a SAT solver on this to
768 find dead code / features (always inactive), 114 dead features were found in
769 Linux using this methodology [1]_ (Section 8: Threats to validity).
770 The kismet tool, based on the semantics in [10]_, finds abuses of reverse
771 dependencies and has led to dozens of committed fixes to Linux Kconfig files [11]_.
772
773 Confirming this could prove useful as Kconfig stands as one of the leading
774 industrial variability modeling languages [1]_ [2]_. Its study would help
775 evaluate practical uses of such languages, their use was only theoretical
776 and real world requirements were not well understood. As it stands though
777 only reverse engineering techniques have been used to deduce semantics from
778 variability modeling languages such as Kconfig [3]_.
779
780 .. [0] https://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf
781 .. [1] https://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
782 .. [2] https://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf
783 .. [3] https://gsd.uwaterloo.ca/sites/default/files/icse2011.pdf
784
785 Full SAT solver for Kconfig
786 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
787
788 Although SAT solvers [4]_ haven't yet been used by Kconfig directly, as noted
789 in the previous subsection, work has been done however to express in boolean
790 abstraction the inferred semantics of Kconfig to translate Kconfig logic into
791 boolean formulas and run a SAT solver on it [5]_. Another known related project
792 is CADOS [6]_ (former VAMOS [7]_) and the tools, mainly undertaker [8]_, which
793 has been introduced first with [9]_. The basic concept of undertaker is to
794 extract variability models from Kconfig and put them together with a
795 propositional formula extracted from CPP #ifdefs and build-rules into a SAT
796 solver in order to find dead code, dead files, and dead symbols. If using a SAT
797 solver is desirable on Kconfig one approach would be to evaluate repurposing
798 such efforts somehow on Kconfig. There is enough interest from mentors of
799 existing projects to not only help advise how to integrate this work upstream
800 but also help maintain it long term. Interested developers should visit:
801
802 https://kernelnewbies.org/KernelProjects/kconfig-sat
803
804 .. [4] https://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf
805 .. [5] https://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
806 .. [6] https://cados.cs.fau.de
807 .. [7] https://vamos.cs.fau.de
808 .. [8] https://undertaker.cs.fau.de
809 .. [9] https://www4.cs.fau.de/Publications/2011/tartler_11_eurosys.pdf
810 .. [10] https://paulgazzillo.com/papers/esecfse21.pdf
811 .. [11] https://github.com/paulgazz/kmax
812

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Configuration tree와 기본 menu attribute

1-120

Configuration database는 option을 tree 구조로 정리한 집합입니다. 예제 tree의 최상위에는 code maturity, general setup, loadable module support가 있고, general setup 아래에는 networking·System V IPC·BSD process accounting·sysctl이, module support 아래에는 symbol version과 module loader가 있습니다.

Kconfig menu tree
Code maturity level options → development/incomplete code promptGeneral setup → Networking support · System V IPC · BSD Process Accounting · SysctlLoadable module support → Enable loadable modules → Symbol version · Module loader

Child entry는 parent가 visible할 때만 보입니다.

각 entry에는 dependency가 있고 이는 visibility를 결정합니다. Child entry는 parent entry도 visible해야 visible합니다. 대부분 entry는 config option을 정의하고 나머지는 이를 구조화합니다.

`config MODVERSIONS` 예제는 `bool` prompt, `depends on MODULES`, indent된 help를 가집니다. 각 줄은 keyword로 시작하고 여러 argument가 뒤따를 수 있습니다. `config`는 새 entry를 시작하며 뒤의 줄이 type, prompt, dependency, help, default를 정의합니다.

같은 이름의 config option을 여러 번 정의할 수 있지만 각 definition에는 input prompt가 하나만 있을 수 있고 type은 서로 충돌하면 안 됩니다.

Config entry 핵심 attribute
Attribute역할
Type`bool`, `tristate`, `string`, `hex`, `int`
Prompt사용자에게 보일 질문
DependencyVisibility와 허용 값의 상한
HelpIndentation으로 경계가 정해지는 설명
Default사용자가 값을 정하지 않았을 때의 값

한 symbol definition에 붙을 수 있는 기본 속성입니다.

모든 config option에는 type이 필요합니다. 기본 type은 tristate와 string 두 가지이고 나머지는 이를 기반으로 합니다. Type 선언은 prompt를 함께 받을 수 있어 `bool "Networking support"`와 `bool` 뒤 `prompt "Networking support"`는 같습니다.

각 menu entry에는 prompt가 최대 하나 있습니다. `prompt <text> if <expr>`로 그 prompt에만 dependency를 붙일 수 있습니다. Prompt가 없으면 menu에 나타나지 않는 non-visible symbol이며 `.config`를 직접 바꾸는 방식으로도 사용자가 값을 바꿀 수 없습니다. 값은 `default`와 `select`로만 설정됩니다.

`default <expr> if <expr>`는 여러 번 정의할 수 있지만 visible한 default가 여러 개면 먼저 정의된 것만 활성화됩니다. Default는 entry와 다른 곳에서 정의할 수 있고 더 앞선 definition이 override할 수 있습니다. 사용자가 visible prompt에서 값을 정하지 않았을 때만 symbol에 배정되며 prompt가 보이면 사용자가 default를 바꿀 수 있습니다.

기본값은 build 비대화를 막기 위해 의도적으로 `n`입니다. `make oldconfig`가 release 사이 기존 config에 가능한 적게 추가하도록 새 option은 드문 예외를 빼고 이를 바꾸지 않아야 합니다.

`default y/m`이 타당한 경우
경우이유
항상 build되던 기능을 새 option으로 전환기존 동작 유지에 `default y`
다른 option을 숨기거나 보이는 gate만 추가다른 option이 계속 보이도록 `default y`
기본 `n` driver의 sub-driver 동작합리적인 하위 default 제공
`CONFIG_NET`, `CONFIG_BLOCK` 같은 보편적 infrastructure매우 드문 기대 기능 예외

새 option이 기존 동작과 발견 가능성을 유지해야 할 때의 예외입니다.

`def_bool`과 `def_tristate`는 type 정의와 default value를 합친 축약형이며 default에만 적용할 `if` dependency를 선택적으로 받을 수 있습니다.

================
Kconfig Language
================

Introduction
------------

The configuration database is a collection of configuration options
organized in a tree structure::

        +- Code maturity level options
        |  +- Prompt for development and/or incomplete code/drivers
        +- General setup
        |  +- Networking support
        |  +- System V IPC
        |  +- BSD Process Accounting
        |  +- Sysctl support
        +- Loadable module support
        |  +- Enable loadable module support
        |     +- Set version information on all module symbols
        |     +- Kernel module loader
        +- ...

Every entry has its own dependencies. These dependencies are used
to determine the visibility of an entry. Any child entry is only
visible if its parent entry is also visible.

Menu entries
------------

Most entries define a config option; all other entries help to organize
them. A single configuration option is defined like this::

  config MODVERSIONS
        bool "Set version information on all module symbols"
        depends on MODULES
        help
          Usually, modules have to be recompiled whenever you switch to a new
          kernel.  ...

Every line starts with a key word and can be followed by multiple
arguments.  "config" starts a new config entry. The following lines
define attributes for this config option. Attributes can be the type of
the config option, input prompt, dependencies, help text and default
values. A config option can be defined multiple times with the same
name, but every definition can have only a single input prompt and the
type must not conflict.

Menu attributes
---------------

A menu entry can have a number of attributes. Not all of them are
applicable everywhere (see syntax).

- type definition: "bool"/"tristate"/"string"/"hex"/"int"

  Every config option must have a type. There are only two basic types:
  tristate and string; the other types are based on these two. The type
  definition optionally accepts an input prompt, so these two examples
  are equivalent::

        bool "Networking support"

  and::

        bool
        prompt "Networking support"

- input prompt: "prompt" <prompt> ["if" <expr>]

  Every menu entry can have at most one prompt, which is used to display
  to the user. Optionally dependencies only for this prompt can be added
  with "if". If a prompt is not present, the config option is a non-visible
  symbol, meaning its value cannot be directly changed by the user (such as
  altering the value in ``.config``) and the option will not appear in any
  config menus. Its value can only be set via "default" and "select" (see
  below).

- default value: "default" <expr> ["if" <expr>]

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

 The default value deliberately defaults to 'n' in order to avoid bloating the
 build. With few exceptions, new config options should not change this. The
 intent is for "make oldconfig" to add as little as possible to the config from
 release to release.

 Note:
        Things that merit "default y/m" include:

        a) A new Kconfig option for something that used to always be built
           should be "default y".

        b) A new gatekeeping Kconfig option that hides/shows other Kconfig
           options (but does not generate any code of its own), should be
           "default y" so people will see those other options.

        c) Sub-driver behavior or similar options for a driver that is
           "default n". This allows you to provide sane defaults.

        d) Hardware or infrastructure that everybody expects, such as CONFIG_NET
           or CONFIG_BLOCK. These are rare exceptions.

- type definition + default value::

        "def_bool"/"def_tristate" <expr> ["if" <expr>]

  This is a shorthand notation for a type definition plus a value.
  Optionally dependencies for this default value can be added with "if".

`depends on`, `select`, `imply`와 기타 속성

121-266

`depends on <expr>`는 menu entry dependency를 정의합니다. 여러 dependency는 `&&`로 연결되고 `if` expression을 받을 수 있는 type·default·prompt 등 entry의 모든 option에 적용됩니다. 따라서 각 attribute에 `if BAR`를 붙이는 것과 entry에 `depends on BAR`를 한 번 쓰는 것은 같습니다.

일반 dependency는 symbol 값의 상한을 낮추지만 reverse dependency인 `select <symbol> if <expr>`는 다른 symbol의 하한을 강제합니다. 현재 menu symbol 값이 대상의 최소값이 되고 여러 곳에서 select하면 가장 큰 값이 하한이 됩니다. Boolean과 tristate에만 사용할 수 있습니다.

`select`는 대상 dependency를 검사하지 않고 값을 강제하므로 주의해야 합니다. BAR가 설정되지 않았는데 `depends on BAR`인 FOO를 select할 수도 있습니다. 일반적으로 prompt가 어디에도 없는 non-visible symbol이며 자체 dependency가 없는 symbol에만 사용해야 illegal configuration을 피할 수 있습니다.

`select` 뒤의 `if`가 있으면 현재 symbol과 expression의 logical AND가 대상 하한입니다. 따라서 조건 때문에 하한이 내려갈 수 있으며 이상해 보이지만 현재 의존하는 동작이고 미래는 결정되지 않았습니다.

Weak reverse dependency인 `imply`도 대상의 하한을 제안하지만 대상 symbol은 direct dependency나 visible prompt를 통해 여전히 `n`으로 설정될 수 있습니다.

`imply BAZ`의 가능한 값
FOOBARBAZ defaultBAZ 선택 가능
nynN/m/y
mymM/y/n
yyyY/m/n
nmnN/m
mmmM/n
ymmM/n
yn*N

FOO가 BAZ를 imply하고 BAZ가 BAR에 depends할 때의 원문 조합입니다.

이는 여러 driver가 secondary subsystem 연동 가능성을 표시하면서도 사용자가 driver를 끄지 않고 subsystem을 제외할 수 있게 할 때 유용합니다. BAZ가 FOO에 매우 중요하면 FOO는 BAZ뿐 아니라 dependency BAR도 imply해야 합니다. `imply <symbol> if <expr>`의 default는 현재 symbol과 expression의 logical AND이며 이 동작의 미래도 결정되지 않았습니다.

Dependency 종류 비교
구문효과Dependency 검사
`depends on X`현재 symbol의 상한 제한직접 반영
`select X`X의 하한 강제X의 dependency를 우회
`imply X`X의 default 하한 제안사용자·dependency가 `n`으로 낮출 수 있음

상한, 강제 하한, 제안 하한의 차이입니다.

`visible if <expr>`는 menu block에만 적용됩니다. False이면 block을 사용자에게 보이지 않지만 내부 symbol을 다른 symbol이 select할 수는 있습니다. 개별 entry의 conditional prompt와 비슷하며 기본 visible 값은 true입니다.

`range <symbol> <symbol> if <expr>`는 int와 hex 입력값을 첫 symbol 이상, 둘째 symbol 이하로 제한합니다.

`help` text는 첫 help line보다 indentation이 작은 줄에서 끝납니다.

`modules` attribute는 모든 config symbol의 세 번째 modular state를 활성화하는 MODULES symbol을 선언합니다. 이 option을 가진 symbol은 최대 하나입니다.

`transitional`은 configuration 중 읽고 처리하지만 새 `.config`에는 쓰지 않는 migration용 symbol입니다. Prompt가 없고 menu에 보이지 않으며 다른 symbol의 default expression에서 참조할 수 있지만 다른 property를 가질 수 없는 pass-through option입니다.

OLD_NAME에서 NEW_NAME으로 옮기는 예제는 NEW_NAME의 default를 OLD_NAME으로 두고 OLD_NAME을 prompt 없는 bool transitional symbol로 정의합니다. 기존 `CONFIG_OLD_NAME=y`는 `CONFIG_NEW_NAME=y`를 만들지만 새 `.config`에는 OLD_NAME이 기록되지 않습니다.

Transitional option migration
기존 `.config`에서 `CONFIG_OLD_NAME` 읽기Transitional OLD_NAME을 정상 평가NEW_NAME의 `default OLD_NAME` 적용새 `.config`에 NEW_NAME 기록OLD_NAME은 출력에서 생략

기존 config 값은 읽되 새 이름만 출력합니다.

- dependencies: "depends on" <expr>

  This defines a dependency for this menu entry. If multiple
  dependencies are defined, they are connected with '&&'. Dependencies
  are applied to all other options within this menu entry (which also
  accept an "if" expression), so these two examples are equivalent::

        bool "foo" if BAR
        default y if BAR

  and::

        depends on BAR
        bool "foo"
        default y

- reverse dependencies: "select" <symbol> ["if" <expr>]

  While normal dependencies reduce the upper limit of a symbol (see
  below), reverse dependencies can be used to force a lower limit of
  another symbol. The value of the current menu symbol is used as the
  minimal value <symbol> can be set to. If <symbol> is selected multiple
  times, the limit is set to the largest selection.
  Reverse dependencies can only be used with boolean or tristate
  symbols.

  Note:
        select should be used with care. select will force
        a symbol to a value without visiting the dependencies.
        By abusing select you are able to select a symbol FOO even
        if FOO depends on BAR that is not set.
        In general use select only for non-visible symbols
        (no prompts anywhere) and for symbols with no dependencies.
        That will limit the usefulness but on the other hand avoid
        the illegal configurations all over.

        If "select" <symbol> is followed by "if" <expr>, <symbol> will be
        selected by the logical AND of the value of the current menu symbol
        and <expr>. This means, the lower limit can be downgraded due to the
        presence of "if" <expr>. This behavior may seem weird, but we rely on
        it. (The future of this behavior is undecided.)

- weak reverse dependencies: "imply" <symbol> ["if" <expr>]

  This is similar to "select" as it enforces a lower limit on another
  symbol except that the "implied" symbol's value may still be set to n
  from a direct dependency or with a visible prompt.

  Given the following example::

    config FOO
        tristate "foo"
        imply BAZ

    config BAZ
        tristate "baz"
        depends on BAR

  The following values are possible:

        ===                ===                =============        ==============
        FOO                BAR                BAZ's default        choice for BAZ
        ===                ===                =============        ==============
        n                y                n                N/m/y
        m                y                m                M/y/n
        y                y                y                Y/m/n
        n                m                n                N/m
        m                m                m                M/n
        y                m                m                M/n
        y                n                *                N
        ===                ===                =============        ==============

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

  Note: If the feature provided by BAZ is highly desirable for FOO,
  FOO should imply not only BAZ, but also its dependency BAR::

    config FOO
        tristate "foo"
        imply BAR
        imply BAZ

  Note: If "imply" <symbol> is followed by "if" <expr>, the default of <symbol>
  will be the logical AND of the value of the current menu symbol and <expr>.
  (The future of this behavior is undecided.)

- limiting menu display: "visible if" <expr>

  This attribute is only applicable to menu blocks, if the condition is
  false, the menu block is not displayed to the user (the symbols
  contained there can still be selected by other symbols, though). It is
  similar to a conditional "prompt" attribute for individual menu
  entries. Default value of "visible" is true.

- numerical ranges: "range" <symbol> <symbol> ["if" <expr>]

  This allows to limit the range of possible input values for int
  and hex symbols. The user can only input a value which is larger than
  or equal to the first symbol and smaller than or equal to the second
  symbol.

- help text: "help"

  This defines a help text. The end of the help text is determined by
  the indentation level, this means it ends at the first line which has
  a smaller indentation than the first line of the help text.

- module attribute: "modules"
  This declares the symbol to be used as the MODULES symbol, which
  enables the third modular state for all config symbols.
  At most one symbol may have the "modules" option set.

- transitional attribute: "transitional"
  This declares the symbol as transitional, meaning it should be processed
  during configuration but omitted from newly written .config files.
  Transitional symbols are useful for backward compatibility during config
  option migrations - they allow olddefconfig to process existing .config
  files while ensuring the old option doesn't appear in new configurations.

  A transitional symbol:
  - Has no prompt (is not visible to users in menus)
  - Is processed normally during configuration (values are read and used)
  - Can be referenced in default expressions of other symbols
  - Is not written to new .config files
  - Cannot have any other properties (it is a pass-through option)

  Example migration from OLD_NAME to NEW_NAME::

    config NEW_NAME
        bool "New option name"
        default OLD_NAME
        help
          This replaces the old CONFIG_OLD_NAME option.

    config OLD_NAME
        bool
        transitional
        help
          Transitional config for OLD_NAME to NEW_NAME migration.

  With this setup, existing .config files with "CONFIG_OLD_NAME=y" will
  result in "CONFIG_NEW_NAME=y" being set, while CONFIG_OLD_NAME will be
  omitted from newly written .config files.

Tristate expression과 menu tree 결정

267-358

Dependency는 menu entry visibility를 정하고 tristate symbol의 입력 범위를 줄일 수도 있습니다. Tristate logic은 module 상태를 표현하기 위해 boolean보다 상태가 하나 더 많습니다.

Dependency expression precedence
형식의미
`<symbol>`Bool/tristate 값을 expression으로, 다른 type은 `n`
`a = b`같으면 `y`, 다르면 `n`
`a != b`같으면 `n`, 다르면 `y`
`<`, `>`, `<=`, `>=`관계가 참이면 `y`, 아니면 `n`
`(<expr>)`우선순위 override
`!<expr>``2 - expr`
`a && b``min(a, b)`
`a || b``max(a, b)`

원문 문법은 위에서 아래로 우선순위가 낮아집니다.

Expression 값은 `n`, `m`, `y`이며 계산에서는 각각 0, 1, 2입니다. Menu entry는 expression이 `m` 또는 `y`일 때 visible합니다.

Symbol에는 constant와 non-constant가 있습니다. 일반적인 non-constant symbol은 `config`로 정의하며 영숫자와 underscore만 포함합니다. Constant symbol은 expression에만 존재하고 single 또는 double quote로 감쌉니다. Quote 안에서는 모든 문자를 허용하며 `\`로 quote를 escape할 수 있습니다.

Menu 위치는 명시적 block 또는 dependency 분석으로 정합니다. `menu "Network device support"`와 `endmenu` 사이 entry는 모두 그 submenu가 되고 menu dependency `NET`도 각 child의 dependency 목록에 추가됩니다.

명시적 menu dependency 상속
`menu`가 parent prompt와 dependency 선언Block 안 config entry 수집각 child dependency에 parent expression 추가`endmenu`에서 block 종료

Block dependency가 모든 enclosed entry에 결합됩니다.

Dependency 분석으로 암시적 submenu를 만들 수도 있습니다. 이전 parent symbol이 child dependency 목록에 있어야 하고, parent가 `n`이면 child가 invisible해지거나 parent가 visible할 때만 child도 visible해야 합니다.

예제에서 MODVERSIONS는 MODULES에 직접 depends하므로 MODULES가 `n`이 아닐 때만 보입니다. 반면 `comment "module support disabled"`는 `depends on !MODULES`이므로 MODULES가 `n`일 때만 보입니다.

Menu dependencies
-----------------

Dependencies define the visibility of a menu entry and can also reduce
the input range of tristate symbols. The tristate logic used in the
expressions uses one more state than normal boolean logic to express the
module state. Dependency expressions have the following syntax::

  <expr> ::= <symbol>                           (1)
           <symbol> '=' <symbol>                (2)
           <symbol> '!=' <symbol>               (3)
           <symbol1> '<' <symbol2>              (4)
           <symbol1> '>' <symbol2>              (4)
           <symbol1> '<=' <symbol2>             (4)
           <symbol1> '>=' <symbol2>             (4)
           '(' <expr> ')'                       (5)
           '!' <expr>                           (6)
           <expr> '&&' <expr>                   (7)
           <expr> '||' <expr>                   (8)

Expressions are listed in decreasing order of precedence.

(1) Convert the symbol into an expression. Boolean and tristate symbols
    are simply converted into the respective expression values. All
    other symbol types result in 'n'.
(2) If the values of both symbols are equal, it returns 'y',
    otherwise 'n'.
(3) If the values of both symbols are equal, it returns 'n',
    otherwise 'y'.
(4) If value of <symbol1> is respectively lower, greater, lower-or-equal,
    or greater-or-equal than value of <symbol2>, it returns 'y',
    otherwise 'n'.
(5) Returns the value of the expression. Used to override precedence.
(6) Returns the result of (2-/expr/).
(7) Returns the result of min(/expr/, /expr/).
(8) Returns the result of max(/expr/, /expr/).

An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
respectively for calculations). A menu entry becomes visible when its
expression evaluates to 'm' or 'y'.

There are two types of symbols: constant and non-constant symbols.
Non-constant symbols are the most common ones and are defined with the
'config' statement. Non-constant symbols consist entirely of alphanumeric
characters or underscores.
Constant symbols are only part of expressions. Constant symbols are
always surrounded by single or double quotes. Within the quote, any
other character is allowed and the quotes can be escaped using '\'.

Menu structure
--------------

The position of a menu entry in the tree is determined in two ways. First
it can be specified explicitly::

  menu "Network device support"
        depends on NET

  config NETDEVICES
        ...

  endmenu

All entries within the "menu" ... "endmenu" block become a submenu of
"Network device support". All subentries inherit the dependencies from
the menu entry, e.g. this means the dependency "NET" is added to the
dependency list of the config option NETDEVICES.

The other way to generate the menu structure is done by analyzing the
dependencies. If a menu entry somehow depends on the previous entry, it
can be made a submenu of it. First, the previous (parent) symbol must
be part of the dependency list and then one of these two conditions
must be true:

- the child entry must become invisible, if the parent is set to 'n'
- the child entry must only be visible, if the parent is visible::

    config MODULES
        bool "Enable loadable module support"

    config MODVERSIONS
        bool "Set version information on all module symbols"
        depends on MODULES

    comment "module support disabled"
        depends on !MODULES

MODVERSIONS directly depends on MODULES, this means it's only visible if
MODULES is different from 'n'. The comment on the other hand is only
visible when MODULES is set to 'n'.

Kconfig statement 문법

359-491

Configuration file은 menu entry의 연속이며 help text를 제외한 모든 줄이 keyword로 시작합니다. `config`, `menuconfig`, `choice/endchoice`, `comment`, `menu/endmenu`, `if/endif`, `source`는 이전 entry를 끝냅니다. 앞의 다섯 종류는 새 menu entry도 시작합니다.

Kconfig statement
Statement역할주요 option
`config <symbol>`Config symbol 정의모든 config attribute
`menuconfig <symbol>`하위 option을 별도 목록으로 표시할 힌트Config attribute
`choice ... endchoice`단일 선택 groupprompt, default, depends on, help
`comment <prompt>`UI와 output file에 comment 표시Dependency만
`menu ... endmenu`Menu blockDependency와 visible
`if <expr> ... endif`Block dependency를 모든 내부 entry에 추가Expression
`source <prompt>`지정 configuration file을 항상 parseFile path
`mainmenu <prompt>`Configurator title bar 설정다른 statement보다 앞

각 keyword가 만드는 구조와 허용 option입니다.

`config`는 symbol과 config option을 정의합니다. `menuconfig`도 같지만 front end에 suboption을 별도 목록으로 표시하라는 hint입니다. 하위 option이 실제로 menuconfig 아래 보이려면 모두 menuconfig symbol에 depend해야 합니다.

권장 예제는 `menuconfig M` 뒤 `if M` block 안에 C1·C2를 두거나 C1·C2 각각에 `depends on M`을 둡니다. C0처럼 M에 depend하지 않는 entry가 사이에 오면 C1·C2가 M dependency를 가져도 더는 menuconfig M 아래 나타나지 않습니다.

`menuconfig` child 묶음
`menuconfig M` 정의이어지는 모든 child가 M에 depends`if M` block 또는 개별 `depends on M` 사용M에 depend하지 않는 C0가 끼면 암시적 child 묶음 종료

연속성과 parent dependency를 모두 만족해야 합니다.

`choice ... endchoice`는 config entry 하나만 선택할 수 있는 group입니다. `comment`는 configuration 과정에서 사용자에게 보이고 output file에도 echo됩니다. `menu`는 block을 만들고, `if` expression은 enclosed entry 전체에 dependency로 추가됩니다.

`source`는 지정 configuration file을 읽으며 그 file은 항상 parse됩니다. `mainmenu`는 configurator가 사용한다면 title bar를 설정하고 다른 statement보다 먼저 configuration top에 둬야 합니다.

Source line에서 quote되지 않은 `#` 문자는 어디에 있든 source comment 시작을 뜻하며 그 줄의 나머지는 comment입니다.

Kconfig syntax
--------------

The configuration file describes a series of menu entries, where every
line starts with a keyword (except help texts). The following keywords
end a menu entry:

- config
- menuconfig
- choice/endchoice
- comment
- menu/endmenu
- if/endif
- source

The first five also start the definition of a menu entry.

config::

        "config" <symbol>
        <config options>

This defines a config symbol <symbol> and accepts any of above
attributes as options.

menuconfig::

        "menuconfig" <symbol>
        <config options>

This is similar to the simple config entry above, but it also gives a
hint to front ends, that all suboptions should be displayed as a
separate list of options. To make sure all the suboptions will really
show up under the menuconfig entry and not outside of it, every item
from the <config options> list must depend on the menuconfig symbol.
In practice, this is achieved by using one of the next two constructs::

  (1):
  menuconfig M
  if M
      config C1
      config C2
  endif

  (2):
  menuconfig M
  config C1
      depends on M
  config C2
      depends on M

In the following examples (3) and (4), C1 and C2 still have the M
dependency, but will not appear under menuconfig M anymore, because
of C0, which doesn't depend on M::

  (3):
  menuconfig M
      config C0
  if M
      config C1
      config C2
  endif

  (4):
  menuconfig M
  config C0
  config C1
      depends on M
  config C2
      depends on M

choices::

        "choice"
        <choice options>
        <choice block>
        "endchoice"

This defines a choice group and accepts "prompt", "default", "depends on", and
"help" attributes as options.

A choice only allows a single config entry to be selected.

comment::

        "comment" <prompt>
        <comment options>

This defines a comment which is displayed to the user during the
configuration process and is also echoed to the output files. The only
possible options are dependencies.

menu::

        "menu" <prompt>
        <menu options>
        <menu block>
        "endmenu"

This defines a menu block, see "Menu structure" above for more
information. The only possible options are dependencies and "visible"
attributes.

if::

        "if" <expr>
        <if block>
        "endif"

This defines an if block. The dependency expression <expr> is appended
to all enclosed menu entries.

source::

        "source" <prompt>

This reads the specified configuration file. This file is always parsed.

mainmenu::

        "mainmenu" <prompt>

This sets the config program's title bar if the config program chooses
to use it. It should be placed at the top of the configuration, before any
other statement.

'#' Kconfig source file comment:

An unquoted '#' character anywhere in a source file line indicates
the beginning of a source file comment.  The remainder of that line
is a comment.

공통 기능, compiler, module과 optional dependency

492-640

일부 architecture에만 관련된 공통 기능은 common Kconfig에 `HAVE_*` variable을 두고 해당 architecture가 select하는 방식이 권장됩니다. Generic IOMAP 예제는 `HAVE_GENERIC_IOMAP`을 내부 capability로 두고 사용자 option `GENERIC_IOMAP`이 `HAVE_GENERIC_IOMAP && FOO`에 depends하며 Makefile이 `CONFIG_GENERIC_IOMAP`으로 `iomap.o`를 build합니다.

Architecture는 기존 X86 option에서 `select HAVE_GENERIC_IOMAP`을 사용하며 HAVE를 select하려고 새 option을 만들지 않습니다. 내부 HAVE symbol은 dependency와 무관하게 `y`를 강제하는 select 한계를 피하기 위한 것으로, 실제 dependency는 사용자 option GENERIC_IOMAP에 둡니다.

`HAVE_*` capability pattern
Common Kconfig에 prompt 없는 `HAVE_FEATURE` 정의지원 architecture가 `select HAVE_FEATURE`사용자 option은 `depends on HAVE_FEATURE && ...`Makefile은 사용자 option으로 object build

Architecture capability 표시와 사용자 기능 dependency를 분리합니다.

Compiler 지원이 필요한 기능은 test macro를 붙인 `depends on`으로 표현합니다. Stack protector 예제는 `depends on $(cc-option,-fstack-protector)`를 사용합니다. Capability를 Makefile이나 C source에도 노출해야 하면 `CC_HAS_` prefix가 권장되며 `CC_HAS_FOO` 예제는 `$(success,...cc-check-foo.sh $(CC))` 결과를 `def_bool`로 사용합니다.

Module로만 build하려면 `depends on m`을 추가합니다. `depends on BAR && m`인 FOO는 `m` 또는 `n`만 가능합니다.

Dependency가 없어도 code 자체는 compile 가능하면 build coverage를 늘리기 위해 `|| COMPILE_TEST`를 권장합니다. 특히 드문 hardware driver를 일반 CI system에서 compile해 bug를 찾는 데 유용하지만 실제 dependency가 없는 system에서 실행해도 crash하지 않아야 합니다.

Stub 덕분에 많은 driver를 여러 architecture에서 compile할 수 있지만 hardware가 특정 architecture·platform에만 있다면 모든 곳에서 option을 보일 필요는 없습니다. Driver symbol은 실제 사용 platform의 superset으로 visibility를 제한하는 `ARM`이나 `ARCH_OMAP4` 같은 dependency를 가져야 distro config maintainer와 사용자에게 불필요한 질문을 줄일 수 있습니다.

Platform 제한은 `depends on ARCH_FOO_VENDOR || COMPILE_TEST`처럼 compile-test rule과 결합해 완화할 수 있습니다.

다른 module의 기능을 선택적으로 사용하며 module이 꺼져도 build되지만 built-in driver가 loadable module을 사용할 때 link 실패하는 경우 `depends on BAR || !BAR`를 씁니다. 이는 FOO=y, BAR=m 조합을 막거나 BAR를 완전히 끄도록 합니다. `!BAR` 경우에는 BAR module이 필요한 stub을 모두 제공해야 합니다.

Optional dependency 상태
FOOBAR결과
yy허용
mm 또는 y허용
ym금지
y/mnStub이 있으면 허용

`BAR || !BAR`는 built-in이 loadable module에 의존하는 조합을 제외합니다.

여러 driver가 같은 optional dependency를 가지면 `BAR_OPTIONAL` helper symbol에 `def_tristate BAR || !BAR`를 두고 각 driver가 depend할 수 있습니다.

BAR가 `!BAR` stub을 제공하지 않을 때 module code 안에서 `IS_REACHABLE(CONFIG_BAR)`를 쓰는 방법은 덜 권장됩니다. CONFIG_BAR=m이고 호출 code가 built-in이면 code가 조용히 버려져 사용자가 BAR를 module로 켰을 때 기대한 동작과 다르기 때문입니다.

Kconfig hints
-------------
This is a collection of Kconfig tips, most of which aren't obvious at
first glance and most of which have become idioms in several Kconfig
files.

Adding common features and make the usage configurable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is a common idiom to implement a feature/functionality that are
relevant for some architectures but not all.
The recommended way to do so is to use a config variable named HAVE_*
that is defined in a common Kconfig file and selected by the relevant
architectures.
An example is the generic IOMAP functionality.

We would in lib/Kconfig see::

  # Generic IOMAP is used to ...
  config HAVE_GENERIC_IOMAP

  config GENERIC_IOMAP
        depends on HAVE_GENERIC_IOMAP && FOO

And in lib/Makefile we would see::

        obj-$(CONFIG_GENERIC_IOMAP) += iomap.o

For each architecture using the generic IOMAP functionality we would see::

  config X86
        select ...
        select HAVE_GENERIC_IOMAP
        select ...

Note: we use the existing config option and avoid creating a new
config variable to select HAVE_GENERIC_IOMAP.

Note: the use of the internal config variable HAVE_GENERIC_IOMAP, it is
introduced to overcome the limitation of select which will force a
config option to 'y' no matter the dependencies.
The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the
situation where select forces a symbol equals to 'y'.

Adding features that need compiler support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There are several features that need compiler support. The recommended way
to describe the dependency on the compiler feature is to use "depends on"
followed by a test macro::

  config STACKPROTECTOR
        bool "Stack Protector buffer overflow detection"
        depends on $(cc-option,-fstack-protector)
        ...

If you need to expose a compiler capability to makefiles and/or C source files,
`CC_HAS_` is the recommended prefix for the config option::

  config CC_HAS_FOO
        def_bool $(success,$(srctree)/scripts/cc-check-foo.sh $(CC))

Build as module only
~~~~~~~~~~~~~~~~~~~~
To restrict a component build to module-only, qualify its config symbol
with "depends on m".  E.g.::

  config FOO
        depends on BAR && m

limits FOO to module (=m) or disabled (=n).

Compile-testing
~~~~~~~~~~~~~~~
If a config symbol has a dependency, but the code controlled by the config
symbol can still be compiled if the dependency is not met, it is encouraged to
increase build coverage by adding an "|| COMPILE_TEST" clause to the
dependency. This is especially useful for drivers for more exotic hardware, as
it allows continuous-integration systems to compile-test the code on a more
common system, and detect bugs that way.
Note that compile-tested code should avoid crashing when run on a system where
the dependency is not met.

Architecture and platform dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Due to the presence of stubs, most drivers can now be compiled on most
architectures. However, this does not mean it makes sense to have all drivers
available everywhere, as the actual hardware may only exist on specific
architectures and platforms. This is especially true for on-SoC IP cores,
which may be limited to a specific vendor or SoC family.

To prevent asking the user about drivers that cannot be used on the system(s)
the user is compiling a kernel for, and if it makes sense, config symbols
controlling the compilation of a driver should contain proper dependencies,
limiting the visibility of the symbol to (a superset of) the platform(s) the
driver can be used on. The dependency can be an architecture (e.g. ARM) or
platform (e.g. ARCH_OMAP4) dependency. This makes life simpler not only for
distro config owners, but also for every single developer or user who
configures a kernel.

Such a dependency can be relaxed by combining it with the compile-testing rule
above, leading to:

  config FOO
        bool "Support for foo hardware"
        depends on ARCH_FOO_VENDOR || COMPILE_TEST

Optional dependencies
~~~~~~~~~~~~~~~~~~~~~

Some drivers are able to optionally use a feature from another module
or build cleanly with that module disabled, but cause a link failure
when trying to use that loadable module from a built-in driver.

The most common way to express this optional dependency in Kconfig logic
uses the slightly counterintuitive::

  config FOO
        tristate "Support for foo hardware"
        depends on BAR || !BAR

This means that there is either a dependency on BAR that disallows
the combination of FOO=y with BAR=m, or BAR is completely disabled. The BAR
module must provide all the stubs for !BAR case.

For a more formalized approach if there are multiple drivers that have
the same dependency, a helper symbol can be used, like::

  config FOO
        tristate "Support for foo hardware"
        depends on BAR_OPTIONAL

  config BAR_OPTIONAL
        def_tristate BAR || !BAR

Much less favorable way to express optional dependency is IS_REACHABLE() within
the module code, useful for example when the module BAR does not provide
!BAR stubs::

        foo_init()
        {
                if (IS_REACHABLE(CONFIG_BAR))
                        bar_register(&foo);
                ...
        }

IS_REACHABLE() is generally discouraged, because the code will be silently
discarded, when CONFIG_BAR=m and this code is built-in. This is not what users
usually expect when enabling BAR as module.

Recursive dependency 한계와 해결 사례

641-733

`recursive dependency detected` error는 둘 이상의 Kconfig symbol 사이 circular dependency를 뜻합니다. Kconfig tool은 모든 symbol의 가능한 값을 알아야 configuration 요구를 확인할 수 있지만 현재 circular relation에서는 계산할 수 없습니다. Kconfig는 recursive dependency resolution을 하지 않습니다.

간단한 사례는 `Documentation/kbuild/Kconfig.recursion-issue-01`이며 `make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig`로 시험합니다. 누적 사례는 `Kconfig.recursion-issue-02`이고 같은 방식으로 해당 path를 `KBUILD_KCONFIG`에 줍니다.

Recursive issue 해결 전략
전략작업
a불필요한 `select FOO` 또는 `depends on FOO` 제거
b1관련 `select FOO`를 모두 `depends on FOO`로 변경
b2관련 `depends on FOO`를 모두 `select FOO`로 변경

불필요한 edge를 없애거나 한 방향의 dependency 의미로 통일합니다.

첫 sample에서는 CORE_BELL_A가 이미 CORE에 depends하므로 CORE_BELL_A_ADVANCED의 `select CORE`가 암시적이고 제거할 수 있습니다. Edge를 제거할 수 없다면 b 방식으로 dependency semantics를 맞춥니다. 둘째 sample에서 두 b 해결책을 시험할 수 있습니다.

과거 recursive dependency 수정
Commit수정
06b718c01208select A → depends on A
c22eacfe82f9depends on A → depends on B
6a91e854442cselect A → depends on A
118c565a8f2eselect A → select B
f004e5594705select A → depends on A
c7861f37b4c6depends on A → 제거
80c69915e5fbselect A → 제거 (1)
c2218e26c0d0select A → depends on A (1)
d6ae99d04e1cselect A → depends on A
95ca19cf8cbfselect A → depends on A
8f057d7bca54depends on A → 제거
8f057d7bca54depends on A → select A
a0701f04846eselect A → depends on A
0c8b92f7f259depends on A → 제거
e4e9e0540928select A → depends on A (2)
7453ea886e87depends on A → 제거 (1)
7b1fff7e4fdfselect A → depends on A
86c747d2a4f0select A → depends on A
d9f9ab51e55eselect A → depends on A
0c51a4d8abd6depends on A → select A (3)
e98062ed6dc4select A → depends on A (3)
91e5d284a7f1select A → 제거

원문 commit과 dependency 변경을 행 단위로 보존했습니다.

표의 (1)은 error 인용이 일부이거나 없음을, (2)는 수정의 요지로 보인다는 뜻이며 (3)은 같은 error를 뜻합니다. 과거 error는 모두 하나 이상의 `select`와 하나 이상의 `depends on`이 얽혀 있습니다.

Kconfig recursive dependency limitations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you've hit the Kconfig error: "recursive dependency detected" you've run
into a recursive dependency issue with Kconfig, a recursive dependency can be
summarized as a circular dependency. The kconfig tools need to ensure that
Kconfig files comply with specified configuration requirements. In order to do
that kconfig must determine the values that are possible for all Kconfig
symbols, this is currently not possible if there is a circular relation
between two or more Kconfig symbols. For more details refer to the "Simple
Kconfig recursive issue" subsection below. Kconfig does not do recursive
dependency resolution; this has a few implications for Kconfig file writers.
We'll first explain why this issues exists and then provide an example
technical limitation which this brings upon Kconfig developers. Eager
developers wishing to try to address this limitation should read the next
subsections.

Simple Kconfig recursive issue
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Read: Documentation/kbuild/Kconfig.recursion-issue-01

Test with::

  make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig

Cumulative Kconfig recursive issue
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Read: Documentation/kbuild/Kconfig.recursion-issue-02

Test with::

  make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig

Practical solutions to kconfig recursive issue
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Developers who run into the recursive Kconfig issue have two options
at their disposal. We document them below and also provide a list of
historical issues resolved through these different solutions.

  a) Remove any superfluous "select FOO" or "depends on FOO"
  b) Match dependency semantics:

        b1) Swap all "select FOO" to "depends on FOO" or,

        b2) Swap all "depends on FOO" to "select FOO"

The resolution to a) can be tested with the sample Kconfig file
Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already
since CORE_BELL_A depends on CORE. At times it may not be possible to remove
some dependency criteria, for such cases you can work with solution b).

The two different resolutions for b) can be tested in the sample Kconfig file
Documentation/kbuild/Kconfig.recursion-issue-02.

Below is a list of examples of prior fixes for these types of recursive issues;
all errors appear to involve one or more "select" statements and one or more
"depends on".

============    ===================================
commit          fix
============    ===================================
06b718c01208    select A -> depends on A
c22eacfe82f9    depends on A -> depends on B
6a91e854442c    select A -> depends on A
118c565a8f2e    select A -> select B
f004e5594705    select A -> depends on A
c7861f37b4c6    depends on A -> (null)
80c69915e5fb    select A -> (null)              (1)
c2218e26c0d0    select A -> depends on A        (1)
d6ae99d04e1c    select A -> depends on A
95ca19cf8cbf    select A -> depends on A
8f057d7bca54    depends on A -> (null)
8f057d7bca54    depends on A -> select A
a0701f04846e    select A -> depends on A
0c8b92f7f259    depends on A -> (null)
e4e9e0540928    select A -> depends on A        (2)
7453ea886e87    depends on A > (null)           (1)
7b1fff7e4fdf    select A -> depends on A
86c747d2a4f0    select A -> depends on A
d9f9ab51e55e    select A -> depends on A
0c51a4d8abd6    depends on A -> select A        (3)
e98062ed6dc4    select A -> depends on A        (3)
91e5d284a7f1    select A -> (null)
============    ===================================

(1) Partial (or no) quote of error.
(2) That seems to be the gist of that fix.
(3) Same error.

Kconfig semantics와 SAT solver 연구

734-811

Kconfig 작업은 semantics를 명확히 하는 분야와 full SAT solver 사용을 평가하는 분야 모두 환영합니다. SAT solver는 더 복잡한 dependency mapping이나 query, 현재 recursive dependency 문제 처리에 유용할 수 있지만 해결 가능 여부는 아직 모릅니다. 너무 복잡하거나 recursion을 해결하지 못하더라도 Kconfig는 제약과 요구를 포함한 명확한 semantics를 가져야 합니다.

Kconfig는 Linux 외 여러 project에서 널리 쓰이며 한 연구는 12개 project를 분석했습니다. 기본 syntax 문서는 있지만 더 정확한 semantics 정의가 필요합니다. 한 project는 xconfig configurator에서 semantics를 추론했고, 다른 project는 core subset의 denotational semantics를 formalize했습니다. 추론된 의미가 Kconfig 설계 목표와 맞는지 확인해야 합니다.

명확한 semantics는 dependency를 실제로 평가하는 tool에 유용합니다. Kconfig logic을 boolean formula로 번역해 SAT solver로 항상 inactive인 dead feature를 찾은 연구는 Linux에서 114개를 발견했습니다. Formal semantics 기반 `kismet` tool은 reverse dependency 남용을 찾아 수십 건의 Kconfig 수정을 이끌었습니다.

Kconfig는 대표적인 industrial variability modeling language이므로 semantics 확인은 실세계 요구를 이해하는 데 도움이 됩니다. 현재까지 Kconfig 같은 language의 semantics는 주로 reverse engineering으로 추론했습니다.

Kconfig semantics 참고 자료
RefURL
[0]https://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf
[1]https://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
[2]https://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf
[3]https://gsd.uwaterloo.ca/sites/default/files/icse2011.pdf
[10]https://paulgazzillo.com/papers/esecfse21.pdf
[11]https://github.com/paulgazz/kmax

원문 [0]~[3], [10], [11]의 연구와 tool link입니다.

Kconfig 자체는 아직 SAT solver를 직접 쓰지 않지만 inferred semantics를 boolean abstraction으로 바꿔 solver에 넣는 연구가 있습니다. CADOS(이전 VAMOS)와 `undertaker`는 Kconfig variability model, CPP `#ifdef`, build rule에서 proposition을 추출해 SAT solver로 dead code·file·symbol을 찾습니다.

Kconfig에 SAT solver를 도입한다면 이런 기존 노력을 재사용할 수 있습니다. 기존 project mentor가 upstream 통합 자문과 장기 유지에 관심을 보이고 있으며 참여자는 `https://kernelnewbies.org/KernelProjects/kconfig-sat`를 참고합니다.

SAT solver 관련 link
RefURL
Projecthttps://kernelnewbies.org/KernelProjects/kconfig-sat
[4]https://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf
[5]https://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
[6]https://cados.cs.fau.de
[7]https://vamos.cs.fau.de
[8]https://undertaker.cs.fau.de
[9]https://www4.cs.fau.de/Publications/2011/tartler_11_eurosys.pdf

원문 [4]~[9]와 project page입니다.

SAT 기반 variability 분석
Kconfig에서 variability model 추출CPP `#ifdef` 조건 추출Build rule 조건 추출Boolean formula로 결합SAT solver로 dead code·file·symbol 탐색

서로 다른 source의 조건을 하나의 proposition model로 결합합니다.

Future kconfig work
~~~~~~~~~~~~~~~~~~~

Work on kconfig is welcomed on both areas of clarifying semantics and on
evaluating the use of a full SAT solver for it. A full SAT solver can be
desirable to enable more complex dependency mappings and / or queries,
for instance one possible use case for a SAT solver could be that of handling
the current known recursive dependency issues. It is not known if this would
address such issues but such evaluation is desirable. If support for a full SAT
solver proves too complex or that it cannot address recursive dependency issues
Kconfig should have at least clear and well defined semantics which also
addresses and documents limitations or requirements such as the ones dealing
with recursive dependencies.

Further work on both of these areas is welcomed on Kconfig. We elaborate
on both of these in the next two subsections.

Semantics of Kconfig
~~~~~~~~~~~~~~~~~~~~

The use of Kconfig is broad, Linux is now only one of Kconfig's users:
one study has completed a broad analysis of Kconfig use in 12 projects [0]_.
Despite its widespread use, and although this document does a reasonable job
in documenting basic Kconfig syntax a more precise definition of Kconfig
semantics is welcomed. One project deduced Kconfig semantics through
the use of the xconfig configurator [1]_. Work should be done to confirm if
the deduced semantics matches our intended Kconfig design goals.
Another project formalized a denotational semantics of a core subset of
the Kconfig language [10]_.

Having well defined semantics can be useful for tools for practical
evaluation of dependencies, for instance one such case was work to
express in boolean abstraction of the inferred semantics of Kconfig to
translate Kconfig logic into boolean formulas and run a SAT solver on this to
find dead code / features (always inactive), 114 dead features were found in
Linux using this methodology [1]_ (Section 8: Threats to validity).
The kismet tool, based on the semantics in [10]_, finds abuses of reverse
dependencies and has led to dozens of committed fixes to Linux Kconfig files [11]_.

Confirming this could prove useful as Kconfig stands as one of the leading
industrial variability modeling languages [1]_ [2]_. Its study would help
evaluate practical uses of such languages, their use was only theoretical
and real world requirements were not well understood. As it stands though
only reverse engineering techniques have been used to deduce semantics from
variability modeling languages such as Kconfig [3]_.

.. [0] https://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf
.. [1] https://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
.. [2] https://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf
.. [3] https://gsd.uwaterloo.ca/sites/default/files/icse2011.pdf

Full SAT solver for Kconfig
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Although SAT solvers [4]_ haven't yet been used by Kconfig directly, as noted
in the previous subsection, work has been done however to express in boolean
abstraction the inferred semantics of Kconfig to translate Kconfig logic into
boolean formulas and run a SAT solver on it [5]_. Another known related project
is CADOS [6]_ (former VAMOS [7]_) and the tools, mainly undertaker [8]_, which
has been introduced first with [9]_.  The basic concept of undertaker is to
extract variability models from Kconfig and put them together with a
propositional formula extracted from CPP #ifdefs and build-rules into a SAT
solver in order to find dead code, dead files, and dead symbols. If using a SAT
solver is desirable on Kconfig one approach would be to evaluate repurposing
such efforts somehow on Kconfig. There is enough interest from mentors of
existing projects to not only help advise how to integrate this work upstream
but also help maintain it long term. Interested developers should visit:

https://kernelnewbies.org/KernelProjects/kconfig-sat

.. [4] https://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf
.. [5] https://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
.. [6] https://cados.cs.fau.de
.. [7] https://vamos.cs.fau.de
.. [8] https://undertaker.cs.fau.de
.. [9] https://www4.cs.fau.de/Publications/2011/tartler_11_eurosys.pdf
.. [10] https://paulgazzillo.com/papers/esecfse21.pdf
.. [11] https://github.com/paulgazz/kmax