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

Linux 6.18.37 · Kbuild

Kconfig Macro Language

Kconfig의 Make 유사 매크로 확장, 변수·함수 문법, 내장 함수, 호출 규칙과 token 경계를 설명합니다.

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

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

1. 요약·해설

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

요약·해설

kconfig-macro-language.rst:1-247

Kconfig는 symbol dependency를 평가하기 전에 Make와 비슷한 macro language로 variable과 function을 text로 확장합니다. `:=`는 즉시 확장, `=`는 사용 시 확장이고, `+=`의 시점은 기존 variable 종류를 따릅니다.

함수 argument는 comma로만 구분하며 whitespace를 그대로 보존합니다. `shell` 결과는 newline을 space로 바꾼 stdout이고, `filename`과 `lineno`는 현재 parsing 위치를 제공합니다.

Macro expansion은 Kconfig token이나 keyword의 경계를 넘을 수 없고 아직 평가되지 않은 symbol value를 shell에 넘길 수도 없습니다. Compile check는 각 정적 shell call에 Kconfig condition을 붙여 표현하는 편이 안전합니다.

확장과 평가의 경계
Variable·function 정의 읽기Macro reference를 text로 확장확장된 Kconfig token stream 생성Kconfig grammar parsingSymbol dependency와 값 평가

문서 전체를 이해하는 핵심 순서입니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ======================
2 Kconfig macro language
3 ======================
4
5 Concept
6 -------
7
8 The basic idea was inspired by Make. When we look at Make, we notice sort of
9 two languages in one. One language describes dependency graphs consisting of
10 targets and prerequisites. The other is a macro language for performing textual
11 substitution.
12
13 There is clear distinction between the two language stages. For example, you
14 can write a makefile like follows::
15
16 APP := foo
17 SRC := foo.c
18 CC := gcc
19
20 $(APP): $(SRC)
21 $(CC) -o $(APP) $(SRC)
22
23 The macro language replaces the variable references with their expanded form,
24 and handles as if the source file were input like follows::
25
26 foo: foo.c
27 gcc -o foo foo.c
28
29 Then, Make analyzes the dependency graph and determines the targets to be
30 updated.
31
32 The idea is quite similar in Kconfig - it is possible to describe a Kconfig
33 file like this::
34
35 CC := gcc
36
37 config CC_HAS_FOO
38 def_bool $(shell, $(srctree)/scripts/gcc-check-foo.sh $(CC))
39
40 The macro language in Kconfig processes the source file into the following
41 intermediate::
42
43 config CC_HAS_FOO
44 def_bool y
45
46 Then, Kconfig moves onto the evaluation stage to resolve inter-symbol
47 dependency as explained in kconfig-language.rst.
48
49
50 Variables
51 ---------
52
53 Like in Make, a variable in Kconfig works as a macro variable. A macro
54 variable is expanded "in place" to yield a text string that may then be
55 expanded further. To get the value of a variable, enclose the variable name in
56 $( ). The parentheses are required even for single-letter variable names; $X is
57 a syntax error. The curly brace form as in ${CC} is not supported either.
58
59 There are two types of variables: simply expanded variables and recursively
60 expanded variables.
61
62 A simply expanded variable is defined using the := assignment operator. Its
63 righthand side is expanded immediately upon reading the line from the Kconfig
64 file.
65
66 A recursively expanded variable is defined using the = assignment operator.
67 Its righthand side is simply stored as the value of the variable without
68 expanding it in any way. Instead, the expansion is performed when the variable
69 is used.
70
71 There is another type of assignment operator; += is used to append text to a
72 variable. The righthand side of += is expanded immediately if the lefthand
73 side was originally defined as a simple variable. Otherwise, its evaluation is
74 deferred.
75
76 The variable reference can take parameters, in the following form::
77
78 $(name,arg1,arg2,arg3)
79
80 You can consider the parameterized reference as a function. (more precisely,
81 "user-defined function" in contrast to "built-in function" listed below).
82
83 Useful functions must be expanded when they are used since the same function is
84 expanded differently if different parameters are passed. Hence, a user-defined
85 function is defined using the = assignment operator. The parameters are
86 referenced within the body definition with $(1), $(2), etc.
87
88 In fact, recursively expanded variables and user-defined functions are the same
89 internally. (In other words, "variable" is "function with zero argument".)
90 When we say "variable" in a broad sense, it includes "user-defined function".
91
92
93 Built-in functions
94 ------------------
95
96 Like Make, Kconfig provides several built-in functions. Every function takes a
97 particular number of arguments.
98
99 In Make, every built-in function takes at least one argument. Kconfig allows
100 zero argument for built-in functions, such as $(filename), $(lineno). You could
101 consider those as "built-in variable", but it is just a matter of how we call
102 it after all. Let's say "built-in function" here to refer to natively supported
103 functionality.
104
105 Kconfig currently supports the following built-in functions.
106
107 - $(shell,command)
108
109 The "shell" function accepts a single argument that is expanded and passed
110 to a subshell for execution. The standard output of the command is then read
111 and returned as the value of the function. Every newline in the output is
112 replaced with a space. Any trailing newlines are deleted. The standard error
113 is not returned, nor is any program exit status.
114
115 - $(info,text)
116
117 The "info" function takes a single argument and prints it to stdout.
118 It evaluates to an empty string.
119
120 - $(warning-if,condition,text)
121
122 The "warning-if" function takes two arguments. If the condition part is "y",
123 the text part is sent to stderr. The text is prefixed with the name of the
124 current Kconfig file and the current line number.
125
126 - $(error-if,condition,text)
127
128 The "error-if" function is similar to "warning-if", but it terminates the
129 parsing immediately if the condition part is "y".
130
131 - $(filename)
132
133 The 'filename' takes no argument, and $(filename) is expanded to the file
134 name being parsed.
135
136 - $(lineno)
137
138 The 'lineno' takes no argument, and $(lineno) is expanded to the line number
139 being parsed.
140
141
142 Make vs Kconfig
143 ---------------
144
145 Kconfig adopts Make-like macro language, but the function call syntax is
146 slightly different.
147
148 A function call in Make looks like this::
149
150 $(func-name arg1,arg2,arg3)
151
152 The function name and the first argument are separated by at least one
153 whitespace. Then, leading whitespaces are trimmed from the first argument,
154 while whitespaces in the other arguments are kept. You need to use a kind of
155 trick to start the first parameter with spaces. For example, if you want
156 to make "info" function print " hello", you can write like follows::
157
158 empty :=
159 space := $(empty) $(empty)
160 $(info $(space)$(space)hello)
161
162 Kconfig uses only commas for delimiters, and keeps all whitespaces in the
163 function call. Some people prefer putting a space after each comma delimiter::
164
165 $(func-name, arg1, arg2, arg3)
166
167 In this case, "func-name" will receive " arg1", " arg2", " arg3". The presence
168 of leading spaces may matter depending on the function. The same applies to
169 Make - for example, $(subst .c, .o, $(sources)) is a typical mistake; it
170 replaces ".c" with " .o".
171
172 In Make, a user-defined function is referenced by using a built-in function,
173 'call', like this::
174
175 $(call my-func,arg1,arg2,arg3)
176
177 Kconfig invokes user-defined functions and built-in functions in the same way.
178 The omission of 'call' makes the syntax shorter.
179
180 In Make, some functions treat commas verbatim instead of argument separators.
181 For example, $(shell echo hello, world) runs the command "echo hello, world".
182 Likewise, $(info hello, world) prints "hello, world" to stdout. You could say
183 this is _useful_ inconsistency.
184
185 In Kconfig, for simpler implementation and grammatical consistency, commas that
186 appear in the $( ) context are always delimiters. It means::
187
188 $(shell, echo hello, world)
189
190 is an error because it is passing two parameters where the 'shell' function
191 accepts only one. To pass commas in arguments, you can use the following trick::
192
193 comma := ,
194 $(shell, echo hello$(comma) world)
195
196
197 Caveats
198 -------
199
200 A variable (or function) cannot be expanded across tokens. So, you cannot use
201 a variable as a shorthand for an expression that consists of multiple tokens.
202 The following works::
203
204 RANGE_MIN := 1
205 RANGE_MAX := 3
206
207 config FOO
208 int "foo"
209 range $(RANGE_MIN) $(RANGE_MAX)
210
211 But, the following does not work::
212
213 RANGES := 1 3
214
215 config FOO
216 int "foo"
217 range $(RANGES)
218
219 A variable cannot be expanded to any keyword in Kconfig. The following does
220 not work::
221
222 MY_TYPE := tristate
223
224 config FOO
225 $(MY_TYPE) "foo"
226 default y
227
228 Obviously from the design, $(shell command) is expanded in the textual
229 substitution phase. You cannot pass symbols to the 'shell' function.
230
231 The following does not work as expected::
232
233 config ENDIAN_FLAG
234 string
235 default "-mbig-endian" if CPU_BIG_ENDIAN
236 default "-mlittle-endian" if CPU_LITTLE_ENDIAN
237
238 config CC_HAS_ENDIAN_FLAG
239 def_bool $(shell $(srctree)/scripts/gcc-check-flag ENDIAN_FLAG)
240
241 Instead, you can do like follows so that any function call is statically
242 expanded::
243
244 config CC_HAS_ENDIAN_FLAG
245 bool
246 default $(shell $(srctree)/scripts/gcc-check-flag -mbig-endian) if CPU_BIG_ENDIAN
247 default $(shell $(srctree)/scripts/gcc-check-flag -mlittle-endian) if CPU_LITTLE_ENDIAN
248

3. 한국어 전문 번역

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

매크로 언어의 개념과 평가 단계

1-49

기본 발상은 Make에서 가져왔습니다. Make에는 사실상 두 언어가 함께 있습니다. 하나는 target과 prerequisite로 이루어진 dependency graph를 기술하고, 다른 하나는 textual substitution을 수행하는 macro language입니다.

이 두 언어의 처리 단계는 분명히 구분됩니다. 예제 makefile에서 `APP := foo`, `SRC := foo.c`, `CC := gcc`를 정의하고 `$(APP): $(SRC)`와 `$(CC) -o $(APP) $(SRC)`를 쓰면, macro language가 variable reference를 먼저 확장합니다.

APP := foo
SRC := foo.c
CC := gcc

$(APP): $(SRC)
        $(CC) -o $(APP) $(SRC)

확장 결과는 `foo: foo.c`와 `gcc -o foo foo.c`가 입력된 것처럼 처리됩니다. 그 뒤에야 Make가 dependency graph를 분석하고 갱신할 target을 결정합니다.

Make 처리 단계
Makefile 원문 읽기`$(APP)`, `$(SRC)`, `$(CC)` macro reference 확장확장된 target·prerequisite graph 구성갱신할 target 결정

문자열 확장과 dependency 평가는 서로 다른 단계입니다.

Kconfig도 같은 생각을 따릅니다. `CC := gcc`와 `def_bool $(shell, $(srctree)/scripts/gcc-check-foo.sh $(CC))`를 작성하면 macro language가 source를 먼저 처리합니다. shell check가 성공해 `y`를 반환한 경우 중간 표현은 `def_bool y`가 됩니다.

CC := gcc

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

# 매크로 확장 뒤의 중간 표현
config CC_HAS_FOO
        def_bool y

매크로 확장이 끝난 다음 Kconfig는 `kconfig-language.rst`에서 설명한 평가 단계로 이동해 symbol 사이의 dependency를 해석합니다. 즉 shell 명령과 variable reference는 dependency 계산 전에 정적으로 텍스트로 치환됩니다.

Kconfig 처리 단계
Kconfig source와 macro variable 읽기Variable·function·shell call을 textual substitution`def_bool y` 같은 중간 Kconfig 생성Symbol dependency와 최종 값 평가

매크로 언어가 만든 중간 표현을 Kconfig evaluator가 해석합니다.

======================
Kconfig macro language
======================

Concept
-------

The basic idea was inspired by Make. When we look at Make, we notice sort of
two languages in one. One language describes dependency graphs consisting of
targets and prerequisites. The other is a macro language for performing textual
substitution.

There is clear distinction between the two language stages. For example, you
can write a makefile like follows::

    APP := foo
    SRC := foo.c
    CC := gcc

    $(APP): $(SRC)
            $(CC) -o $(APP) $(SRC)

The macro language replaces the variable references with their expanded form,
and handles as if the source file were input like follows::

    foo: foo.c
            gcc -o foo foo.c

Then, Make analyzes the dependency graph and determines the targets to be
updated.

The idea is quite similar in Kconfig - it is possible to describe a Kconfig
file like this::

    CC := gcc

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

The macro language in Kconfig processes the source file into the following
intermediate::

    config CC_HAS_FOO
            def_bool y

Then, Kconfig moves onto the evaluation stage to resolve inter-symbol
dependency as explained in kconfig-language.rst.

변수와 사용자 정의 함수

50-92

Kconfig variable은 Make와 마찬가지로 macro variable로 동작합니다. Variable은 사용 위치에서 text string으로 확장되며, 그 결과가 다시 확장될 수도 있습니다. 값을 얻으려면 이름을 반드시 `$( )`로 감싸야 합니다. 한 글자 이름도 `$(X)`로 써야 하며 `$X`는 syntax error입니다. `${CC}` 형태도 지원하지 않습니다.

Variable에는 simply expanded variable과 recursively expanded variable 두 종류가 있습니다. `:=`로 정의한 simply expanded variable은 Kconfig가 해당 줄을 읽을 때 우변을 즉시 확장합니다. `=`로 정의한 recursively expanded variable은 우변을 확장하지 않고 그대로 저장했다가 실제 사용 시점에 확장합니다.

`+=`는 variable 끝에 text를 덧붙입니다. 좌변이 처음에 simple variable로 정의되었다면 `+=` 우변도 즉시 확장하고, 그렇지 않으면 확장을 사용 시점까지 미룹니다.

Kconfig variable assignment
연산자종류우변 확장 시점
`:=`Simply expanded variable정의 줄을 읽는 즉시
`=`Recursively expanded variableVariable을 사용할 때
`+=`Append기존 variable이 simple이면 즉시, 아니면 지연

연산자는 우변을 확장하는 시점을 결정합니다.

Variable reference는 `$(name,arg1,arg2,arg3)` 형태로 parameter를 받을 수 있습니다. 이런 parameterized reference는 아래의 built-in function과 구분해 user-defined function으로 볼 수 있습니다.

유용한 function은 전달된 parameter에 따라 결과가 달라지므로 사용할 때 확장되어야 합니다. 따라서 user-defined function은 `=` 연산자로 정의하고, body에서는 `$(1)`, `$(2)`처럼 각 parameter를 참조합니다.

format = $(1): $(2)
MESSAGE := $(format,level,text)

내부적으로 recursively expanded variable과 user-defined function은 같습니다. 다시 말해 variable은 argument가 0개인 function입니다. 이 문서가 넓은 의미에서 variable이라고 할 때는 user-defined function도 포함합니다.

Variables
---------

Like in Make, a variable in Kconfig works as a macro variable.  A macro
variable is expanded "in place" to yield a text string that may then be
expanded further. To get the value of a variable, enclose the variable name in
$( ). The parentheses are required even for single-letter variable names; $X is
a syntax error. The curly brace form as in ${CC} is not supported either.

There are two types of variables: simply expanded variables and recursively
expanded variables.

A simply expanded variable is defined using the := assignment operator. Its
righthand side is expanded immediately upon reading the line from the Kconfig
file.

A recursively expanded variable is defined using the = assignment operator.
Its righthand side is simply stored as the value of the variable without
expanding it in any way. Instead, the expansion is performed when the variable
is used.

There is another type of assignment operator; += is used to append text to a
variable. The righthand side of += is expanded immediately if the lefthand
side was originally defined as a simple variable. Otherwise, its evaluation is
deferred.

The variable reference can take parameters, in the following form::

  $(name,arg1,arg2,arg3)

You can consider the parameterized reference as a function. (more precisely,
"user-defined function" in contrast to "built-in function" listed below).

Useful functions must be expanded when they are used since the same function is
expanded differently if different parameters are passed. Hence, a user-defined
function is defined using the = assignment operator. The parameters are
referenced within the body definition with $(1), $(2), etc.

In fact, recursively expanded variables and user-defined functions are the same
internally. (In other words, "variable" is "function with zero argument".)
When we say "variable" in a broad sense, it includes "user-defined function".

내장 함수

93-141

Kconfig는 Make처럼 여러 built-in function을 제공하며, 각 함수는 정해진 수의 argument를 받습니다. Make의 built-in function은 적어도 argument 하나를 받지만 Kconfig는 `$(filename)`, `$(lineno)`처럼 argument가 0개인 함수도 허용합니다. 이를 built-in variable이라고 부를 수도 있지만, 여기서는 native functionality 전체를 built-in function이라고 부릅니다.

Kconfig built-in function
함수인자동작·반환
`$(shell,command)`1확장한 command를 subshell에서 실행하고 stdout을 반환
`$(info,text)`1Text를 stdout에 출력하고 빈 문자열로 평가
`$(warning-if,condition,text)`2Condition이 `y`이면 위치 prefix와 함께 stderr에 경고
`$(error-if,condition,text)`2Condition이 `y`이면 error를 내고 parsing 즉시 종료
`$(filename)`0현재 parsing 중인 file name으로 확장
`$(lineno)`0현재 parsing 중인 line number로 확장

현재 지원되는 함수와 반환·부작용을 정리합니다.

`shell`은 argument 하나를 먼저 확장한 뒤 subshell에 넘겨 실행합니다. Command의 standard output을 읽어 함수 값으로 반환하며, 출력의 모든 newline은 space로 바꾸고 끝의 newline은 제거합니다. Standard error와 program exit status는 반환하지 않습니다.

`shell` 함수 처리
`command` argument 확장Subshell에서 command 실행Standard output 읽기내부 newline을 space로 치환하고 trailing newline 제거결과 text를 호출 위치에 삽입

Shell 결과는 Kconfig evaluator가 보기 전에 문자열이 됩니다.

`info`는 argument 하나를 stdout에 출력하고 빈 문자열로 평가됩니다. `warning-if`는 condition과 text 두 argument를 받으며 condition이 `y`일 때 text를 stderr로 보냅니다. 이 경고 앞에는 현재 Kconfig file name과 line number가 붙습니다. `error-if`도 같지만 condition이 `y`이면 parsing을 즉시 종료합니다.

Argument가 없는 `filename`은 parsing 중인 file name으로, `lineno`는 parsing 중인 line number로 확장됩니다.

Built-in functions
------------------

Like Make, Kconfig provides several built-in functions. Every function takes a
particular number of arguments.

In Make, every built-in function takes at least one argument. Kconfig allows
zero argument for built-in functions, such as $(filename), $(lineno). You could
consider those as "built-in variable", but it is just a matter of how we call
it after all. Let's say "built-in function" here to refer to natively supported
functionality.

Kconfig currently supports the following built-in functions.

 - $(shell,command)

  The "shell" function accepts a single argument that is expanded and passed
  to a subshell for execution. The standard output of the command is then read
  and returned as the value of the function. Every newline in the output is
  replaced with a space. Any trailing newlines are deleted. The standard error
  is not returned, nor is any program exit status.

 - $(info,text)

  The "info" function takes a single argument and prints it to stdout.
  It evaluates to an empty string.

 - $(warning-if,condition,text)

  The "warning-if" function takes two arguments. If the condition part is "y",
  the text part is sent to stderr. The text is prefixed with the name of the
  current Kconfig file and the current line number.

 - $(error-if,condition,text)

  The "error-if" function is similar to "warning-if", but it terminates the
  parsing immediately if the condition part is "y".

 - $(filename)

  The 'filename' takes no argument, and $(filename) is expanded to the file
  name being parsed.

 - $(lineno)

  The 'lineno' takes no argument, and $(lineno) is expanded to the line number
  being parsed.

Make와 Kconfig 호출 문법의 차이

142-196

Kconfig는 Make와 비슷한 macro language를 채택했지만 function call syntax에는 차이가 있습니다. Make 호출은 `$(func-name arg1,arg2,arg3)`처럼 function name과 첫 argument를 적어도 하나의 whitespace로 구분합니다.

Make는 첫 argument 앞의 leading whitespace를 제거하지만 나머지 argument의 whitespace는 보존합니다. 첫 parameter를 space로 시작하려면 빈 variable로 `space`를 만든 뒤 조합하는 우회 기법이 필요합니다.

empty :=
space := $(empty) $(empty)
$(info $(space)$(space)hello)

Kconfig는 delimiter로 comma만 사용하며 function call 내부 whitespace를 모두 보존합니다. `$(func-name, arg1, arg2, arg3)`처럼 comma 뒤에 space를 넣으면 함수는 실제로 `" arg1"`, `" arg2"`, `" arg3"`을 받습니다. Leading space가 중요한 함수에서는 결과가 달라질 수 있습니다.

Make에도 같은 주의점이 있습니다. `$(subst .c, .o, $(sources))`는 `.c`를 `.o`가 아니라 앞에 space가 붙은 ` .o`로 바꾸는 전형적인 실수입니다.

Make와 Kconfig function call
항목MakeKconfig
호출 형태`$(func-name arg1,arg2)``$(func-name,arg1,arg2)`
이름/첫 인자 구분WhitespaceComma
첫 인자 leading whitespace제거보존
User function`$(call my-func,...)``$(my-func,...)`
괄호 안 comma함수에 따라 literal 가능항상 argument delimiter

두 언어의 delimiter와 whitespace 처리 차이입니다.

Make는 user-defined function을 `$(call my-func,arg1,arg2,arg3)`처럼 built-in `call`을 통해 참조합니다. Kconfig는 user-defined function과 built-in function을 같은 방식으로 호출하므로 `call`을 생략하고 더 짧게 씁니다.

Make의 일부 함수는 comma를 argument separator가 아닌 literal로 취급합니다. 그래서 `$(shell echo hello, world)`는 `echo hello, world`를 실행하고 `$(info hello, world)`는 해당 문장을 출력합니다. 이는 유용하지만 일관되지 않은 동작입니다.

Kconfig는 구현과 grammar를 단순하고 일관되게 유지하기 위해 `$( )` 안의 모든 comma를 delimiter로 해석합니다. 따라서 `$(shell, echo hello, world)`는 argument 하나만 받는 `shell`에 두 parameter를 전달하므로 error입니다.

Argument에 comma를 넣으려면 `comma := ,`를 먼저 정의한 뒤 `$(shell, echo hello$(comma) world)`처럼 variable expansion으로 삽입해야 합니다.

Kconfig comma 전달
`comma := ,`로 comma text 정의Function call에는 `$(comma)` reference 사용Parser는 바깥 comma만 argument delimiter로 처리Macro expansion이 argument 안에 literal comma 삽입

Literal comma는 호출 parser를 통과한 뒤 확장되도록 우회합니다.

Make vs Kconfig
---------------

Kconfig adopts Make-like macro language, but the function call syntax is
slightly different.

A function call in Make looks like this::

  $(func-name arg1,arg2,arg3)

The function name and the first argument are separated by at least one
whitespace. Then, leading whitespaces are trimmed from the first argument,
while whitespaces in the other arguments are kept. You need to use a kind of
trick to start the first parameter with spaces. For example, if you want
to make "info" function print "  hello", you can write like follows::

  empty :=
  space := $(empty) $(empty)
  $(info $(space)$(space)hello)

Kconfig uses only commas for delimiters, and keeps all whitespaces in the
function call. Some people prefer putting a space after each comma delimiter::

  $(func-name, arg1, arg2, arg3)

In this case, "func-name" will receive " arg1", " arg2", " arg3". The presence
of leading spaces may matter depending on the function. The same applies to
Make - for example, $(subst .c, .o, $(sources)) is a typical mistake; it
replaces ".c" with " .o".

In Make, a user-defined function is referenced by using a built-in function,
'call', like this::

    $(call my-func,arg1,arg2,arg3)

Kconfig invokes user-defined functions and built-in functions in the same way.
The omission of 'call' makes the syntax shorter.

In Make, some functions treat commas verbatim instead of argument separators.
For example, $(shell echo hello, world) runs the command "echo hello, world".
Likewise, $(info hello, world) prints "hello, world" to stdout. You could say
this is _useful_ inconsistency.

In Kconfig, for simpler implementation and grammatical consistency, commas that
appear in the $( ) context are always delimiters. It means::

  $(shell, echo hello, world)

is an error because it is passing two parameters where the 'shell' function
accepts only one. To pass commas in arguments, you can use the following trick::

  comma := ,
  $(shell, echo hello$(comma) world)

확장 한계와 주의사항

197-247

Variable이나 function은 여러 token에 걸쳐 확장될 수 없습니다. 따라서 여러 token으로 이루어진 expression 전체의 shorthand로 variable을 사용할 수 없습니다.

예를 들어 `RANGE_MIN := 1`, `RANGE_MAX := 3`을 각각 정의하고 `range $(RANGE_MIN) $(RANGE_MAX)`로 쓰면 각 reference가 token 하나에 대응하므로 동작합니다.

RANGE_MIN := 1
RANGE_MAX := 3

config FOO
        int "foo"
        range $(RANGE_MIN) $(RANGE_MAX)

반면 `RANGES := 1 3`을 정의하고 `range $(RANGES)`로 쓰면 하나의 variable expansion이 두 token을 대신하려 하므로 동작하지 않습니다.

RANGES := 1 3

config FOO
        int "foo"
        range $(RANGES)

Variable을 Kconfig keyword로 확장하는 것도 허용되지 않습니다. `MY_TYPE := tristate`를 정의하고 config entry에서 `$(MY_TYPE) "foo"`를 쓰는 방식은 동작하지 않습니다. Type keyword는 source grammar에 직접 나타나야 합니다.

MY_TYPE := tristate

config FOO
        $(MY_TYPE) "foo"
        default y

설계상 `shell` 함수는 textual substitution 단계에서 확장되므로 Kconfig symbol을 shell command에 전달할 수 없습니다. Symbol value는 그 다음 evaluation 단계에서 결정되기 때문입니다.

따라서 `ENDIAN_FLAG` string symbol에 CPU endianness에 따른 compiler flag를 넣고 `gcc-check-flag ENDIAN_FLAG`를 실행하면 symbol의 값이 아니라 literal name이 전달되어 기대대로 동작하지 않습니다.

대신 각 function call이 정적으로 확장되도록 두 command를 직접 작성하고, Kconfig dependency를 각 default에 붙입니다. `CPU_BIG_ENDIAN`일 때 `-mbig-endian` 검사 결과를, `CPU_LITTLE_ENDIAN`일 때 `-mlittle-endian` 검사 결과를 사용합니다.

config CC_HAS_ENDIAN_FLAG
        bool
        default $(shell $(srctree)/scripts/gcc-check-flag -mbig-endian) if CPU_BIG_ENDIAN
        default $(shell $(srctree)/scripts/gcc-check-flag -mlittle-endian) if CPU_LITTLE_ENDIAN
매크로 확장의 경계
시도결과대안
Variable 하나로 여러 token 생성지원하지 않음Token마다 별도 variable 사용
Variable을 Kconfig keyword로 확장지원하지 않음Keyword를 source에 직접 작성
Kconfig symbol을 `shell`에 전달평가 전이라 값 사용 불가정적 call마다 Kconfig condition 부여

문법 token과 symbol evaluation은 textual substitution보다 뒤에 있습니다.

Caveats
-------

A variable (or function) cannot be expanded across tokens. So, you cannot use
a variable as a shorthand for an expression that consists of multiple tokens.
The following works::

    RANGE_MIN := 1
    RANGE_MAX := 3

    config FOO
            int "foo"
            range $(RANGE_MIN) $(RANGE_MAX)

But, the following does not work::

    RANGES := 1 3

    config FOO
            int "foo"
            range $(RANGES)

A variable cannot be expanded to any keyword in Kconfig.  The following does
not work::

    MY_TYPE := tristate

    config FOO
            $(MY_TYPE) "foo"
            default y

Obviously from the design, $(shell command) is expanded in the textual
substitution phase. You cannot pass symbols to the 'shell' function.

The following does not work as expected::

    config ENDIAN_FLAG
            string
            default "-mbig-endian" if CPU_BIG_ENDIAN
            default "-mlittle-endian" if CPU_LITTLE_ENDIAN

    config CC_HAS_ENDIAN_FLAG
            def_bool $(shell $(srctree)/scripts/gcc-check-flag ENDIAN_FLAG)

Instead, you can do like follows so that any function call is statically
expanded::

    config CC_HAS_ENDIAN_FLAG
            bool
            default $(shell $(srctree)/scripts/gcc-check-flag -mbig-endian) if CPU_BIG_ENDIAN
            default $(shell $(srctree)/scripts/gcc-check-flag -mlittle-endian) if CPU_LITTLE_ENDIAN