1# Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13cur_makefile := $(lastword $(MAKEFILE_LIST)) 14 15# ========================================================================== 16# Building 17# ========================================================================== 18 19src := $(obj) 20 21PHONY := __build 22__build: 23 24$(cur_makefile): ; 25 26# Init all relevant variables used in kbuild files so 27# 1) they have correct type 28# 2) they do not inherit any value from the environment 29obj-y := 30lib-y := 31subdir-y := 32archive-custom := 33archive-custom-valid := 34always := 35targets := 36EXTRA_AFLAGS := 37EXTRA_CFLAGS := 38EXTRA_CPPFLAGS := 39EXTRA_LDFLAGS := 40asflags-y := 41ccflags-y := 42cppflags-y := 43ldflags-y := 44 45subdir-asflags-y := 46subdir-ccflags-y := 47 48include scripts/include.mk 49 50# For backward compatibility check that these variables do not change 51save-cflags := $(CFLAGS) 52 53kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) 54kbuild-file := $(kbuild-dir)/Makefile 55include $(kbuild-file) 56 57$(kbuild-file): ; 58 59# If the save-* variables changed error out 60ifeq ($(KBUILD_NOPEDANTIC),) 61 ifneq ("$(save-cflags)","$(CFLAGS)") 62 $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y) 63 endif 64endif 65 66include scripts/lib.mk 67 68ifeq ($(WIN_PLAT),y) 69create_dir = if not exist $(subst /,\,$(1)) mkdir $(subst /,\,$(1)) 70else 71create_dir = [ -d $(1) ] || mkdir -p $(1) 72endif 73 74ifneq ($(KBUILD_SRC),) 75# Create output directory if not already present 76_dummy := $(shell $(call create_dir,$(obj))) 77 78# Create directories for object files if directory does not exist 79# Needed when obj-y := dir/file.o syntax is used 80_dummy := $(foreach d,$(obj-dirs), $(shell $(call create_dir,$(d)))) 81endif 82 83ifndef obj 84$(warning kbuild: build.mk is included improperly) 85endif 86 87# =========================================================================== 88 89ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) 90lib-target := $(obj)/lib.a 91endif 92 93ifneq ($(strip $(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),) 94builtin-target := $(obj)/built-in$(built_in_suffix) 95endif 96 97submodgoals = 98SUBMODS := $(filter $(obj)/%,$(SUBMODS)) 99 100ifneq ($(SUBMODS),) 101 102lst_target := $(filter %.s %.i %.lst, $(SUBMODS)) 103ifeq ($(lib-target),) 104ifneq ($(filter $(obj)/lib.lst,$(lst_target)),) 105$(error Cannot make lib.lst: lib-target not exists) 106endif 107endif 108ifeq ($(builtin-target),) 109ifneq ($(filter $(obj)/built-in.lst,$(lst_target)),) 110$(error Cannot make built-in.lst: builtin-target not exists) 111endif 112endif 113 114lst_target_obj := $(lst_target) 115lst_target_obj := $(filter-out $(obj)/built-in.lst $(obj)/lib.lst,$(lst_target_obj)) 116lst_target_obj := $(lst_target_obj:.s=.o) 117lst_target_obj := $(lst_target_obj:.i=.o) 118lst_target_obj := $(lst_target_obj:.lst=.o) 119lst_target_obj := $(sort $(lst_target_obj)) 120 121cur_submods := $(filter-out $(lst_target),$(SUBMODS)) 122cur_submods += $(lst_target_obj) 123 124include scripts/submods.mk 125 126buildextra-y := $(filter $(cur_submods),$(extra-y)) 127 128ifeq ($(filter $(obj)/built-in.lst,$(lst_target)),) 129 130# Just compile some of the object files 131buildsubdir-y := $(call get_subdirs,$(subdir-y),$(cur_submods)) 132buildobj-y := $(filter $(cur_submods) $(addsuffix /built-in$(built_in_suffix),$(buildsubdir-y)),$(obj-y)) 133buildobj-y += $(foreach m,$(multi-used-y),$(if $(filter $(cur_submods),$(call get_multi_objs,$m)),$m,)) 134 135else 136 137# Compile all the object files 138buildsubdir-y := $(subdir-y) 139buildobj-y := $(obj-y) 140 141endif 142 143ifeq ($(filter $(obj)/lib.lst,$(lst_target)),) 144# Just compile some of the lib files 145buildlib-y := $(filter $(cur_submods),$(lib-y)) 146else 147# Compile all the lib files 148buildlib-y := $(lib-y) 149endif 150 151# Check for invalid targets 152errobj-y := $(cur_submods) 153errobj-y := $(filter-out $(buildsubdir-y) $(addsuffix /%,$(buildsubdir-y)),$(errobj-y)) 154errobj-y := $(filter-out $(buildextra-y) $(buildobj-y) $(buildlib-y),$(errobj-y)) 155errobj-y := $(filter-out $(foreach m,$(multi-used-y),$(call get_multi_objs,$m)),$(errobj-y)) 156ifneq ($(errobj-y),) 157$(warning Unknown targets in [$(obj)]: $(errobj-y)) 158endif 159 160# Update lst targets 161all_buildobj-y := $(buildextra-y) $(buildobj-y) $(filter-out %.a,$(builtin-target)) 162all_buildlib-y := $(filter %.a,$(builtin-target)) $(lib-target) 163lst_target := $(filter $(lst_target), \ 164 $(all_buildobj-y:.o=.s) \ 165 $(all_buildobj-y:.o=.i) \ 166 $(all_buildobj-y:.o=.lst) \ 167 $(patsubst %.a,%.lst,$(all_buildlib-y))) 168 169# Avoid .o compile error affecting .i generation 170lst_i_target := $(filter %.i, $(lst_target)) 171ifneq ($(lst_i_target),) 172$(lst_i_target:.i=.o) : | $(lst_i_target) 173endif 174 175ifeq ($(COMPILE_ONLY),1) 176submodgoals = $(call get_submodgoals,$@,$(SUBMODS)) 177endif 178 179else # SUBMODS 180 181buildsubdir-y := $(subdir-y) 182buildextra-y := $(extra-y) 183buildobj-y := $(obj-y) 184buildlib-y := $(lib-y) 185 186buildobj-y := $(if $(filter-obj),$(filter-out $(filter-obj),$(buildobj-y)),$(buildobj-y)) 187endif # SUBMODS 188 189ifeq ($(LIB_BIN_IN_SRC_DIR),1) 190archive-bin-path := $(srctree)/$(src)/lib 191else ifeq ($(LIB_BIN_IN_TOP_WITH_SRC_DIR),1) 192archive-bin-path := $(srctree)/lib/$(src) 193else 194LIB_BIN_DIR ?= $(BES_LIB_DIR) 195archive-bin-path := $(srctree)/$(LIB_BIN_DIR) 196endif 197 198archive-src-target := 199archive-custom-target := 200ifeq ($(GEN_LIB),1) 201archive-src-target := $(archive-src-y:$(obj)/%=$(archive-bin-path)/%) 202archive-src-target += $(archive-custom-valid) 203archive-src-target := $(strip $(archive-src-target)) 204archive-custom-target := $(archive-custom-valid:$(obj)/%=$(archive-bin-path)/%) 205endif 206 207__build: $(builtin-target) $(lib-target) $(buildextra-y) $(buildsubdir-y) $(lst_target) $(archive-src-target) $(archive-custom-target) $(always) 208 @: 209 210# Compile C sources (.c) 211# --------------------------------------------------------------------------- 212 213# Default is built-in, unless we know otherwise 214quiet_modtag := $(empty) $(empty) 215 216quiet_cmd_cc_dummy = CC $(quiet_modtag) $@ 217cmd_cc_dummy = $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -c -x c -o $@ $(devnull) 218 219# For dummy object files. Recipe is: $(call if_changed,cc_dummy) 220 221quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ 222cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< 223 224$(obj)/%.s: $(src)/%.c FORCE 225 $(call if_changed_dep,cc_s_c) 226 227quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@ 228cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $< 229 230$(obj)/%.i: $(src)/%.c FORCE 231 $(call if_changed_dep,cc_i_c) 232 233# C (.c) files 234# The C file is compiled and updated dependency information is generated. 235# (See cmd_cc_o_c + relevant part of rule_cc_o_c) 236 237quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ 238cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< 239 240define rule_cc_o_c 241 $(call echo-cmd,cc_o_c) $(cmd_cc_o_c) 242endef 243 244# Built-in and composite module parts 245$(obj)/%.o: $(src)/%.c FORCE 246 $(call if_changed_rule,cc_o_c) 247 248# Compile C++ sources (.cpp) 249# --------------------------------------------------------------------------- 250 251quiet_cmd_cc_s_c++ = C++ $(quiet_modtag) $@ 252cmd_cc_s_c++ = $(CC) $(c++_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< 253 254$(obj)/%.s: $(src)/%.cpp FORCE 255 $(call if_changed_dep,cc_s_c++) 256 257$(obj)/%.s: $(src)/%.cc FORCE 258 $(call if_changed_dep,cc_s_c++) 259 260quiet_cmd_cc_i_c++ = CPP $(quiet_modtag) $@ 261cmd_cc_i_c++ = $(CPP) $(c++_flags) -o $@ $< 262 263$(obj)/%.i: $(src)/%.cpp FORCE 264 $(call if_changed_dep,cc_i_c++) 265 266$(obj)/%.i: $(src)/%.cc FORCE 267 $(call if_changed_dep,cc_i_c++) 268 269# C++ (.cpp) files 270# The C++ file is compiled and updated dependency information is generated. 271# (See cmd_cc_o_c++ + relevant part of rule_cc_o_c) 272 273quiet_cmd_cc_o_c++ = C++ $(quiet_modtag) $@ 274cmd_cc_o_c++ = $(C++) $(c++_flags) -c -o $@ $< 275 276define rule_cc_o_c++ 277 $(call echo-cmd,cc_o_c++) $(cmd_cc_o_c++) 278endef 279 280# Built-in and composite module parts 281$(obj)/%.o: $(src)/%.cpp FORCE 282 $(call if_changed_rule,cc_o_c++) 283 284$(obj)/%.o: $(src)/%.cc FORCE 285 $(call if_changed_rule,cc_o_c++) 286 287# Compile assembler sources (.S) 288# --------------------------------------------------------------------------- 289 290quiet_cmd_as_s_S = CPP $(quiet_modtag) $@ 291cmd_as_s_S = $(CPP) $(a_cpp_flags) -o $@ $< 292 293$(obj)/%.s: $(src)/%.S FORCE 294 $(call if_changed_dep,as_s_S) 295 296quiet_cmd_as_o_S = AS $(quiet_modtag) $@ 297cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< 298 299$(obj)/%.o: $(src)/%.S FORCE 300 $(call if_changed_dep,as_o_S) 301 302targets += $(real-objs-y) $(real-objs-m) $(lib-y) $(lst_target) 303targets += $(MAKECMDGOALS) $(always) 304 305# Common list command 306# --------------------------------------------------------------------------- 307 308quiet_cmd_dump_lst_o = MKLST $@ 309ifeq ($(TOOLCHAIN),armclang) 310 cmd_dump_lst_o = $(OBJDUMP) --datasymbols --text -c -d --interleave=source --output=$@ $< 311else 312 cmd_dump_lst_o = $(OBJDUMP) -Sdlxr $< > $@ 313endif 314 315lst-cmd = @$(call echo-cmd,dump_lst_o) $(cmd_dump_lst_o) 316 317$(obj)/%.lst: $(obj)/%.o 318 $(call lst-cmd) 319 320# Build the compiled-in targets 321# --------------------------------------------------------------------------- 322 323# To build objects in subdirs, we need to descend into the directories 324$(sort $(subdir-obj-y)): $(buildsubdir-y) ; 325 326# Archive check 327 328ifeq ($(CHECK_LIB_SRC),1) 329ifneq ($(archive-bin-y),) 330$(info ) 331$(info Library source check OK: $(archive-bin-y)) 332$(info ) 333endif 334 335ifneq ($(archive-src-y),) 336$(info ) 337$(foreach m, $(archive-src-y), \ 338 $(eval $(info $(m) :) \ 339 $(eval tmp_list=$(call get-archive-src,$(patsubst $(obj)/%,%,$(m)))) \ 340 $(eval $(foreach k, $(tmp_list), $(info $(empty) $(k)))))) 341$(info ) 342$(error Error: The source files exist for libraries: $(archive-src-y)) 343endif 344endif 345 346# Archive without source files 347 348 cmd_use_lib_file = $(call CMDCPFILE,$<,$@) 349quiet_cmd_use_lib_file = USELIB $(@) 350 351ifneq ($(archive-bin-y),) 352 353ifeq ($(GEN_LIB),1) 354$(info ) 355$(warning WARNING: No source files found for libraries: $(archive-bin-y)) 356$(info ) 357endif 358 359$(archive-bin-y): $(obj)/%: $(archive-bin-path)/% FORCE 360ifeq ($(FORCE_TO_USE_LIB),1) 361 $(call cmd,use_lib_file) 362else 363 $(call if_changed,use_lib_file) 364endif 365 366targets += $(archive-bin-y) 367 368endif # archive-bin-y 369 370# Archive generation (with source files) 371 372ifeq ($(GEN_LIB),1) 373ifeq ($(FORCE_TO_USE_LIB),1) 374$(error Conflicted options: GEN_LIB and FORCE_TO_USE_LIB) 375endif 376ifneq ($(archive-src-target),) 377 378 cmd_gen_lib_file = ( $(call create_dir,$(dir $(@))) ) && $(call archive-cmd,$(filter-out $(PHONY),$^)) 379quiet_cmd_gen_lib_file = GENLIB $(@) 380 381define archive-src-target-rule 382$(1): $(addprefix $(obj)/,$(patsubst %/,%/$(notdir $(builtin-target)),$($(notdir $(1:.a=-y))))) 383endef 384 385$(foreach m, $(archive-src-target), $(eval $(call archive-src-target-rule,$(m)))) 386 387$(archive-src-target): FORCE 388ifeq ($(CHECK_GEN_LIB_DEP),1) 389 $(call if_changed,gen_lib_file) 390else 391# Always pack lib 392 $(call cmd,gen_lib_file) 393endif 394 395targets += $(archive-src-target) 396 397endif # archive-src-y 398endif # GEN_LIB 399 400# 401# Rule to compile a set of .o files into one .o/.a built-in file 402# 403ifdef builtin-target 404 405ifeq ($(BUILT-IN-OBJ),1) 406 407quiet_cmd_link_o_target = LD $@ 408# If the list of objects to link is empty, just create an empty built-in.o 409ifeq ($(TOOLCHAIN),armclang) 410 cmd_link_o_target = $(if $(strip $(obj-y)),\ 411 $(LD) -Wl$(comma)$(subst $(space),$(comma),$(strip $(ld_flags) --partial)) -nostdlib $(LINK_CFLAGS) -o $@ $(obj-y), \ 412 $(call CMDRMFILE,$@) && $(AR) --create --debug_symbols $@) 413else 414 cmd_link_o_target = $(if $(strip $(obj-y)),\ 415 $(LD) -Wl$(comma)$(subst $(space),$(comma),$(strip $(ld_flags) -r)) -nostdlib -nostartfiles $(LINK_CFLAGS) -o $@ $(obj-y), \ 416 $(call CMDRMFILE,$@) && $(AR) rcs$(KBUILD_ARFLAGS) $@) 417endif 418 419$(builtin-target): $(buildobj-y) FORCE 420 $(call if_changed,link_o_target) 421 422else # BUILT-IN-OBJ 423 424quiet_cmd_ar_o_target = AR $@ 425cmd_ar_o_target = $(call archive-cmd,$(obj-y)) 426 427$(builtin-target): $(buildobj-y) FORCE 428 $(call if_changed,ar_o_target) 429 430endif # BUILT-IN-OBJ 431 432targets += $(builtin-target) 433 434$(obj)/built-in.lst: $(builtin-target) 435 $(call lst-cmd) 436 437endif # builtin-target 438 439# 440# Rule to compile a set of .o files into one .a file 441# 442ifdef lib-target 443 444quiet_cmd_link_l_target = AR $@ 445ifeq ($(TOOLCHAIN),armclang) 446 cmd_link_l_target = $(call CMDRMFILE,$@) && $(AR) --create --debug_symbols $@ $(lib-y) 447else 448 cmd_link_l_target = $(call CMDRMFILE,$@) && $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y) 449endif 450 451$(lib-target): $(buildlib-y) FORCE 452 $(call if_changed,link_l_target) 453 454targets += $(lib-target) 455 456$(obj)/lib.lst: $(lib-target) 457 $(call lst-cmd) 458 459endif 460 461# 462# Rule to link composite objects 463# 464# Composite objects are specified in kbuild makefile as follows: 465# <composite-object>-objs := <list of .o files> 466# or 467# <composite-object>-y := <list of .o files> 468link_multi_deps = \ 469$(filter $(addprefix $(obj)/, \ 470$($(subst $(obj)/,,$(@:.o=-objs))) \ 471$($(subst $(obj)/,,$(@:.o=-y)))), $^) 472 473quiet_cmd_link_multi-y = LD $@ 474ifeq ($(TOOLCHAIN),armclang) 475 cmd_link_multi-y = $(LD) -Wl,$(subst $(space),$(comma),$(strip $(ld_flags) --partial)) -nostdlib $(LINK_CFLAGS) -o $@ $(link_multi_deps) 476else 477 cmd_link_multi-y = $(LD) -Wl,$(subst $(space),$(comma),$(strip $(ld_flags) -r --whole-archive)) -nostdlib -nostartfiles $(LINK_CFLAGS) -o $@ $(link_multi_deps) 478endif 479 480$(multi-used-y): FORCE 481 $(call if_changed,link_multi-y) 482$(call multi_depend, $(multi-used-y), .o, -objs -y) 483 484targets += $(multi-used-y) 485 486$(multi-used-y:.o=.lst): %.lst : %.o 487 $(call lst-cmd) 488 489# Descending 490# --------------------------------------------------------------------------- 491 492PHONY += $(subdir-y) 493 494$(subdir-y): 495 $(Q)$(MAKE) $(build)=$@ $(submodgoals) 496 497# Add FORCE to the prequisites of a target to force it to be always rebuilt. 498# --------------------------------------------------------------------------- 499 500PHONY += FORCE 501 502FORCE: 503 504# Read all saved command lines and dependencies for the $(targets) we 505# may be building above, using $(if_changed{,_dep}). As an 506# optimization, we don't need to read them if the target does not 507# exist, we will rebuild anyway in that case. 508 509targets := $(wildcard $(sort $(targets))) 510cmd_files := $(wildcard $(foreach f,$(targets),$(call get_depfile_name,$(f)))) 511 512ifneq ($(cmd_files),) 513include $(cmd_files) 514$(cmd_files): ; 515endif 516 517# Declare the contents of the .PHONY variable as phony. We keep that 518# information in a variable se we can use it in if_changed and friends. 519 520.PHONY: $(PHONY) 521 522# Last-resort default rule for unknown targets 523 524%:: 525 @$(call echo-help,*** Error: No rule is defined for target: $@) 526 @exit 1 527 528