| # SPDX-License-Identifier: GPL-2.0 |
| ### |
| # Main build makefile. |
| # |
| # Lots of this code have been borrowed or heavily inspired from parts |
| # of kbuild code, which is not credited, but mostly developed by: |
| # |
| # Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015 |
| # Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015 |
| # |
| |
| PHONY := __build |
| __build: |
| |
| ifeq ($(V),1) |
| quiet = |
| Q = |
| else |
| quiet=quiet_ |
| Q=@ |
| endif |
| |
| ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),) |
| quiet=silent_ |
| endif |
| |
| build-dir := $(srctree)/tools/build |
| |
| # Define $(fixdep) for dep-cmd function |
| ifeq ($(OUTPUT),) |
| fixdep := $(build-dir)/fixdep |
| else |
| fixdep := $(OUTPUT)/fixdep |
| endif |
| |
| # Generic definitions |
| include $(build-dir)/Build.include |
| |
| # do not force detected configuration |
| -include $(OUTPUT).config-detected |
| |
| # Init all relevant variables used in build files so |
| # 1) they have correct type |
| # 2) they do not inherit any value from the environment |
| subdir-y := |
| obj-y := |
| subdir-y := |
| subdir-obj-y := |
| |
| # Build definitions |
| build-file := $(dir)/Build |
| -include $(build-file) |
| |
| quiet_cmd_flex = FLEX $@ |
| quiet_cmd_bison = BISON $@ |
| quiet_cmd_test = TEST $@ |
| |
| # Create directory unless it exists |
| quiet_cmd_mkdir = MKDIR $(dir $@) |
| cmd_mkdir = mkdir -p $(dir $@) |
| rule_mkdir = $(if $(wildcard $(dir $@)),,@$(call echo-cmd,mkdir) $(cmd_mkdir)) |
| |
| # Compile command |
| quiet_cmd_cc_o_c = CC $@ |
| cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< |
| |
| quiet_cmd_host_cc_o_c = HOSTCC $@ |
| cmd_host_cc_o_c = $(HOSTCC) $(host_c_flags) -c -o $@ $< |
| |
| quiet_cmd_cxx_o_c = CXX $@ |
| cmd_cxx_o_c = $(CXX) $(cxx_flags) -c -o $@ $< |
| |
| quiet_cmd_cpp_i_c = CPP $@ |
| cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $< |
| |
| quiet_cmd_cc_s_c = AS $@ |
| cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< |
| |
| quiet_cmd_gen = GEN $@ |
| |
| # Link agregate command |
| # If there's nothing to link, create empty $@ object. |
| quiet_cmd_ld_multi = LD $@ |
| cmd_ld_multi = $(if $(strip $(obj-y)),\ |
| $(LD) -r -o $@ $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@) |
| |
| quiet_cmd_host_ld_multi = HOSTLD $@ |
| cmd_host_ld_multi = $(if $(strip $(obj-y)),\ |
| $(HOSTLD) -r -o $@ $(filter $(obj-y),$^),rm -f $@; $(HOSTAR) rcs $@) |
| |
| ifneq ($(filter $(obj),$(hostprogs)),) |
| host = host_ |
| endif |
| |
| # Build rules |
| $(OUTPUT)%.o: %.c FORCE |
| $(call rule_mkdir) |
| $(call if_changed_dep,$(host)cc_o_c) |
| |
| $(OUTPUT)%.o: %.cpp FORCE |
| $(call rule_mkdir) |
| $(call if_changed_dep,cxx_o_c) |
| |
| $(OUTPUT)%.o: %.S FORCE |
| $(call rule_mkdir) |
| $(call if_changed_dep,$(host)cc_o_c) |
| |
| $(OUTPUT)%.i: %.c FORCE |
| $(call rule_mkdir) |
| $(call if_changed_dep,cpp_i_c) |
| |
| $(OUTPUT)%.s: %.S FORCE |
| $(call rule_mkdir) |
| $(call if_changed_dep,cpp_i_c) |
| |
| $(OUTPUT)%.s: %.c FORCE |
| $(call rule_mkdir) |
| $(call if_changed_dep,cc_s_c) |
| |
| # Gather build data: |
| # obj-y - list of build objects |
| # subdir-y - list of directories to nest |
| # subdir-obj-y - list of directories objects 'dir/$(obj)-in.o' |
| obj-y := $($(obj)-y) |
| subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) |
| obj-y := $(patsubst %/, %/$(obj)-in.o, $(obj-y)) |
| subdir-obj-y := $(filter %/$(obj)-in.o, $(obj-y)) |
| |
| # '$(OUTPUT)/dir' prefix to all objects |
| objprefix := $(subst ./,,$(OUTPUT)$(dir)/) |
| obj-y := $(addprefix $(objprefix),$(obj-y)) |
| subdir-obj-y := $(addprefix $(objprefix),$(subdir-obj-y)) |
| |
| # Final '$(obj)-in.o' object |
| in-target := $(objprefix)$(obj)-in.o |
| |
| PHONY += $(subdir-y) |
| |
| $(subdir-y): |
| $(Q)$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj) |
| |
| $(sort $(subdir-obj-y)): $(subdir-y) ; |
| |
| $(in-target): $(obj-y) FORCE |
| $(call rule_mkdir) |
| $(call if_changed,$(host)ld_multi) |
| |
| __build: $(in-target) |
| @: |
| |
| PHONY += FORCE |
| FORCE: |
| |
| # Include all cmd files to get all the dependency rules |
| # for all objects included |
| targets := $(wildcard $(sort $(obj-y) $(in-target) $(MAKECMDGOALS))) |
| cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) |
| |
| ifneq ($(cmd_files),) |
| include $(cmd_files) |
| endif |
| |
| .PHONY: $(PHONY) |