|
|
|
@ -85,11 +85,8 @@ ifdef need-builtin
|
|
|
|
|
targets-for-builtin += $(obj)/built-in.a
|
|
|
|
|
endif |
|
|
|
|
|
|
|
|
|
targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m)))
|
|
|
|
|
|
|
|
|
|
ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) |
|
|
|
|
targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m)))
|
|
|
|
|
endif |
|
|
|
|
targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \
|
|
|
|
|
$(patsubst %.o, %.$x, $(filter %.o, $(obj-m))))
|
|
|
|
|
|
|
|
|
|
ifdef need-modorder |
|
|
|
|
targets-for-modules += $(obj)/modules.order
|
|
|
|
@ -125,18 +122,16 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $<
|
|
|
|
|
$(obj)/%.i: $(src)/%.c FORCE |
|
|
|
|
$(call if_changed_dep,cpp_i_c)
|
|
|
|
|
|
|
|
|
|
# These mirror gensymtypes_S and co below, keep them in synch.
|
|
|
|
|
cmd_gensymtypes_c = \
|
|
|
|
|
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
|
|
|
|
|
scripts/genksyms/genksyms $(if $(1), -T $(2)) \
|
|
|
|
|
$(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
|
|
|
|
|
genksyms = scripts/genksyms/genksyms \
|
|
|
|
|
$(if $(1), -T $(2)) \
|
|
|
|
|
$(if $(KBUILD_PRESERVE), -p) \
|
|
|
|
|
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
|
|
|
|
|
-r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null)
|
|
|
|
|
|
|
|
|
|
# These mirror gensymtypes_S and co below, keep them in synch.
|
|
|
|
|
cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms)
|
|
|
|
|
|
|
|
|
|
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
|
|
|
|
|
cmd_cc_symtypes_c = \
|
|
|
|
|
$(call cmd_gensymtypes_c,true,$@) >/dev/null; \
|
|
|
|
|
test -s $@ || rm -f $@
|
|
|
|
|
cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null
|
|
|
|
|
|
|
|
|
|
$(obj)/%.symtypes : $(src)/%.c FORCE |
|
|
|
|
$(call cmd,cc_symtypes_c)
|
|
|
|
@ -153,8 +148,18 @@ $(obj)/%.ll: $(src)/%.c FORCE
|
|
|
|
|
# The C file is compiled and updated dependency information is generated.
|
|
|
|
|
# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
|
|
|
|
|
|
|
|
|
|
is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y)
|
|
|
|
|
|
|
|
|
|
# When a module consists of a single object, there is no reason to keep LLVM IR.
|
|
|
|
|
# Make $(LD) covert LLVM IR to ELF here.
|
|
|
|
|
ifdef CONFIG_LTO_CLANG |
|
|
|
|
cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@)
|
|
|
|
|
endif |
|
|
|
|
|
|
|
|
|
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
|
|
|
|
|
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< $(cmd_objtool)
|
|
|
|
|
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \
|
|
|
|
|
$(cmd_ld_single_m) \
|
|
|
|
|
$(cmd_objtool)
|
|
|
|
|
|
|
|
|
|
ifdef CONFIG_MODVERSIONS |
|
|
|
|
# When module versioning is enabled the following steps are executed:
|
|
|
|
@ -162,35 +167,18 @@ ifdef CONFIG_MODVERSIONS
|
|
|
|
|
# o if <file>.o doesn't contain a __ksymtab version, i.e. does
|
|
|
|
|
# not export symbols, it's done.
|
|
|
|
|
# o otherwise, we calculate symbol versions using the good old
|
|
|
|
|
# genksyms on the preprocessed source and postprocess them in a way
|
|
|
|
|
# that they are usable as a linker script
|
|
|
|
|
# o generate .tmp_<file>.o from <file>.o using the linker to
|
|
|
|
|
# replace the unresolved symbols __crc_exported_symbol with
|
|
|
|
|
# the actual value of the checksum generated by genksyms
|
|
|
|
|
# o remove .tmp_<file>.o to <file>.o
|
|
|
|
|
# genksyms on the preprocessed source and dump them into the .cmd file.
|
|
|
|
|
# o modpost will extract versions from that file and create *.c files that will
|
|
|
|
|
# be compiled and linked to the kernel and/or modules.
|
|
|
|
|
|
|
|
|
|
ifdef CONFIG_LTO_CLANG |
|
|
|
|
# Generate .o.symversions files for each .o with exported symbols, and link these
|
|
|
|
|
# to the kernel and/or modules at the end.
|
|
|
|
|
cmd_modversions_c = \
|
|
|
|
|
gen_symversions = \
|
|
|
|
|
if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \
|
|
|
|
|
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
|
|
|
|
> $@.symversions; \
|
|
|
|
|
else \
|
|
|
|
|
rm -f $@.symversions; \
|
|
|
|
|
fi;
|
|
|
|
|
else |
|
|
|
|
cmd_modversions_c = \
|
|
|
|
|
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
|
|
|
|
|
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
|
|
|
|
> $(@D)/.tmp_$(@F:.o=.ver); \
|
|
|
|
|
\
|
|
|
|
|
$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
|
|
|
|
|
-T $(@D)/.tmp_$(@F:.o=.ver); \
|
|
|
|
|
mv -f $(@D)/.tmp_$(@F) $@; \
|
|
|
|
|
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
|
|
|
|
|
$(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
|
|
|
|
>> $(dot-target).cmd; \
|
|
|
|
|
fi
|
|
|
|
|
endif |
|
|
|
|
|
|
|
|
|
cmd_gen_symversions_c = $(call gen_symversions,c)
|
|
|
|
|
|
|
|
|
|
endif |
|
|
|
|
|
|
|
|
|
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT |
|
|
|
@ -222,65 +210,38 @@ cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)),
|
|
|
|
|
$(sub_cmd_record_mcount))
|
|
|
|
|
endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
|
|
|
|
|
|
|
|
|
|
ifdef CONFIG_STACK_VALIDATION |
|
|
|
|
|
|
|
|
|
objtool := $(objtree)/tools/objtool/objtool
|
|
|
|
|
|
|
|
|
|
objtool_args = \
|
|
|
|
|
$(if $(CONFIG_UNWINDER_ORC),orc generate,check) \
|
|
|
|
|
$(if $(part-of-module), --module) \
|
|
|
|
|
$(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \
|
|
|
|
|
$(if $(CONFIG_FRAME_POINTER),, --no-fp) \
|
|
|
|
|
$(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \
|
|
|
|
|
$(if $(CONFIG_RETPOLINE), --retpoline) \
|
|
|
|
|
$(if $(CONFIG_X86_SMAP), --uaccess) \
|
|
|
|
|
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \
|
|
|
|
|
$(if $(CONFIG_SLS), --sls)
|
|
|
|
|
|
|
|
|
|
cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@)
|
|
|
|
|
cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd)
|
|
|
|
|
|
|
|
|
|
endif # CONFIG_STACK_VALIDATION
|
|
|
|
|
|
|
|
|
|
ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) |
|
|
|
|
|
|
|
|
|
# Skip objtool for LLVM bitcode
|
|
|
|
|
$(obj)/%.o: objtool-enabled := |
|
|
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
|
|
# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
|
|
|
|
|
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
|
|
|
|
|
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
|
|
|
|
|
|
|
|
|
|
$(obj)/%.o: objtool-enabled = $(if $(filter-out y%, \
|
|
|
|
|
$(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y)
|
|
|
|
|
is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y)
|
|
|
|
|
|
|
|
|
|
endif |
|
|
|
|
$(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y)) |
|
|
|
|
|
|
|
|
|
ifdef CONFIG_TRIM_UNUSED_KSYMS |
|
|
|
|
cmd_gen_ksymdeps = \
|
|
|
|
|
$(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd
|
|
|
|
|
|
|
|
|
|
# List module undefined symbols
|
|
|
|
|
undefined_syms = $(NM) $< | $(AWK) '$$1 == "U" { printf("%s%s", x++ ? " " : "", $$2) }';
|
|
|
|
|
endif |
|
|
|
|
|
|
|
|
|
cmd_check_local_export = $(srctree)/scripts/check-local-export $@
|
|
|
|
|
|
|
|
|
|
define rule_cc_o_c |
|
|
|
|
$(call cmd_and_fixdep,cc_o_c)
|
|
|
|
|
$(call cmd,gen_ksymdeps)
|
|
|
|
|
$(call cmd,check_local_export)
|
|
|
|
|
$(call cmd,checksrc)
|
|
|
|
|
$(call cmd,checkdoc)
|
|
|
|
|
$(call cmd,gen_objtooldep)
|
|
|
|
|
$(call cmd,modversions_c)
|
|
|
|
|
$(call cmd,gen_symversions_c)
|
|
|
|
|
$(call cmd,record_mcount)
|
|
|
|
|
endef |
|
|
|
|
|
|
|
|
|
define rule_as_o_S |
|
|
|
|
$(call cmd_and_fixdep,as_o_S)
|
|
|
|
|
$(call cmd,gen_ksymdeps)
|
|
|
|
|
$(call cmd,check_local_export)
|
|
|
|
|
$(call cmd,gen_objtooldep)
|
|
|
|
|
$(call cmd,modversions_S)
|
|
|
|
|
$(call cmd,gen_symversions_S)
|
|
|
|
|
endef |
|
|
|
|
|
|
|
|
|
# Built-in and composite module parts
|
|
|
|
@ -288,33 +249,19 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
|
|
|
|
|
$(call if_changed_rule,cc_o_c)
|
|
|
|
|
$(call cmd,force_checksrc)
|
|
|
|
|
|
|
|
|
|
ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) |
|
|
|
|
# Module .o files may contain LLVM bitcode, compile them into native code
|
|
|
|
|
# before ELF processing
|
|
|
|
|
quiet_cmd_cc_prelink_modules = LD [M] $@
|
|
|
|
|
cmd_cc_prelink_modules = \
|
|
|
|
|
$(LD) $(ld_flags) -r -o $@ \
|
|
|
|
|
$(shell [ -s $(@:.prelink.o=.o.symversions) ] && \
|
|
|
|
|
echo -T $(@:.prelink.o=.o.symversions)) \
|
|
|
|
|
--whole-archive $(filter-out FORCE,$^) \
|
|
|
|
|
$(cmd_objtool)
|
|
|
|
|
|
|
|
|
|
# objtool was skipped for LLVM bitcode, run it now that we have compiled
|
|
|
|
|
# modules into native code
|
|
|
|
|
$(obj)/%.prelink.o: objtool-enabled = y |
|
|
|
|
$(obj)/%.prelink.o: part-of-module := y |
|
|
|
|
# To make this rule robust against "Argument list too long" error,
|
|
|
|
|
# ensure to add $(obj)/ prefix by a shell command.
|
|
|
|
|
cmd_mod = printf '%s\n' $(call real-search, $*.o, .o, -objs -y -m) | \
|
|
|
|
|
$(AWK) '!x[$$0]++ { print("$(obj)/"$$0) }' > $@
|
|
|
|
|
|
|
|
|
|
$(obj)/%.prelink.o: $(obj)/%.o FORCE |
|
|
|
|
$(call if_changed,cc_prelink_modules)
|
|
|
|
|
endif |
|
|
|
|
$(obj)/%.mod: FORCE |
|
|
|
|
$(call if_changed,mod)
|
|
|
|
|
|
|
|
|
|
cmd_mod = { \
|
|
|
|
|
echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \
|
|
|
|
|
$(undefined_syms) echo; \
|
|
|
|
|
} > $@
|
|
|
|
|
# List module undefined symbols
|
|
|
|
|
cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@
|
|
|
|
|
|
|
|
|
|
$(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE |
|
|
|
|
$(call if_changed,mod)
|
|
|
|
|
$(obj)/%.usyms: $(obj)/%.o FORCE |
|
|
|
|
$(call if_changed,undefined_syms)
|
|
|
|
|
|
|
|
|
|
quiet_cmd_cc_lst_c = MKLST $@
|
|
|
|
|
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
|
|
|
|
@ -344,16 +291,10 @@ cmd_gensymtypes_S = \
|
|
|
|
|
$(CPP) $(a_flags) $< | \
|
|
|
|
|
grep "\<___EXPORT_SYMBOL\>" | \
|
|
|
|
|
sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ; } | \
|
|
|
|
|
$(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \
|
|
|
|
|
scripts/genksyms/genksyms $(if $(1), -T $(2)) \
|
|
|
|
|
$(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
|
|
|
|
|
$(if $(KBUILD_PRESERVE),-p) \
|
|
|
|
|
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
|
|
|
|
|
$(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms)
|
|
|
|
|
|
|
|
|
|
quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@
|
|
|
|
|
cmd_cc_symtypes_S = \
|
|
|
|
|
$(call cmd_gensymtypes_S,true,$@) >/dev/null; \
|
|
|
|
|
test -s $@ || rm -f $@
|
|
|
|
|
cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null
|
|
|
|
|
|
|
|
|
|
$(obj)/%.symtypes : $(src)/%.S FORCE |
|
|
|
|
$(call cmd,cc_symtypes_S)
|
|
|
|
@ -373,16 +314,8 @@ ifdef CONFIG_ASM_MODVERSIONS
|
|
|
|
|
# versioning matches the C process described above, with difference that
|
|
|
|
|
# we parse asm-prototypes.h C header to get function definitions.
|
|
|
|
|
|
|
|
|
|
cmd_modversions_S = \
|
|
|
|
|
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
|
|
|
|
|
$(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
|
|
|
|
> $(@D)/.tmp_$(@F:.o=.ver); \
|
|
|
|
|
\
|
|
|
|
|
$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
|
|
|
|
|
-T $(@D)/.tmp_$(@F:.o=.ver); \
|
|
|
|
|
mv -f $(@D)/.tmp_$(@F) $@; \
|
|
|
|
|
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
|
|
|
|
|
fi
|
|
|
|
|
cmd_gen_symversions_S = $(call gen_symversions,S)
|
|
|
|
|
|
|
|
|
|
endif |
|
|
|
|
|
|
|
|
|
$(obj)/%.o: $(src)/%.S FORCE |
|
|
|
@ -417,29 +350,19 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
|
|
|
|
|
$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; |
|
|
|
|
$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; |
|
|
|
|
|
|
|
|
|
# combine symversions for later processing
|
|
|
|
|
ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y) |
|
|
|
|
cmd_update_lto_symversions = \
|
|
|
|
|
rm -f $@.symversions \
|
|
|
|
|
$(foreach n, $(filter-out FORCE,$^), \
|
|
|
|
|
$(if $(shell test -s $(n).symversions && echo y), \
|
|
|
|
|
; cat $(n).symversions >> $@.symversions))
|
|
|
|
|
else |
|
|
|
|
cmd_update_lto_symversions = echo >/dev/null
|
|
|
|
|
endif |
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Rule to compile a set of .o files into one .a file (without symbol table)
|
|
|
|
|
#
|
|
|
|
|
# To make this rule robust against "Argument list too long" error,
|
|
|
|
|
# remove $(obj)/ prefix, and restore it by a shell command.
|
|
|
|
|
|
|
|
|
|
quiet_cmd_ar_builtin = AR $@
|
|
|
|
|
cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
|
|
|
|
|
|
|
|
|
|
quiet_cmd_ar_and_symver = AR $@
|
|
|
|
|
cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin)
|
|
|
|
|
cmd_ar_builtin = rm -f $@; \
|
|
|
|
|
$(if $(real-prereqs), printf "$(obj)/%s " $(patsubst $(obj)/%,%,$(real-prereqs)) | xargs) \
|
|
|
|
|
$(AR) cDPrST $@
|
|
|
|
|
|
|
|
|
|
$(obj)/built-in.a: $(real-obj-y) FORCE |
|
|
|
|
$(call if_changed,ar_and_symver)
|
|
|
|
|
$(call if_changed,ar_builtin)
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Rule to create modules.order file
|
|
|
|
@ -459,32 +382,24 @@ $(obj)/modules.order: $(obj-m) FORCE
|
|
|
|
|
#
|
|
|
|
|
# Rule to compile a set of .o files into one .a file (with symbol table)
|
|
|
|
|
#
|
|
|
|
|
quiet_cmd_ar_lib = AR $@
|
|
|
|
|
cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar)
|
|
|
|
|
|
|
|
|
|
$(obj)/lib.a: $(lib-y) FORCE |
|
|
|
|
$(call if_changed,ar_lib)
|
|
|
|
|
|
|
|
|
|
# NOTE:
|
|
|
|
|
# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
|
|
|
|
|
# module is turned into a multi object module, $^ will contain header file
|
|
|
|
|
# dependencies recorded in the .*.cmd file.
|
|
|
|
|
ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) |
|
|
|
|
quiet_cmd_link_multi-m = AR [M] $@
|
|
|
|
|
cmd_link_multi-m = \
|
|
|
|
|
$(cmd_update_lto_symversions); \
|
|
|
|
|
rm -f $@; \
|
|
|
|
|
$(AR) cDPrsT $@ $(filter %.o,$^)
|
|
|
|
|
else |
|
|
|
|
quiet_cmd_link_multi-m = LD [M] $@
|
|
|
|
|
cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^)
|
|
|
|
|
endif |
|
|
|
|
$(call if_changed,ar)
|
|
|
|
|
|
|
|
|
|
quiet_cmd_ld_multi_m = LD [M] $@
|
|
|
|
|
cmd_ld_multi_m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@) $(cmd_objtool)
|
|
|
|
|
|
|
|
|
|
define rule_ld_multi_m |
|
|
|
|
$(call cmd_and_savecmd,ld_multi_m)
|
|
|
|
|
$(call cmd,gen_objtooldep)
|
|
|
|
|
endef |
|
|
|
|
|
|
|
|
|
$(multi-obj-m): FORCE |
|
|
|
|
$(call if_changed,link_multi-m)
|
|
|
|
|
$(multi-obj-m): objtool-enabled := $(delay-objtool) |
|
|
|
|
$(multi-obj-m): part-of-module := y |
|
|
|
|
$(multi-obj-m): %.o: %.mod FORCE |
|
|
|
|
$(call if_changed_rule,ld_multi_m)
|
|
|
|
|
$(call multi_depend, $(multi-obj-m), .o, -objs -y -m) |
|
|
|
|
|
|
|
|
|
targets += $(multi-obj-m)
|
|
|
|
|
targets := $(filter-out $(PHONY), $(targets))
|
|
|
|
|
|
|
|
|
|
# Add intermediate targets:
|
|
|
|
|