@@ -304,11 +304,6 @@ HOSTCXX = g++
HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89
HOSTCXXFLAGS = -O2
-ifeq ($(shell $(HOSTCC) -v 2>&1 | grep -c "clang version"), 1)
-HOSTCFLAGS += -Wno-unused-value -Wno-unused-parameter \
- -Wno-missing-field-initializers -fno-delete-null-pointer-checks
-endif
-
# Decide whether to build built-in, modular, or both.
# Normally, just do built-in.
@@ -343,6 +338,11 @@ export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
scripts/Kbuild.include: ;
include scripts/Kbuild.include
+ifeq ($(call cached-shell,$(HOSTCC) -v 2>&1 | grep -c "clang version"), 1)
+HOSTCFLAGS += -Wno-unused-value -Wno-unused-parameter \
+ -Wno-missing-field-initializers -fno-delete-null-pointer-checks
+endif
+
# Make variables (CC, etc...)
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
@@ -767,7 +767,7 @@ KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
endif
# arch Makefile may override CC so keep this after arch Makefile is included
-NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
+NOSTDINC_FLAGS += -nostdinc -isystem $(call cached-shell,$(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)
# warn about C99 declaration after statement
@@ -798,7 +798,7 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
KBUILD_ARFLAGS := $(call ar-option,D)
# check for 'asm goto'
-ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC)), y)
+ifeq ($(call cached-shell,$(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC)), y)
KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO
KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO
endif
@@ -1237,6 +1237,7 @@ endif # CONFIG_MODULES
# Directories & files removed with 'make clean'
CLEAN_DIRS += $(MODVERDIR)
+CLEAN_FILES += $(KBUILD_SHELLCACHE)
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config usr/include include/generated \
@@ -7,6 +7,7 @@ quote := "
squote := '
empty :=
space := $(empty) $(empty)
+tab := $(empty) $(empty)
space_escape := _-_SPACE_-_
###
@@ -83,11 +84,35 @@ cc-cross-prefix = \
# output directory for tests below
TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
+KBUILD_SHELLCACHE := .shellcache
+
+ifeq ($(KBUILD_SHELLCACHE),)
+cached-shell = $(shell $(1))
+else
+-include $(KBUILD_SHELLCACHE)
+
+sanitize = $(subst $(space),_, \
+ $(subst $(tab),_, \
+ $(subst \n,_, \
+ $(subst :,_, \
+ $(subst \#,_, \
+ $(subst =,_, \
+ $(subst $$,_, \
+ $(subst ',_, \
+ $(subst ",_, \
+ $(1))))))))))
+
+cached-shell = $(if $(cmd$(call sanitize,$(1))),$(subst CACHED,,$(cmd$(call sanitize,$(1)))),$(shell \
+ res='$(shell $(1))'; \
+ echo "$$res"; \
+ echo 'cmd$(call sanitize,$(1)) = CACHED'"$$res" >> $(KBUILD_SHELLCACHE)))
+endif
+
# try-run
# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
# Exit code chooses option. "$$TMP" is can be used as temporary file and
# is automatically cleaned up.
-try-run = $(shell set -e; \
+try-run = $(call cached-shell,set -e; \
TMP="$(TMPOUT).$$$$.tmp"; \
TMPO="$(TMPOUT).$$$$.o"; \
if ($(1)) >/dev/null 2>&1; \
@@ -131,18 +156,19 @@ cc-disable-warning = $(call try-run,\
# cc-name
# Expands to either gcc or clang
-cc-name = $(shell $(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc)
+cc-name = $(call cached-shell,$(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc)
# cc-version
-cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))
+cc-version = $(call cached-shell,$(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))
# cc-fullversion
-cc-fullversion = $(shell $(CONFIG_SHELL) \
+cc-fullversion = $(call cached-shell $(CONFIG_SHELL) \
$(srctree)/scripts/gcc-version.sh -p $(CC))
# cc-ifversion
# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
-cc-ifversion = $(shell [ $(cc-version) $(1) $(2) ] && echo $(3) || echo $(4))
+cc-ifversion = $(call cached-shell, \
+ [ $(cc-version) $(1) $(2) ] && echo $(3) || echo $(4))
# cc-ldoption
# Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
@@ -161,11 +187,13 @@ ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2))
# ld-version
# Note this is mainly for HJ Lu's 3 number binutil versions
-ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh)
+ld-version = $(call cached-shell, \
+ $(LD) --version | $(srctree)/scripts/ld-version.sh)
# ld-ifversion
# Usage: $(call ld-ifversion, -ge, 22252, y)
-ld-ifversion = $(shell [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4))
+ld-ifversion = $(call cached-shell, \
+ [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4))
######
Running make results in over 40 invocations of the compiler just during processing of the Makefile, before any actual rules are run. To reduce this overhead, cache the results of $(shell) calls to the compiler. On my machine, this reduces make's processing time by over 96%: $ make kernelversion && perf stat -r5 make kernelversion Before: 0,252219929 seconds time elapsed ( +- 0,39% ) After: 0,008607464 seconds time elapsed ( +- 0,50% ) Signed-off-by: Rabin Vincent <rabin@rab.in> --- Makefile | 15 ++++++++------- scripts/Kbuild.include | 42 +++++++++++++++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 14 deletions(-)