Skip to content

Commit

Permalink
Merge tag 'kconfig-v4.18' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/masahiroy/linux-kbuild

Pull Kconfig updates from Masahiro Yamada:
 "Kconfig now supports new functionality to perform textual
  substitution. It has been a while since Linus suggested to move
  compiler option tests from makefiles to Kconfig. Finally, here it is.

  The implementation has been generalized into a Make-like macro
  language.

  Some built-in functions such as 'shell' are provided. Variables and
  user-defined functions are also supported so that 'cc-option',
  'ld-option', etc. are implemented as macros.

  Summary:

   - refactor package checks for building {m,n,q,g}conf

   - remove unused/unmaintained localization support

   - remove Kbuild cache

   - drop CONFIG_CROSS_COMPILE support

   - replace 'option env=' with direct variable expansion

   - add built-in functions such as 'shell'

   - support variables and user-defined functions

   - add helper macros as as 'cc-option'

   - add unit tests and a document of the new macro language

   - add 'testconfig' to help

   - fix warnings from GCC 8.1"

* tag 'kconfig-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (30 commits)
  kconfig: Avoid format overflow warning from GCC 8.1
  kbuild: Move last word of nconfig help to the previous line
  kconfig: Add testconfig into make help output
  kconfig: add basic helper macros to scripts/Kconfig.include
  kconfig: show compiler version text in the top comment
  kconfig: test: add Kconfig macro language tests
  Documentation: kconfig: document a new Kconfig macro language
  kconfig: error out if a recursive variable references itself
  kconfig: add 'filename' and 'lineno' built-in variables
  kconfig: add 'info', 'warning-if', and 'error-if' built-in functions
  kconfig: expand lefthand side of assignment statement
  kconfig: support append assignment operator
  kconfig: support simply expanded variable
  kconfig: support user-defined function and recursively expanded variable
  kconfig: begin PARAM state only when seeing a command keyword
  kconfig: replace $(UNAME_RELEASE) with function call
  kconfig: add 'shell' built-in function
  kconfig: add built-in function support
  kconfig: make default prompt of mainmenu less specific
  kconfig: remove sym_expand_string_value()
  ...
  • Loading branch information
Linus Torvalds committed Jun 6, 2018
2 parents 8715ee7 + 2ae89c7 commit 0ad39cb
Show file tree
Hide file tree
Showing 59 changed files with 1,666 additions and 1,143 deletions.
8 changes: 0 additions & 8 deletions Documentation/kbuild/kconfig-language.txt
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,6 @@ applicable everywhere (see syntax).
enables the third modular state for all config symbols.
At most one symbol may have the "modules" option set.

- "env"=<value>
This imports the environment variable into Kconfig. It behaves like
a default, except that the value comes from the environment, this
also means that the behaviour when mixing it with normal defaults is
undefined at this point. The symbol is currently not exported back
to the build environment (if this is desired, it can be done via
another symbol).

- "allnoconfig_y"
This declares the symbol as one that should have the value y when
using "allnoconfig". Used for symbols that hide other symbols.
Expand Down
242 changes: 242 additions & 0 deletions Documentation/kbuild/kconfig-macro-language.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
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.txt.


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".


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 $(fileno), $(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 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)


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
10 changes: 5 additions & 5 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/kconfig-language.txt.
#
mainmenu "Linux/$ARCH $KERNELVERSION Kernel Configuration"
mainmenu "Linux/$(ARCH) $(KERNELVERSION) Kernel Configuration"

config SRCARCH
string
option env="SRCARCH"
comment "Compiler: $(CC_VERSION_TEXT)"

source "arch/$SRCARCH/Kconfig"
source "scripts/Kconfig.include"

source "arch/$(SRCARCH)/Kconfig"
3 changes: 2 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7684,8 +7684,9 @@ M: Masahiro Yamada <yamada.masahiro@socionext.com>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git kconfig
L: linux-kbuild@vger.kernel.org
S: Maintained
F: Documentation/kbuild/kconfig-language.txt
F: Documentation/kbuild/kconfig*
F: scripts/kconfig/
F: scripts/Kconfig.include

KDUMP
M: Dave Young <dyoung@redhat.com>
Expand Down
10 changes: 4 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -316,12 +316,9 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
# CROSS_COMPILE can be set on the command line
# make CROSS_COMPILE=ia64-linux-
# Alternatively CROSS_COMPILE can be set in the environment.
# A third alternative is to store a setting in .config so that plain
# "make" in the configured kernel build directory always uses that.
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)

# Architecture as present in compile.h
UTS_MACHINE := $(ARCH)
Expand Down Expand Up @@ -445,6 +442,8 @@ export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
export KBUILD_ARFLAGS

export CC_VERSION_TEXT := $(shell $(CC) --version | head -n 1)

# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
# even be read-only.
Expand Down Expand Up @@ -504,7 +503,7 @@ KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
KBUILD_AFLAGS += $(call cc-option,-fno-PIE)

# check for 'asm goto'
ifeq ($(call shell-cached,$(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) $(KBUILD_CFLAGS)), y)
ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) $(KBUILD_CFLAGS)), y)
CC_HAVE_ASM_GOTO := 1
KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO
KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO
Expand Down Expand Up @@ -807,7 +806,7 @@ KBUILD_CFLAGS_KERNEL += $(call cc-option,-fdata-sections,)
endif

# arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS += -nostdinc -isystem $(call shell-cached,$(CC) -print-file-name=include)
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)

# warn about C99 declaration after statement
KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
Expand Down Expand Up @@ -1630,7 +1629,6 @@ clean: $(clean-dirs)
-o -name '*.asn1.[ch]' \
-o -name '*.symtypes' -o -name 'modules.order' \
-o -name modules.builtin -o -name '.tmp_*.o.*' \
-o -name .cache.mk \
-o -name '*.c.[012]*.*' \
-o -name '*.ll' \
-o -name '*.gcno' \) -type f -print | xargs rm -f
Expand Down
4 changes: 2 additions & 2 deletions arch/sh/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ config SUPERH
<http://www.linux-sh.org/>.

config SUPERH32
def_bool ARCH = "sh"
def_bool "$(ARCH)" = "sh"
select HAVE_KPROBES
select HAVE_KRETPROBES
select HAVE_IOREMAP_PROT if MMU && !X2TLB
Expand All @@ -79,7 +79,7 @@ config SUPERH32
select HAVE_CC_STACKPROTECTOR

config SUPERH64
def_bool ARCH = "sh64"
def_bool "$(ARCH)" = "sh64"
select HAVE_EXIT_THREAD
select KALLSYMS

Expand Down
4 changes: 2 additions & 2 deletions arch/sparc/Kconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
config 64BIT
bool "64-bit kernel" if ARCH = "sparc"
default ARCH = "sparc64"
bool "64-bit kernel" if "$(ARCH)" = "sparc"
default "$(ARCH)" = "sparc64"
help
SPARC is a family of RISC microprocessors designed and marketed by
Sun Microsystems, incorporated. They are very widely found in Sun
Expand Down
4 changes: 0 additions & 4 deletions arch/um/Kconfig.common
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ config HZ
int
default 100

config SUBARCH
string
option env="SUBARCH"

config NR_CPUS
int
range 1 1
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
# Select 32 or 64 bit
config 64BIT
bool "64-bit kernel" if ARCH = "x86"
default ARCH != "i386"
bool "64-bit kernel" if "$(ARCH)" = "x86"
default "$(ARCH)" != "i386"
---help---
Say yes to build a 64-bit kernel - formerly known as x86_64
Say no to build a 32-bit kernel - formerly known as i386
Expand Down
Loading

0 comments on commit 0ad39cb

Please sign in to comment.