1# SPDX-License-Identifier: GPL-2.0 2#### 3# kbuild: Generic definitions 4 5# Convenient variables 6squote := ' 7empty := 8space := $(empty) $(empty) 9space_escape := _-_SPACE_-_ 10pound := \# 11 12### 13# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o 14dot-target = $(@D)/.$(@F) 15 16### 17# dependencies 18depfile = $(dot-target).d 19 20### 21# real prerequisites without phony targets 22real-prereqs = $(filter-out $(PHONY), $^) 23 24### 25# Escape single quote for use in echo statements 26escsq = $(subst $(squote),'\$(squote)',$1) 27 28### 29# Easy method for doing a status message 30 kecho := : 31 quiet_kecho := echo 32silent_kecho := : 33kecho := $($(quiet)kecho) 34 35### 36# filechk is used to check if the content of a generated file is updated. 37# Sample usage: 38# 39# filechk_sample = echo $(KERNELRELEASE) 40# version.h: FORCE 41# $(call filechk,sample) 42# 43# The rule defined shall write to stdout the content of the new file. 44# The existing file will be compared with the new one. 45# - If no file exist it is created 46# - If the content differ the new file is used 47# - If they are equal no change, and no timestamp update 48define filechk 49 $(Q)set -e; \ 50 mkdir -p $(dir $@); \ 51 trap "rm -f $(dot-target).tmp" EXIT; \ 52 { $(filechk_$(1)); } > $(dot-target).tmp; \ 53 if [ ! -r $@ ] || ! cmp -s $@ $(dot-target).tmp; then \ 54 $(kecho) ' UPD $@'; \ 55 mv -f $(dot-target).tmp $@; \ 56 fi 57endef 58 59# as-insn: Check whether assembler supports an instruction. 60# Usage: cflags-y += $(call as-insn,CC FLAGS,"insn",option-yes,option-no) 61as-insn = $(if $(shell echo 'void _(void) { asm volatile ( $(2) ); }' \ 62 | $(filter-out -include %/include/xen/config.h,$(1)) \ 63 -c -x c -o /dev/null - 2>&1),$(4),$(3)) 64 65# as-option-add: Conditionally add options to flags 66# Usage: $(call as-option-add,CFLAGS,CC,"insn",option-yes,option-no) 67as-option-add = $(eval $(call as-option-add-closure,$(1),$(2),$(3),$(4),$(5))) 68define as-option-add-closure 69 ifeq ($$(call as-insn,$$($(2)) $$($(1)),$$(3),y,n),y) 70 $(1) += $(4) 71 else 72 $(1) += $(5) 73 endif 74endef 75 76# $(call if-success,<command>,<then>,<else>) 77# Return <then> if <command> exits with 0, <else> otherwise. 78if-success = $(shell { $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)") 79 80# $(call success,<command>) 81# Return y if <command> exits with 0, n otherwise 82success = $(call if-success,$(1),y,n) 83 84# $(call ld-option,<flag>) 85# Return y if the linker supports <flag>, n otherwise 86ld-option = $(call success,$(LD) -v $(1)) 87 88# cc-ifversion 89# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) 90cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4)) 91 92clang-ifversion = $(shell [ $(CONFIG_CLANG_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4)) 93 94### 95# Shorthand for $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.asm-generic obj 96# Usage: 97# $(Q)$(MAKE) $(asm-generic)=dir 98asm-generic := -f $(srctree)/scripts/Makefile.asm-generic obj 99 100### 101# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= 102# Usage: 103# $(Q)$(MAKE) $(build)=dir 104build := -f $(srctree)/Rules.mk obj 105 106# Shorthand for $(MAKE) clean 107# Usage: 108# $(Q)$(MAKE) $(clean)=dir 109clean := -f $(srctree)/scripts/Makefile.clean obj 110 111# echo command. 112# Short version is used, if $(quiet) equals `quiet_', otherwise full one. 113echo-cmd = $(if $($(quiet)cmd_$(1)),\ 114 echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';) 115 116# printing commands 117cmd = @set -e; $(echo-cmd) $(cmd_$(1)) 118 119### 120# if_changed - execute command if any prerequisite is newer than 121# target, or command line has changed 122# if_changed_dep - as if_changed, but uses fixdep to reveal dependencies 123# including used config symbols 124# if_changed_rule - as if_changed but execute rule instead 125 126ifneq ($(KBUILD_NOCMDDEP),1) 127# Check if both commands are the same including their order. Result is empty 128# string if equal. User may override this check using make KBUILD_NOCMDDEP=1 129cmd-check = $(filter-out $(subst $(space),$(space_escape),$(strip $(cmd_$@))), \ 130 $(subst $(space),$(space_escape),$(strip $(cmd_$1)))) 131else 132cmd-check = $(if $(strip $(cmd_$@)),,1) 133endif 134 135# Replace >$< with >$$< to preserve $ when reloading the .cmd file 136# (needed for make) 137# Replace >#< with >$(pound)< to avoid starting a comment in the .cmd file 138# (needed for make) 139# Replace >'< with >'\''< to be able to enclose the whole string in '...' 140# (needed for the shell) 141make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1))))) 142 143# Find any prerequisites that is newer than target or that does not exist. 144# PHONY targets skipped in both cases. 145any-prereq = $(filter-out $(PHONY),$?)$(filter-out $(PHONY) $(wildcard $^),$^) 146 147# Execute command if command has changed or prerequisite(s) are updated. 148if_changed = $(if $(any-prereq)$(cmd-check), \ 149 $(cmd); \ 150 printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) 151 152# Execute the command and also postprocess generated .d dependencies file. 153if_changed_dep = $(if $(any-prereq)$(cmd-check),$(cmd_and_fixdep),@:) 154 155cmd_and_fixdep = \ 156 $(cmd); \ 157 tools/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd; \ 158 rm -f $(depfile) 159 160# Usage: $(call if_changed_rule,foo) 161# Will check if $(cmd_foo) or any of the prerequisites changed, 162# and if so will execute $(rule_foo). 163if_changed_rule = $(if $(any-prereq)$(cmd-check),$(rule_$(1)),@:) 164 165### 166# why - tell why a target got built 167# enabled by make V=2 168# Output (listed in the order they are checked): 169# (1) - due to target is PHONY 170# (2) - due to target missing 171# (3) - due to: file1.h file2.h 172# (4) - due to command line change 173# (5) - due to missing .cmd file 174# (6) - due to target not in $(targets) 175# (1) PHONY targets are always build 176# (2) No target, so we better build it 177# (3) Prerequisite is newer than target 178# (4) The command line stored in the file named dir/.target.cmd 179# differed from actual command line. This happens when compiler 180# options changes 181# (5) No dir/.target.cmd file (used to store command line) 182# (6) No dir/.target.cmd file and target not listed in $(targets) 183# This is a good hint that there is a bug in the kbuild file 184ifeq ($(KBUILD_VERBOSE),2) 185why = \ 186 $(if $(filter $@, $(PHONY)),- due to target is PHONY, \ 187 $(if $(wildcard $@), \ 188 $(if $(any-prereq),- due to: $(any-prereq), \ 189 $(if $(cmd-check), \ 190 $(if $(cmd_$@),- due to command line change, \ 191 $(if $(filter $@, $(targets)), \ 192 - due to missing .cmd file, \ 193 - due to $(notdir $@) not in $$(targets) \ 194 ) \ 195 ) \ 196 ) \ 197 ), \ 198 - due to target missing \ 199 ) \ 200 ) 201 202echo-why = $(call escsq, $(strip $(why))) 203endif 204 205# Useful for describing the dependency of composite objects 206# Usage: 207# $(call multi-depend, multi-used-targets, suffix-to-remove, suffix-to-add) 208define multi-depend 209$(foreach m, $(notdir $1), \ 210 $(eval $(obj)/$(m): \ 211 $(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s))))))) 212endef 213