162306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#### 362306a36Sopenharmony_ci# kbuild: Generic definitions 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci# Convenient variables 662306a36Sopenharmony_cicomma := , 762306a36Sopenharmony_ciquote := " 862306a36Sopenharmony_cisquote := ' 962306a36Sopenharmony_ciempty := 1062306a36Sopenharmony_cispace := $(empty) $(empty) 1162306a36Sopenharmony_cispace_escape := _-_SPACE_-_ 1262306a36Sopenharmony_cipound := \# 1362306a36Sopenharmony_cidefine newline 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ciendef 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci### 1962306a36Sopenharmony_ci# Comparison macros. 2062306a36Sopenharmony_ci# Usage: $(call test-lt, $(CONFIG_LLD_VERSION), 150000) 2162306a36Sopenharmony_ci# 2262306a36Sopenharmony_ci# Use $(intcmp ...) if supported. (Make >= 4.4) 2362306a36Sopenharmony_ci# Otherwise, fall back to the 'test' shell command. 2462306a36Sopenharmony_ciifeq ($(intcmp 1,0,,,y),y) 2562306a36Sopenharmony_citest-ge = $(intcmp $(strip $1)0, $(strip $2)0,,y,y) 2662306a36Sopenharmony_citest-gt = $(intcmp $(strip $1)0, $(strip $2)0,,,y) 2762306a36Sopenharmony_cielse 2862306a36Sopenharmony_citest-ge = $(shell test $(strip $1)0 -ge $(strip $2)0 && echo y) 2962306a36Sopenharmony_citest-gt = $(shell test $(strip $1)0 -gt $(strip $2)0 && echo y) 3062306a36Sopenharmony_ciendif 3162306a36Sopenharmony_citest-le = $(call test-ge, $2, $1) 3262306a36Sopenharmony_citest-lt = $(call test-gt, $2, $1) 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci### 3562306a36Sopenharmony_ci# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o 3662306a36Sopenharmony_cidot-target = $(dir $@).$(notdir $@) 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci### 3962306a36Sopenharmony_ci# Name of target with a '.tmp_' as filename prefix. foo/bar.o => foo/.tmp_bar.o 4062306a36Sopenharmony_citmp-target = $(dir $@).tmp_$(notdir $@) 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci### 4362306a36Sopenharmony_ci# The temporary file to save gcc -MMD generated dependencies must not 4462306a36Sopenharmony_ci# contain a comma 4562306a36Sopenharmony_cidepfile = $(subst $(comma),_,$(dot-target).d) 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci### 4862306a36Sopenharmony_ci# filename of target with directory and extension stripped 4962306a36Sopenharmony_cibasetarget = $(basename $(notdir $@)) 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci### 5262306a36Sopenharmony_ci# real prerequisites without phony targets 5362306a36Sopenharmony_cireal-prereqs = $(filter-out $(PHONY), $^) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci### 5662306a36Sopenharmony_ci# Escape single quote for use in echo statements 5762306a36Sopenharmony_ciescsq = $(subst $(squote),'\$(squote)',$1) 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci### 6062306a36Sopenharmony_ci# Quote a string to pass it to C files. foo => '"foo"' 6162306a36Sopenharmony_cistringify = $(squote)$(quote)$1$(quote)$(squote) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci### 6462306a36Sopenharmony_ci# The path to Kbuild or Makefile. Kbuild has precedence over Makefile. 6562306a36Sopenharmony_cikbuild-dir = $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) 6662306a36Sopenharmony_cikbuild-file = $(or $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Makefile) 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci### 6962306a36Sopenharmony_ci# Read a file, replacing newlines with spaces 7062306a36Sopenharmony_ci# 7162306a36Sopenharmony_ci# Make 4.2 or later can read a file by using its builtin function. 7262306a36Sopenharmony_ciifneq ($(filter-out 3.% 4.0 4.1, $(MAKE_VERSION)),) 7362306a36Sopenharmony_ciread-file = $(subst $(newline),$(space),$(file < $1)) 7462306a36Sopenharmony_cielse 7562306a36Sopenharmony_ciread-file = $(shell cat $1 2>/dev/null) 7662306a36Sopenharmony_ciendif 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci### 7962306a36Sopenharmony_ci# Easy method for doing a status message 8062306a36Sopenharmony_ci kecho := : 8162306a36Sopenharmony_ci quiet_kecho := echo 8262306a36Sopenharmony_cisilent_kecho := : 8362306a36Sopenharmony_cikecho := $($(quiet)kecho) 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci### 8662306a36Sopenharmony_ci# filechk is used to check if the content of a generated file is updated. 8762306a36Sopenharmony_ci# Sample usage: 8862306a36Sopenharmony_ci# 8962306a36Sopenharmony_ci# filechk_sample = echo $(KERNELRELEASE) 9062306a36Sopenharmony_ci# version.h: FORCE 9162306a36Sopenharmony_ci# $(call filechk,sample) 9262306a36Sopenharmony_ci# 9362306a36Sopenharmony_ci# The rule defined shall write to stdout the content of the new file. 9462306a36Sopenharmony_ci# The existing file will be compared with the new one. 9562306a36Sopenharmony_ci# - If no file exist it is created 9662306a36Sopenharmony_ci# - If the content differ the new file is used 9762306a36Sopenharmony_ci# - If they are equal no change, and no timestamp update 9862306a36Sopenharmony_cidefine filechk 9962306a36Sopenharmony_ci $(check-FORCE) 10062306a36Sopenharmony_ci $(Q)set -e; \ 10162306a36Sopenharmony_ci mkdir -p $(dir $@); \ 10262306a36Sopenharmony_ci trap "rm -f $(tmp-target)" EXIT; \ 10362306a36Sopenharmony_ci { $(filechk_$(1)); } > $(tmp-target); \ 10462306a36Sopenharmony_ci if [ ! -r $@ ] || ! cmp -s $@ $(tmp-target); then \ 10562306a36Sopenharmony_ci $(kecho) ' UPD $@'; \ 10662306a36Sopenharmony_ci mv -f $(tmp-target) $@; \ 10762306a36Sopenharmony_ci fi 10862306a36Sopenharmony_ciendef 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci### 11162306a36Sopenharmony_ci# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= 11262306a36Sopenharmony_ci# Usage: 11362306a36Sopenharmony_ci# $(Q)$(MAKE) $(build)=dir 11462306a36Sopenharmony_cibuild := -f $(srctree)/scripts/Makefile.build obj 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci### 11762306a36Sopenharmony_ci# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj= 11862306a36Sopenharmony_ci# Usage: 11962306a36Sopenharmony_ci# $(Q)$(MAKE) $(dtbinst)=dir 12062306a36Sopenharmony_cidtbinst := -f $(srctree)/scripts/Makefile.dtbinst obj 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci### 12362306a36Sopenharmony_ci# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj= 12462306a36Sopenharmony_ci# Usage: 12562306a36Sopenharmony_ci# $(Q)$(MAKE) $(clean)=dir 12662306a36Sopenharmony_ciclean := -f $(srctree)/scripts/Makefile.clean obj 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci# pring log 12962306a36Sopenharmony_ci# 13062306a36Sopenharmony_ci# If quiet is "silent_", print nothing and sink stdout 13162306a36Sopenharmony_ci# If quiet is "quiet_", print short log 13262306a36Sopenharmony_ci# If quiet is empty, print short log and whole command 13362306a36Sopenharmony_cisilent_log_print = exec >/dev/null; 13462306a36Sopenharmony_ci quiet_log_print = $(if $(quiet_cmd_$1), echo ' $(call escsq,$(quiet_cmd_$1)$(why))';) 13562306a36Sopenharmony_ci log_print = echo '$(pound) $(call escsq,$(or $(quiet_cmd_$1),cmd_$1 $@)$(why))'; \ 13662306a36Sopenharmony_ci echo ' $(call escsq,$(cmd_$1))'; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci# Delete the target on interruption 13962306a36Sopenharmony_ci# 14062306a36Sopenharmony_ci# GNU Make automatically deletes the target if it has already been changed by 14162306a36Sopenharmony_ci# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make 14262306a36Sopenharmony_ci# will delete incomplete targets), and resume it later. 14362306a36Sopenharmony_ci# 14462306a36Sopenharmony_ci# However, this does not work when the stderr is piped to another program, like 14562306a36Sopenharmony_ci# $ make >&2 | tee log 14662306a36Sopenharmony_ci# Make dies with SIGPIPE before cleaning the targets. 14762306a36Sopenharmony_ci# 14862306a36Sopenharmony_ci# To address it, we clean the target in signal traps. 14962306a36Sopenharmony_ci# 15062306a36Sopenharmony_ci# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM. 15162306a36Sopenharmony_ci# So, we cover them, and also SIGPIPE just in case. 15262306a36Sopenharmony_ci# 15362306a36Sopenharmony_ci# Of course, this is unneeded for phony targets. 15462306a36Sopenharmony_cidelete-on-interrupt = \ 15562306a36Sopenharmony_ci $(if $(filter-out $(PHONY), $@), \ 15662306a36Sopenharmony_ci $(foreach sig, HUP INT QUIT TERM PIPE, \ 15762306a36Sopenharmony_ci trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);)) 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci# print and execute commands 16062306a36Sopenharmony_cicmd = @$(if $(cmd_$(1)),set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:) 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci### 16362306a36Sopenharmony_ci# if_changed - execute command if any prerequisite is newer than 16462306a36Sopenharmony_ci# target, or command line has changed 16562306a36Sopenharmony_ci# if_changed_dep - as if_changed, but uses fixdep to reveal dependencies 16662306a36Sopenharmony_ci# including used config symbols 16762306a36Sopenharmony_ci# if_changed_rule - as if_changed but execute rule instead 16862306a36Sopenharmony_ci# See Documentation/kbuild/makefiles.rst for more info 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ciifneq ($(KBUILD_NOCMDDEP),1) 17162306a36Sopenharmony_ci# Check if both commands are the same including their order. Result is empty 17262306a36Sopenharmony_ci# string if equal. User may override this check using make KBUILD_NOCMDDEP=1 17362306a36Sopenharmony_ci# If the target does not exist, the *.cmd file should not be included so 17462306a36Sopenharmony_ci# $(savedcmd_$@) gets empty. Then, target will be built even if $(newer-prereqs) 17562306a36Sopenharmony_ci# happens to become empty. 17662306a36Sopenharmony_cicmd-check = $(filter-out $(subst $(space),$(space_escape),$(strip $(savedcmd_$@))), \ 17762306a36Sopenharmony_ci $(subst $(space),$(space_escape),$(strip $(cmd_$1)))) 17862306a36Sopenharmony_cielse 17962306a36Sopenharmony_ci# We still need to detect missing targets. 18062306a36Sopenharmony_cicmd-check = $(if $(strip $(savedcmd_$@)),,1) 18162306a36Sopenharmony_ciendif 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci# Replace >$< with >$$< to preserve $ when reloading the .cmd file 18462306a36Sopenharmony_ci# (needed for make) 18562306a36Sopenharmony_ci# Replace >#< with >$(pound)< to avoid starting a comment in the .cmd file 18662306a36Sopenharmony_ci# (needed for make) 18762306a36Sopenharmony_ci# Replace >'< with >'\''< to be able to enclose the whole string in '...' 18862306a36Sopenharmony_ci# (needed for the shell) 18962306a36Sopenharmony_cimake-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1))))) 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci# Find any prerequisites that are newer than target or that do not exist. 19262306a36Sopenharmony_ci# PHONY targets skipped in both cases. 19362306a36Sopenharmony_ci# If there is no prerequisite other than phony targets, $(newer-prereqs) becomes 19462306a36Sopenharmony_ci# empty even if the target does not exist. cmd-check saves this corner case. 19562306a36Sopenharmony_cinewer-prereqs = $(filter-out $(PHONY),$?) 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci# It is a typical mistake to forget the FORCE prerequisite. Check it here so 19862306a36Sopenharmony_ci# no more breakage will slip in. 19962306a36Sopenharmony_cicheck-FORCE = $(if $(filter FORCE, $^),,$(warning FORCE prerequisite is missing)) 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ciif-changed-cond = $(newer-prereqs)$(cmd-check)$(check-FORCE) 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci# Execute command if command has changed or prerequisite(s) are updated. 20462306a36Sopenharmony_ciif_changed = $(if $(if-changed-cond),$(cmd_and_savecmd),@:) 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cicmd_and_savecmd = \ 20762306a36Sopenharmony_ci $(cmd); \ 20862306a36Sopenharmony_ci printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci# Execute the command and also postprocess generated .d dependencies file. 21162306a36Sopenharmony_ciif_changed_dep = $(if $(if-changed-cond),$(cmd_and_fixdep),@:) 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cicmd_and_fixdep = \ 21462306a36Sopenharmony_ci $(cmd); \ 21562306a36Sopenharmony_ci scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\ 21662306a36Sopenharmony_ci rm -f $(depfile) 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci# Usage: $(call if_changed_rule,foo) 21962306a36Sopenharmony_ci# Will check if $(cmd_foo) or any of the prerequisites changed, 22062306a36Sopenharmony_ci# and if so will execute $(rule_foo). 22162306a36Sopenharmony_ciif_changed_rule = $(if $(if-changed-cond),$(rule_$(1)),@:) 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci### 22462306a36Sopenharmony_ci# why - tell why a target got built 22562306a36Sopenharmony_ci# enabled by make V=2 22662306a36Sopenharmony_ci# Output (listed in the order they are checked): 22762306a36Sopenharmony_ci# (1) - due to target is PHONY 22862306a36Sopenharmony_ci# (2) - due to target missing 22962306a36Sopenharmony_ci# (3) - due to: file1.h file2.h 23062306a36Sopenharmony_ci# (4) - due to command line change 23162306a36Sopenharmony_ci# (5) - due to missing .cmd file 23262306a36Sopenharmony_ci# (6) - due to target not in $(targets) 23362306a36Sopenharmony_ci# (1) PHONY targets are always build 23462306a36Sopenharmony_ci# (2) No target, so we better build it 23562306a36Sopenharmony_ci# (3) Prerequisite is newer than target 23662306a36Sopenharmony_ci# (4) The command line stored in the file named dir/.target.cmd 23762306a36Sopenharmony_ci# differed from actual command line. This happens when compiler 23862306a36Sopenharmony_ci# options changes 23962306a36Sopenharmony_ci# (5) No dir/.target.cmd file (used to store command line) 24062306a36Sopenharmony_ci# (6) No dir/.target.cmd file and target not listed in $(targets) 24162306a36Sopenharmony_ci# This is a good hint that there is a bug in the kbuild file 24262306a36Sopenharmony_ciifneq ($(findstring 2, $(KBUILD_VERBOSE)),) 24362306a36Sopenharmony_ci_why = \ 24462306a36Sopenharmony_ci $(if $(filter $@, $(PHONY)),- due to target is PHONY, \ 24562306a36Sopenharmony_ci $(if $(wildcard $@), \ 24662306a36Sopenharmony_ci $(if $(newer-prereqs),- due to: $(newer-prereqs), \ 24762306a36Sopenharmony_ci $(if $(cmd-check), \ 24862306a36Sopenharmony_ci $(if $(savedcmd_$@),- due to command line change, \ 24962306a36Sopenharmony_ci $(if $(filter $@, $(targets)), \ 25062306a36Sopenharmony_ci - due to missing .cmd file, \ 25162306a36Sopenharmony_ci - due to $(notdir $@) not in $$(targets) \ 25262306a36Sopenharmony_ci ) \ 25362306a36Sopenharmony_ci ) \ 25462306a36Sopenharmony_ci ) \ 25562306a36Sopenharmony_ci ), \ 25662306a36Sopenharmony_ci - due to target missing \ 25762306a36Sopenharmony_ci ) \ 25862306a36Sopenharmony_ci ) 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ciwhy = $(space)$(strip $(_why)) 26162306a36Sopenharmony_ciendif 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci############################################################################### 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci# delete partially updated (i.e. corrupted) files on error 26662306a36Sopenharmony_ci.DELETE_ON_ERROR: 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci# do not delete intermediate files automatically 26962306a36Sopenharmony_ci# 27062306a36Sopenharmony_ci# .NOTINTERMEDIATE is more correct, but only available on newer Make versions. 27162306a36Sopenharmony_ci# Make 4.4 introduced .NOTINTERMEDIATE, and it appears in .FEATURES, but the 27262306a36Sopenharmony_ci# global .NOTINTERMEDIATE does not work. We can use it on Make > 4.4. 27362306a36Sopenharmony_ci# Use .SECONDARY for older Make versions, but "newer-prereq" cannot detect 27462306a36Sopenharmony_ci# deleted files. 27562306a36Sopenharmony_ciifneq ($(and $(filter notintermediate, $(.FEATURES)),$(filter-out 4.4,$(MAKE_VERSION))),) 27662306a36Sopenharmony_ci.NOTINTERMEDIATE: 27762306a36Sopenharmony_cielse 27862306a36Sopenharmony_ci.SECONDARY: 27962306a36Sopenharmony_ciendif 280