2019-05-19 20:07:45 +08:00
|
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
2018-05-28 17:21:59 +08:00
|
|
|
# Kconfig helper macros
|
|
|
|
|
|
|
|
# Convenient variables
|
|
|
|
comma := ,
|
|
|
|
quote := "
|
|
|
|
squote := '
|
|
|
|
empty :=
|
|
|
|
space := $(empty) $(empty)
|
|
|
|
dollar := $
|
|
|
|
right_paren := )
|
|
|
|
left_paren := (
|
|
|
|
|
|
|
|
# $(if-success,<command>,<then>,<else>)
|
|
|
|
# Return <then> if <command> exits with 0, <else> otherwise.
|
|
|
|
if-success = $(shell,{ $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)")
|
|
|
|
|
|
|
|
# $(success,<command>)
|
|
|
|
# Return y if <command> exits with 0, n otherwise
|
|
|
|
success = $(if-success,$(1),y,n)
|
|
|
|
|
2019-05-09 15:35:55 +08:00
|
|
|
# $(failure,<command>)
|
|
|
|
# Return n if <command> exits with 0, y otherwise
|
|
|
|
failure = $(if-success,$(1),n,y)
|
|
|
|
|
2018-05-28 17:21:59 +08:00
|
|
|
# $(cc-option,<flag>)
|
|
|
|
# Return y if the compiler supports <flag>, n otherwise
|
2022-07-28 11:14:33 +08:00
|
|
|
cc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$/tmp.o)
|
2018-05-28 17:21:59 +08:00
|
|
|
|
|
|
|
# $(ld-option,<flag>)
|
|
|
|
# Return y if the linker supports <flag>, n otherwise
|
|
|
|
ld-option = $(success,$(LD) -v $(1))
|
2018-05-28 17:22:06 +08:00
|
|
|
|
2020-01-15 19:30:07 +08:00
|
|
|
# $(as-instr,<instr>)
|
|
|
|
# Return y if the assembler supports <instr>, n otherwise
|
2024-01-26 01:32:11 +08:00
|
|
|
as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -Wa$(comma)--fatal-warnings -c -x assembler-with-cpp -o /dev/null -)
|
2020-01-15 19:30:07 +08:00
|
|
|
|
2019-05-09 15:35:55 +08:00
|
|
|
# check if $(CC) and $(LD) exist
|
2021-07-03 22:42:57 +08:00
|
|
|
$(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found)
|
2019-05-09 15:35:55 +08:00
|
|
|
$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)
|
|
|
|
|
2021-07-03 22:42:57 +08:00
|
|
|
# Get the C compiler name, version, and error out if it is not supported.
|
2021-01-16 07:35:42 +08:00
|
|
|
cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC))
|
2021-07-03 22:42:57 +08:00
|
|
|
$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this C compiler is not supported.)
|
2021-01-16 07:35:42 +08:00
|
|
|
cc-name := $(shell,set -- $(cc-info) && echo $1)
|
|
|
|
cc-version := $(shell,set -- $(cc-info) && echo $2)
|
|
|
|
|
kbuild: check the minimum assembler version in Kconfig
Documentation/process/changes.rst defines the minimum assembler version
(binutils version), but we have never checked it in the build time.
Kbuild never invokes 'as' directly because all assembly files in the
kernel tree are *.S, hence must be preprocessed. I do not expect
raw assembly source files (*.s) would be added to the kernel tree.
Therefore, we always use $(CC) as the assembler driver, and commit
aa824e0c962b ("kbuild: remove AS variable") removed 'AS'. However,
we are still interested in the version of the assembler acting behind.
As usual, the --version option prints the version string.
$ as --version | head -n 1
GNU assembler (GNU Binutils for Ubuntu) 2.35.1
But, we do not have $(AS). So, we can add the -Wa prefix so that
$(CC) passes --version down to the backing assembler.
$ gcc -Wa,--version | head -n 1
gcc: fatal error: no input files
compilation terminated.
OK, we need to input something to satisfy gcc.
$ gcc -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1
GNU assembler (GNU Binutils for Ubuntu) 2.35.1
The combination of Clang and GNU assembler works in the same way:
$ clang -no-integrated-as -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1
GNU assembler (GNU Binutils for Ubuntu) 2.35.1
Clang with the integrated assembler fails like this:
$ clang -integrated-as -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1
clang: error: unsupported argument '--version' to option 'Wa,'
For the last case, checking the error message is fragile. If the
proposal for -Wa,--version support [1] is accepted, this may not be
even an error in the future.
One easy way is to check if -integrated-as is present in the passed
arguments. We did not pass -integrated-as to CLANG_FLAGS before, but
we can make it explicit.
Nathan pointed out -integrated-as is the default for all of the
architectures/targets that the kernel cares about, but it goes
along with "explicit is better than implicit" policy. [2]
With all this in my mind, I implemented scripts/as-version.sh to
check the assembler version in Kconfig time.
$ scripts/as-version.sh gcc
GNU 23501
$ scripts/as-version.sh clang -no-integrated-as
GNU 23501
$ scripts/as-version.sh clang -integrated-as
LLVM 0
[1]: https://github.com/ClangBuiltLinux/linux/issues/1320
[2]: https://lore.kernel.org/linux-kbuild/20210307044253.v3h47ucq6ng25iay@archlinux-ax161/
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
2021-03-16 00:12:56 +08:00
|
|
|
# Get the assembler name, version, and error out if it is not supported.
|
|
|
|
as-info := $(shell,$(srctree)/scripts/as-version.sh $(CC) $(CLANG_FLAGS))
|
|
|
|
$(error-if,$(success,test -z "$(as-info)"),Sorry$(comma) this assembler is not supported.)
|
|
|
|
as-name := $(shell,set -- $(as-info) && echo $1)
|
|
|
|
as-version := $(shell,set -- $(as-info) && echo $2)
|
|
|
|
|
2021-02-16 11:10:04 +08:00
|
|
|
# Get the linker name, version, and error out if it is not supported.
|
|
|
|
ld-info := $(shell,$(srctree)/scripts/ld-version.sh $(LD))
|
|
|
|
$(error-if,$(success,test -z "$(ld-info)"),Sorry$(comma) this linker is not supported.)
|
|
|
|
ld-name := $(shell,set -- $(ld-info) && echo $1)
|
|
|
|
ld-version := $(shell,set -- $(ld-info) && echo $2)
|
2019-07-17 03:47:27 +08:00
|
|
|
|
kconfig: introduce m32-flag and m64-flag
When a compiler supports multiple architectures, some compiler features
can be dependent on the target architecture.
This is typical for Clang, which supports multiple LLVM backends.
Even for GCC, we need to take care of biarch compiler cases.
It is not a problem when we evaluate cc-option in Makefiles because
cc-option is tested against the flag in question + $(KBUILD_CFLAGS).
The cc-option in Kconfig, on the other hand, does not accumulate
tested flags. Due to this simplification, it could potentially test
cc-option against a different target.
At first, Kconfig always evaluated cc-option against the host
architecture.
Since commit e8de12fb7cde ("kbuild: Check for unknown options with
cc-option usage in Kconfig and clang"), in case of cross-compiling
with Clang, the target triple is correctly passed to Kconfig.
The case with biarch GCC (and native build with Clang) is still not
handled properly. We need to pass some flags to specify the target
machine bit.
Due to the design, all the macros in Kconfig are expanded in the
parse stage, where we do not know the target bit size yet.
For example, arch/x86/Kconfig allows a user to toggle CONFIG_64BIT.
If a compiler flag -foo depends on the machine bit, it must be tested
twice, one with -m32 and the other with -m64.
However, -m32/-m64 are not always recognized. So, this commits adds
m64-flag and m32-flag macros. They expand to -m32, -m64, respectively
if supported. Or, they expand to an empty string if unsupported.
The typical usage is like this:
config FOO
bool
default $(cc-option,$(m64-flag) -foo) if 64BIT
default $(cc-option,$(m32-flag) -foo)
This is clumsy, but there is no elegant way to handle this in the
current static macro expansion.
There was discussion for static functions vs dynamic functions.
The consensus was to go as far as possible with the static functions.
(https://lkml.org/lkml/2018/3/2/22)
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Tested-by: George Spelvin <lkml@sdf.org>
Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
2020-03-10 18:12:49 +08:00
|
|
|
# machine bit flags
|
|
|
|
# $(m32-flag): -m32 if the compiler supports it, or an empty string otherwise.
|
|
|
|
# $(m64-flag): -m64 if the compiler supports it, or an empty string otherwise.
|
|
|
|
cc-option-bit = $(if-success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null,$(1))
|
|
|
|
m32-flag := $(cc-option-bit,-m32)
|
|
|
|
m64-flag := $(cc-option-bit,-m64)
|