1# Input 2# 3# The output from mk/sub.mk 4# base-prefix 5# conf-file [optional] if set, all objects will depend on $(conf-file) 6# additional-compile-deps [optional] additional dependencies 7# 8# Output 9# 10# set objs 11# update cleanfiles 12# 13# Generates explicit rules for all objs 14 15objs := 16 17# Disable all builtin rules 18.SUFFIXES: 19 20__cc-option = $(if $(shell $(CC$(sm)) $(1) -c -x c /dev/null -o /dev/null 2>&1 >/dev/null),$(2),$(1)) 21_cc-opt-cached-var-name = cached-cc-option$(subst =,~,$(strip $(1)))$(subst $(empty) $(empty),,$(CC$(sm))) 22define _cc-option 23$(eval _cached := $(call _cc-opt-cached-var-name,$1)) 24$(eval $(_cached) := $(if $(filter $(origin $(_cached)),undefined),$(call __cc-option,$(1),$(2)),$($(_cached)))) 25$($(_cached)) 26endef 27cc-option = $(strip $(call _cc-option,$(1),$(2))) 28 29comp-cflags$(sm) = -std=gnu99 30comp-aflags$(sm) = 31comp-cppflags$(sm) = 32 33ifeq ($(CFG_WERROR),y) 34comp-cflags$(sm) += -Werror 35endif 36comp-cflags$(sm) += -fdiagnostics-show-option 37 38comp-cflags-warns-high = \ 39 -Wall -Wcast-align \ 40 -Werror-implicit-function-declaration -Wextra -Wfloat-equal \ 41 -Wformat-nonliteral -Wformat-security -Wformat=2 -Winit-self \ 42 -Wmissing-declarations -Wmissing-format-attribute \ 43 -Wmissing-include-dirs -Wmissing-noreturn \ 44 -Wmissing-prototypes -Wnested-externs -Wpointer-arith \ 45 -Wshadow -Wstrict-prototypes -Wswitch-default \ 46 -Wwrite-strings \ 47 -Wno-missing-field-initializers -Wno-format-zero-length 48comp-cflags-warns-medium = \ 49 -Waggregate-return -Wredundant-decls 50comp-cflags-warns-low = \ 51 -Wold-style-definition -Wstrict-aliasing=2 \ 52 -Wundef 53 54comp-cflags-warns-1:= $(comp-cflags-warns-high) 55comp-cflags-warns-2:= $(comp-cflags-warns-1) $(comp-cflags-warns-medium) 56comp-cflags-warns-3:= $(comp-cflags-warns-2) $(comp-cflags-warns-low) 57 58WARNS ?= 3 59 60comp-cflags$(sm) += $(comp-cflags-warns-$(WARNS)) \ 61 $(comp-cflags-warns-$(COMPILER_$(sm))) 62 63CHECK ?= sparse 64 65.PHONY: FORCE 66.PHONY: FORCE-GENSRC$(sm) 67FORCE: 68FORCE-GENSRC$(sm): 69 70 71define process_srcs 72objs += $2 73comp-dep-$2 := $$(dir $2).$$(notdir $2).d 74comp-cmd-file-$2:= $$(dir $2).$$(notdir $2).cmd 75comp-sm-$2 := $(sm) 76comp-lib-$2 := $(libname)-$(sm) 77 78cleanfiles := $$(cleanfiles) $$(comp-dep-$2) $$(comp-cmd-file-$2) $2 79 80ifeq ($$(filter %.c,$1),$1) 81comp-q-$2 := CC 82comp-flags-$2 = $$(filter-out $$(CFLAGS_REMOVE) $$(cflags-remove) \ 83 $$(cflags-remove-$$(comp-sm-$2)) \ 84 $$(cflags-remove-$2), \ 85 $$(CFLAGS$$(arch-bits-$$(comp-sm-$2))) $$(CFLAGS_WARNS) \ 86 $$(comp-cflags$$(comp-sm-$2)) $$(cflags$$(comp-sm-$2)) \ 87 $$(cflags-lib$$(comp-lib-$2)) $$(cflags-$2)) 88ifeq ($C,1) 89check-cmd-$2 = $(CHECK) $$(comp-cppflags-$2) $$< 90echo-check-$2 := $(cmd-echo-silent) 91echo-check-cmd-$2 = $(cmd-echo) $$(subst \",\\\",$$(check-cmd-$2)) 92endif 93 94else ifeq ($$(filter %.S,$1),$1) 95comp-q-$2 := AS 96comp-flags-$2 = $$(filter-out $$(AFLAGS_REMOVE) $$(aflags-remove) \ 97 $$(aflags-remove-$$(comp-sm-$2)) \ 98 $$(aflags-remove-$2), \ 99 $$(AFLAGS) $$(comp-aflags$$(comp-sm-$2)) \ 100 $$(aflags$$(comp-sm-$2)) $$(aflags-$2)) 101 102else 103$$(error "Don't know what to do with $1") 104endif 105 106comp-cppflags-$2 = $$(filter-out $$(CPPFLAGS_REMOVE) $$(cppflags-remove) \ 107 $$(cppflags-remove-$$(comp-sm-$2)) \ 108 $$(cppflags-remove-$2), \ 109 $$(nostdinc$$(comp-sm-$2)) $$(CPPFLAGS) \ 110 $$(addprefix -I,$$(incdirs$$(comp-sm-$2))) \ 111 $$(addprefix -I,$$(incdirs-lib$$(comp-lib-$2))) \ 112 $$(addprefix -I,$$(incdirs-$2)) \ 113 $$(cppflags$$(comp-sm-$2)) \ 114 $$(cppflags-lib$$(comp-lib-$2)) $$(cppflags-$2)) \ 115 -D__FILE_ID__=$$(subst -,_,$$(subst /,_,$$(subst .,_,$1))) 116 117comp-flags-$2 += -MD -MF $$(comp-dep-$2) -MT $$@ 118comp-flags-$2 += $$(comp-cppflags-$2) 119 120comp-cmd-$2 = $$(CC$(sm)) $$(comp-flags-$2) -c $$< -o $$@ 121comp-objcpy-cmd-$2 = $$(OBJCOPY$(sm)) \ 122 --rename-section .rodata=.rodata.$1 \ 123 --rename-section .rodata.str1.1=.rodata.str1.1.$1 \ 124 $2 125 126# Assign defaults if unassigned 127echo-check-$2 ?= true 128echo-check-cmd-$2 ?= true 129check-cmd-$2 ?= true 130 131-include $$(comp-cmd-file-$2) 132-include $$(comp-dep-$2) 133 134 135$2: $1 FORCE-GENSRC$(sm) 136# Check if any prerequisites are newer than the target and 137# check if command line has changed 138 $$(if $$(strip $$(filter-out FORCE-GENSRC$(sm), $$?) \ 139 $$(filter-out $$(comp-cmd-$2), $$(old-cmd-$2)) \ 140 $$(filter-out $$(old-cmd-$2), $$(comp-cmd-$2))), \ 141 @set -e ;\ 142 mkdir -p $$(dir $2) ;\ 143 $$(echo-check-$2) ' CHECK $$<' ;\ 144 $$(echo-check-cmd-$2) ;\ 145 $$(check-cmd-$2) ;\ 146 $(cmd-echo-silent) ' $$(comp-q-$2) $$@' ;\ 147 $(cmd-echo) $$(subst \",\\\",$$(comp-cmd-$2)) ;\ 148 $$(comp-cmd-$2) ;\ 149 $(cmd-echo) $$(comp-objcpy-cmd-$2) ;\ 150 $$(comp-objcpy-cmd-$2) ;\ 151 echo "old-cmd-$2 := $$(subst \",\\\",$$(comp-cmd-$2))" > \ 152 $$(comp-cmd-file-$2) ;\ 153 ) 154 155endef 156 157$(foreach f, $(srcs), $(eval $(call \ 158 process_srcs,$(f),$(out-dir)/$(base-prefix)$$(basename $f).o))) 159 160# Handle generated source files, that is, files that are compiled from out-dir 161$(foreach f, $(gen-srcs), $(eval $(call process_srcs,$(f),$$(basename $f).o))) 162 163# Handle specified source files, that is, files that have a specified path 164# but where the object file should go into a specified out directory 165$(foreach f, $(spec-srcs), $(eval $(call \ 166 process_srcs,$(f),$(spec-out-dir)/$$(notdir $$(basename $f)).o))) 167 168$(objs): $(conf-file) $(additional-compile-deps) 169 170define _gen-asm-defines-file 171# c-filename in $1 172# h-filename in $2 173# s-filename in $3 174 175FORCE-GENSRC$(sm): $(2) 176 177comp-dep-$3 := $$(dir $3)$$(notdir $3).d 178comp-cmd-file-$3:= $$(dir $3)$$(notdir $3).cmd 179comp-sm-$3 := $(sm) 180 181cleanfiles := $$(cleanfiles) $$(comp-dep-$3) $$(comp-cmd-file-$3) $3 $2 182 183comp-flags-$3 = $$(filter-out $$(CFLAGS_REMOVE) $$(cflags-remove) \ 184 $$(cflags-remove-$$(comp-sm-$3)) \ 185 $$(cflags-remove-$3), \ 186 $$(CFLAGS) $$(CFLAGS_WARNS) \ 187 $$(comp-cflags$$(comp-sm-$3)) $$(cflags$$(comp-sm-$3)) \ 188 $$(cflags-lib$$(comp-lib-$3)) $$(cflags-$3)) 189 190comp-cppflags-$3 = $$(filter-out $$(CPPFLAGS_REMOVE) $$(cppflags-remove) \ 191 $$(cppflags-remove-$$(comp-sm-$3)) \ 192 $$(cppflags-remove-$3), \ 193 $$(nostdinc$$(comp-sm-$3)) $$(CPPFLAGS) \ 194 $$(addprefix -I,$$(incdirs$$(comp-sm-$3))) \ 195 $$(addprefix -I,$$(incdirs-lib$$(comp-lib-$3))) \ 196 $$(addprefix -I,$$(incdirs-$3)) \ 197 $$(cppflags$$(comp-sm-$3)) \ 198 $$(cppflags-lib$$(comp-lib-$3)) $$(cppflags-$3)) 199 200comp-flags-$3 += -MD -MF $$(comp-dep-$3) -MT $$@ 201comp-flags-$3 += $$(comp-cppflags-$3) 202 203comp-cmd-$3 = $$(CC$(sm)) $$(comp-flags-$3) -fverbose-asm -S $$< -o $$@ 204 205 206-include $$(comp-cmd-file-$3) 207-include $$(comp-dep-$3) 208 209$3: $1 $(conf-file) FORCE 210# Check if any prerequisites are newer than the target and 211# check if command line has changed 212 $$(if $$(strip $$(filter-out FORCE, $$?) \ 213 $$(filter-out $$(comp-cmd-$3), $$(old-cmd-$3)) \ 214 $$(filter-out $$(old-cmd-$3), $$(comp-cmd-$3))), \ 215 @set -e ;\ 216 mkdir -p $$(dir $2) $$(dir $3) ;\ 217 $(cmd-echo-silent) ' CC $$@'; \ 218 $(cmd-echo) $$(subst \",\\\",$$(comp-cmd-$3)) ;\ 219 $$(comp-cmd-$3) ;\ 220 echo "old-cmd-$3 := $$(subst \",\\\",$$(comp-cmd-$3))" > \ 221 $$(comp-cmd-file-$3) ;\ 222 ) 223 224guard-$2 := $$(subst -,_,$$(subst .,_,$$(subst /,_,$2))) 225 226$(2): $(3) 227 $(q)set -e; \ 228 $(cmd-echo-silent) ' CHK $$@'; \ 229 mkdir -p $$(dir $$@); \ 230 echo "#ifndef $$(guard-$2)" >$$@.tmp; \ 231 echo "#define $$(guard-$2)" >>$$@.tmp; \ 232 sed -ne 's|^.*==>\([^ ]*\) [\$$$$#]*\([-0-9]*\) \([^@/]*\).*|#define \1\t\2\t/* \3*/|p' \ 233 < $$< >>$$@.tmp; \ 234 echo "#endif" >>$$@.tmp; \ 235 $$(call mv-if-changed,$$@.tmp,$$@) 236 237endef 238 239define gen-asm-defines-file 240$(call _gen-asm-defines-file,$1,$2,$(dir $2).$(notdir $(2:.h=.s))) 241endef 242 243$(foreach f,$(asm-defines-files),$(eval $(call gen-asm-defines-file,$(f),$(out-dir)/$(sm)/include/generated/$(basename $(notdir $(f))).h))) 244 245# Device tree source file compilation 246DTC := dtc 247DTC_FLAGS += -I dts -O dtb 248DTC_FLAGS += -Wno-unit_address_vs_reg 249 250define gen-dtb-file 251# dts file path/name in $1 252# dtb file path/name in $2 253 254dtb-basename-$2 := $$(basename $$(notdir $2)) 255dtb-predts-$2 := $$(dir $2)$$(dtb-basename-$2).pre.dts 256dtb-predep-$2 := $$(dir $2).$$(dtb-basename-$2).pre.dts.d 257dtb-dep-$2 := $$(dir $2).$$(notdir $2).d 258dtb-cmd-file-$2 := $$(dir $2).$$(notdir $2).cmd 259 260cleanfiles := $$(cleanfiles) $2 \ 261 $$(dtb-predts-$2) $$(dtb-predep-$2) \ 262 $$(dtb-dep-$2) $$(dtb-cmd-file-$2) 263 264dtb-cppflags-$2 := -Icore/include/ -x assembler-with-cpp \ 265 -E -ffreestanding $$(CPPFLAGS) \ 266 -MD -MF $$(dtb-predep-$2) -MT $2 267 268dtb-dtcflags-$2 := $$(DTC_FLAGS) -d $$(dtb-dep-$2) 269 270-include $$(dtb-dep-$2) 271-include $$(dtb-predep-$2) 272-include $$(dtb-cmd-file-$2) 273 274dtb-precmd-$2 = $$(CPP$(sm)) $$(dtb-cppflags-$2) -o $$(dtb-predts-$2) $$< 275dtb-cmd-$2 = $$(DTC) $$(dtb-dtcflags-$2) -o $$@ $$(dtb-predts-$2) 276 277$2: $1 FORCE 278# Check if any prerequisites are newer than the target and 279# check if command line has changed 280 $$(if $$(strip $$(filter-out FORCE, $$?) \ 281 $$(filter-out $$(dtb-precmd-$2), $$(dtb-old-precmd-$2)) \ 282 $$(filter-out $$(dtb-old-precmd-$2), $$(dtb-precmd-$2)) \ 283 $$(filter-out $$(dtb-cmd-$2), $$(dtb-old-cmd-$2)) \ 284 $$(filter-out $$(dtb-old-cmd-$2), $$(dtb-cmd-$2))), \ 285 @set -e; \ 286 mkdir -p $$(dir $2); \ 287 $(cmd-echo-silent) ' CPP $$(dtb-predts-$2)'; \ 288 $$(dtb-precmd-$2); \ 289 $(cmd-echo-silent) ' DTC $$@'; \ 290 $$(dtb-cmd-$2); \ 291 echo "dtb-old-precmd-$2 := $$(subst \",\\\",$$(dtb-precmd-$2))" > \ 292 $$(dtb-cmd-file-$2) ;\ 293 echo "dtb-old-cmd-$2 := $$(subst \",\\\",$$(dtb-cmd-$2))" >> \ 294 $$(dtb-cmd-file-$2) ;\ 295 ) 296 297endef 298 299additional-compile-deps := 300