On Thu, Nov 24, 2022 at 12:19 AM Masahiro Yamada <masahiroy@xxxxxxxxxx> wrote: > > Because GNU Make is only able to handle strings, it is very hard to > perform arighmetic in Makefiles. I terribly missed that GNU Make 4.4 introduced the $(intcmp ...) function. https://www.gnu.org/software/make/manual/make.html#Conditional-Functions I am thinking if we can do better by using it. > > When we compare two integers, we invokes shell. One example is in the > top Makefile: > > ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 130000; echo $$?),0) > > This is more expensive than using built-in functions since it forks a > process. > > If we know the two have the same number of digits, we can do better. > > This commit adds four macros, test-le, test-ge, test-lt, test-gt. > > $(call test-lt, A, B) is evaluated to 'y' if A is less than B, or > empty otherwise. This will replace $(call shell test A -lt B). > > Again, the limitation is that A and B must have the same number of > digits because these macros are based on $(sort ) function. > > $(call test-lt, 1, 9) --> y (Works!) > $(call test-lt, 10, 9) --> y (Not work...) > > To make the latter work, you need to add '0' prefix to align the number > of digits: > > $(call test-lt, 10, 09) --> empty (Works!) > > Actually, we can live with this limitation in many places. As for the > example above, we know $(CONFIG_LLD_VERSION) is 6-digits because the > minimal supported version of LLVM is 11.0.0. > > So, the shell invocation can be replaced with more efficient code: > > ifeq ($(call test-lt, $(CONFIG_LLD_VERSION), 130000),y) > > Of course, this assumption will break when LLVM 100 is released, but it > will be far in the future. > > Signed-off-by: Masahiro Yamada <masahiroy@xxxxxxxxxx> > --- > > (no changes since v1) > > Makefile | 2 +- > arch/riscv/Makefile | 2 +- > arch/x86/Makefile | 2 +- > scripts/Kbuild.include | 10 ++++++++++ > 4 files changed, 13 insertions(+), 3 deletions(-) > > diff --git a/Makefile b/Makefile > index 6f846b1f2618..eb80332f7b51 100644 > --- a/Makefile > +++ b/Makefile > @@ -986,7 +986,7 @@ KBUILD_LDFLAGS += -mllvm -import-instr-limit=5 > # Check for frame size exceeding threshold during prolog/epilog insertion > # when using lld < 13.0.0. > ifneq ($(CONFIG_FRAME_WARN),0) > -ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 130000; echo $$?),0) > +ifeq ($(call test-lt, $(CONFIG_LLD_VERSION), 130000),y) > KBUILD_LDFLAGS += -plugin-opt=-warn-stack-size=$(CONFIG_FRAME_WARN) > endif > endif > diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile > index 0d13b597cb55..faf2c2177094 100644 > --- a/arch/riscv/Makefile > +++ b/arch/riscv/Makefile > @@ -37,7 +37,7 @@ else > endif > > ifeq ($(CONFIG_LD_IS_LLD),y) > -ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 150000; echo $$?),0) > +ifeq ($(call test-lt, $(CONFIG_LLD_VERSION), 150000),y) > KBUILD_CFLAGS += -mno-relax > KBUILD_AFLAGS += -mno-relax > ifndef CONFIG_AS_IS_LLVM > diff --git a/arch/x86/Makefile b/arch/x86/Makefile > index 415a5d138de4..e72c7a49cd59 100644 > --- a/arch/x86/Makefile > +++ b/arch/x86/Makefile > @@ -211,7 +211,7 @@ endif > KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE) > > ifdef CONFIG_LTO_CLANG > -ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 130000; echo $$?),0) > +ifeq ($(call test-lt, $(CONFIG_LLD_VERSION), 130000),y) > KBUILD_LDFLAGS += -plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8) > endif > endif > diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include > index cbe28744637b..9996f34327cb 100644 > --- a/scripts/Kbuild.include > +++ b/scripts/Kbuild.include > @@ -11,6 +11,16 @@ space := $(empty) $(empty) > space_escape := _-_SPACE_-_ > pound := \# > > +### > +# Comparison macros. > +# Usage: $(call test-le, A, B) > +# works like shell's "test A -le B", but A and B must have the same number of > +# digits since it is just ASCII sort. > +test-le = $(if $(filter $1, $(firstword $(sort $1 $2))),y) > +test-ge = $(call test-le, $2, $1) > +test-lt = $(if $(filter-out $2, $(firstword $(sort $1 $2))),y) > +test-gt = $(call test-lt, $2, $1) > + > ### > # Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o > dot-target = $(dir $@).$(notdir $@) > -- > 2.34.1 > -- Best Regards Masahiro Yamada