diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-30 09:22:00 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-30 09:22:00 -0700 |
| commit | 034dd340b08be1f2f0477ad16131d609f9dbd53c (patch) | |
| tree | 2536f4b2d7893ccd916b5abdf3c454ad6edc03c2 /scripts/Makefile.build | |
| download | linux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.tar.gz linux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.zip | |
Merge tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-tracegrafted
Pull tracing fixes from Steven Rostedt:
- Fix error output of boot instance creation failure
Currently if a boot instance creation fails, instead of printing out
the name of the instance that failed, it prints "(null)". That is
because it prints "cur_str" that had already been processed by
strsep(). Print the saved name instead.
While at it, print the error code of the failure.
- Fix use-after-free for same named historgrams
Histograms can be named so that they can be used in multiple events.
But if the named histogram has a variable attached, the second event
that uses the named histogram which duplicates it and needs to free
the original after duplication leaves the old variable in place and
still visible. If another histogram uses than variable, it will use
the stale one which will try to reference the freed duplicate
histogram and crash the kernel.
Free the duplicate variables along with the duplicated histogram
data.
- Check return value of kthread_run() in event self test
The events self tests uses a kthread for testing but does not check
if it succeeded in creating a kthread. If the kthread creation were
to fail, the code will still try to call kthread_stop() on the error
returned.
- Fix race between reading trace_pipe and updating subbuffer size
If a user is reading the trace_pipe file at the same time they update
the ring buffer sub-buffer size, can cause the trace_pipe read to
read stale data. Add trace_access_lock() around updating the ring
buffer sub-buffer size.
- Fix eventfs_inode on failure path in creation of the events directory
In the creation of the "events" directory, if after allocating the
eventfs_inode a failure is detected, it calls cleanup_ei() which
calls free_ei(). The free_ei() will test if eventfs_inode being freed
has no children. It is a bug if it does. But on the failure case of
the creation of the "events" directory, the children lists have not
yet been initialized and the free will trigger a warning because
list_empty() on an uninitialized list returns false.
Move the initialization into init_ei() where it makes more sense and
makes sure that a created eventfs_inode has its lists initialized
upon creation.
- Check return value of kthread_run() in ftrace direct sample code
The sample code that shows how to use the ftrace direct calls does
not test the return of kthread_run() to see if it succeeds. Return a
failure if the kthread_run() doesn't succeed.
- Clear user events state on fork in case of alloc failure
On fork, the child gets a pointer to the parent's user events state.
It makes a copy of it then updates the child's pointer to it. But if
the allocation fails, the duplication function leaves the child with
a pointer to its parent's descriptor. When the child cleans up its
data, it will free the parent's descriptor while the parent is still
using it.
In the duplication function, set the child's user_event_mm to NULL
before testing if the allocation succeeded, and when it exits it will
not free the parent's descriptor.
- Fix retry exhaustion in simple ring buffer reader swap
simple_ring_buffer_swap_reader_page() starts with retry set to 8 and
post-decrements it only after a failed link replacement. On the final
attempt, a successful replacement leaves retry at zero, while a
failed replacement leaves it at -1.
But the check for success expects the retry value to be non-zero and
exits with an error on zero. This is the opposite result. Fix it.
- Fail nicely when the remote swap_reader_page() returns an error
Currently, if the swap_reader_page() of a remote buffer fails, it
triggers a WARN_ON_ONCE() and continues normally. Instead, have it
exit with an error and a pr_warn() print instead of a full WARNING.
* tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
ring-buffer: Stop remote reader update when page swap fails
tracing: Fix retry exhaustion in simple ring buffer reader swap
tracing/user_events: Clear copied tracing state before fork duplication
samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modify
samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modify
eventfs: Initialize ei->children and ei->list in init_ei()
tracing: Fix use-after-free in trace_pipe read on sub-buffer order change
tracing: Fix crash passing ERR_PTR to kthread_stop()
tracing: Fix use-after-free with same-name named triggers
tracing: Fix logged instance name on creation failure
Diffstat (limited to 'scripts/Makefile.build')
| -rw-r--r-- | scripts/Makefile.build | 597 |
1 files changed, 597 insertions, 0 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build new file mode 100644 index 000000000..a48209591 --- /dev/null +++ b/scripts/Makefile.build @@ -0,0 +1,597 @@ +# SPDX-License-Identifier: GPL-2.0 +# ========================================================================== +# Building +# ========================================================================== + +src := $(srcroot)/$(obj) + +PHONY := $(obj)/ +$(obj)/: + +# Init all relevant variables used in kbuild files so +# 1) they have correct type +# 2) they do not inherit any value from the environment +obj-y := +obj-m := +lib-y := +lib-m := +always-y := +always-m := +targets := +subdir-y := +subdir-m := +asflags-y := +ccflags-y := +rustflags-y := +cppflags-y := +ldflags-y := + +subdir-asflags-y := +subdir-ccflags-y := +subdir-rustflags-y := + +# Read auto.conf if it exists, otherwise ignore +-include $(objtree)/include/config/auto.conf + +include $(srctree)/scripts/Kbuild.include +include $(srctree)/scripts/Makefile.compiler +include $(kbuild-file) +include $(srctree)/scripts/Makefile.lib + +# flags that take effect in current and sub directories +KBUILD_AFLAGS += $(subdir-asflags-y) +KBUILD_CFLAGS += $(subdir-ccflags-y) +KBUILD_RUSTFLAGS += $(subdir-rustflags-y) + +# Figure out what we need to build from the various variables +# =========================================================================== + +# When an object is listed to be built compiled-in and modular, +# only build the compiled-in version +obj-m := $(filter-out $(obj-y),$(obj-m)) + +# Libraries are always collected in one lib file. +# Filter out objects already built-in +lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m))) + +# Subdirectories we need to descend into +subdir-ym := $(sort $(subdir-y) $(subdir-m) \ + $(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m)))) + +# Handle objects in subdirs: +# - If we encounter foo/ in $(obj-y), replace it by foo/built-in.a and +# foo/modules.order +# - If we encounter foo/ in $(obj-m), replace it by foo/modules.order +# +# Generate modules.order to determine modorder. Unfortunately, we don't have +# information about ordering between -y and -m subdirs. Just put -y's first. + +ifdef need-modorder +obj-m := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m)) +else +obj-m := $(filter-out %/, $(obj-m)) +endif + +ifdef need-builtin +obj-y := $(patsubst %/, %/built-in.a, $(obj-y)) +else +obj-y := $(filter-out %/, $(obj-y)) +endif + +# Expand $(foo-objs) $(foo-y) etc. by replacing their individuals +suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s)))) +# List composite targets that are constructed by combining other targets +multi-search = $(sort $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $m))) +# List primitive targets that are compiled from source files +real-search = $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $(call suffix-search, $m, $2, $3), $m)) + +# If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object +multi-obj-y := $(call multi-search, $(obj-y), .o, -objs -y) +multi-obj-m := $(call multi-search, $(obj-m), .o, -objs -y -m) +multi-obj-ym := $(multi-obj-y) $(multi-obj-m) + +# Replace multi-part objects by their individual parts, +# including built-in.a from subdirectories +real-obj-y := $(call real-search, $(obj-y), .o, -objs -y) +real-obj-m := $(call real-search, $(obj-m), .o, -objs -y -m) + +always-y += $(always-m) + +# hostprogs-always-y += foo +# ... is a shorthand for +# hostprogs += foo +# always-y += foo +hostprogs += $(hostprogs-always-y) $(hostprogs-always-m) +always-y += $(hostprogs-always-y) $(hostprogs-always-m) + +# userprogs-always-y is likewise. +userprogs += $(userprogs-always-y) $(userprogs-always-m) +always-y += $(userprogs-always-y) $(userprogs-always-m) + +# Add subdir path + +ifneq ($(obj),.) +extra-y := $(addprefix $(obj)/, $(extra-y)) +always-y := $(addprefix $(obj)/, $(always-y)) +targets := $(addprefix $(obj)/, $(targets)) +obj-m := $(addprefix $(obj)/, $(obj-m)) +lib-y := $(addprefix $(obj)/, $(lib-y)) +real-obj-y := $(addprefix $(obj)/, $(real-obj-y)) +real-obj-m := $(addprefix $(obj)/, $(real-obj-m)) +multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m)) +subdir-ym := $(addprefix $(obj)/, $(subdir-ym)) +endif + +ifndef obj +$(warning kbuild: Makefile.build is included improperly) +endif + +ifeq ($(need-modorder),) +ifneq ($(obj-m),) +$(warning $(patsubst %.o,'%.ko',$(obj-m)) will not be built even though obj-m is specified.) +$(warning You cannot use subdir-y/m to visit a module Makefile. Use obj-y/m instead.) +endif +endif + +# =========================================================================== + +# subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...) +subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y))) +subdir-modorder := $(sort $(filter %/modules.order, $(obj-m))) + +targets-for-builtin := $(extra-y) + +ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) +targets-for-builtin += $(obj)/lib.a +endif + +ifdef need-builtin +targets-for-builtin += $(obj)/built-in.a +endif + +targets-for-modules := $(foreach x, o mod, \ + $(patsubst %.o, %.$x, $(filter %.o, $(obj-m)))) + +ifdef need-modorder +targets-for-modules += $(obj)/modules.order +endif + +targets += $(targets-for-builtin) $(targets-for-modules) + +# Linus' kernel sanity checking tool +ifeq ($(KBUILD_CHECKSRC),1) + quiet_cmd_checksrc = CHECK $(patsubst $(srctree)/%,%,$<) + cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< +else ifeq ($(KBUILD_CHECKSRC),2) + quiet_cmd_force_checksrc = CHECK $(patsubst $(srctree)/%,%,$<) + cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< +endif + +ifeq ($(KBUILD_EXTMOD),) +ifneq ($(KBUILD_EXTRA_WARN),) + cmd_checkdoc = PYTHONDONTWRITEBYTECODE=1 $(PYTHON3) $(KERNELDOC) -none $(KDOCFLAGS) \ + $(if $(findstring 2, $(KBUILD_EXTRA_WARN)), -Wall) \ + $< +endif +endif + +# Compile C sources (.c) +# --------------------------------------------------------------------------- + +quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ + cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS) $(CC_FLAGS_LTO), $(c_flags)) -fverbose-asm -S -o $@ $< + +$(obj)/%.s: $(obj)/%.c FORCE + $(call if_changed_dep,cc_s_c) + +quiet_cmd_cpp_i_c = CPP $(quiet_modtag) $@ +cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< + +$(obj)/%.i: $(obj)/%.c FORCE + $(call if_changed_dep,cpp_i_c) + +getexportsymbols = $(NM) $@ | sed -n 's/.* __export_symbol_\(.*\)/$(1)/p' + +gendwarfksyms = $(objtree)/scripts/gendwarfksyms/gendwarfksyms \ + $(if $(KBUILD_SYMTYPES), --symtypes $(@:.o=.symtypes)) \ + $(if $(KBUILD_GENDWARFKSYMS_STABLE), --stable) + +genksyms = $(objtree)/scripts/genksyms/genksyms \ + $(if $(KBUILD_SYMTYPES), -T $(@:.o=.symtypes)) \ + $(if $(KBUILD_PRESERVE), -p) \ + $(addprefix -r , $(wildcard $(@:.o=.symref))) + +# These mirror gensymtypes_S and co below, keep them in synch. +ifdef CONFIG_GENDWARFKSYMS +cmd_gensymtypes_c = $(if $(skip_gendwarfksyms),, \ + $(call getexportsymbols,\1) | $(gendwarfksyms) $@) +else +cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) +endif # CONFIG_GENDWARFKSYMS + +# LLVM assembly +# Generate .ll files from .c +quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@ + cmd_cc_ll_c = $(CC) $(c_flags) -emit-llvm -S -fno-discard-value-names -o $@ $< + +$(obj)/%.ll: $(obj)/%.c FORCE + $(call if_changed_dep,cc_ll_c) + +# C (.c) files +# 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) + +ifdef CONFIG_MODVERSIONS +# When module versioning is enabled the following steps are executed: +# o compile a <file>.o from <file>.c +# o if <file>.o doesn't contain a __export_symbol_*, 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 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. + +gen_symversions = \ + if $(NM) $@ 2>/dev/null | grep -q ' __export_symbol_'; then \ + $(cmd_gensymtypes_$1) >> $(dot-target).cmd; \ + fi + +cmd_gen_symversions_c = $(call gen_symversions,c) + +endif + +ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT +# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl +ifdef BUILD_C_RECORDMCOUNT +ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") + RECORDMCOUNT_FLAGS = -w +endif +# Due to recursion, we must skip empty.o. +# The empty.o file is created in the make process in order to determine +# the target endianness and word size. It is made before all other C +# files, including recordmcount. +sub_cmd_record_mcount = \ + if [ $(@) != "scripts/mod/empty.o" ]; then \ + $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \ + fi; +recordmcount_source := $(srctree)/scripts/recordmcount.c \ + $(srctree)/scripts/recordmcount.h +else +sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ + "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ + "$(if $(CONFIG_64BIT),64,32)" \ + "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \ + "$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \ + "$(if $(part-of-module),1,0)" "$(@)"; +recordmcount_source := $(srctree)/scripts/recordmcount.pl +endif # BUILD_C_RECORDMCOUNT +cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \ + $(sub_cmd_record_mcount)) +endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT + +# '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 + +is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(target-stem).o)$(OBJECT_FILES_NON_STANDARD)n),$(is-kernel-object)) + +ifdef CONFIG_OBJTOOL +$(obj)/%.o: private objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y)) +endif + +ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) +cmd_warn_shared_object = $(if $(word 2, $(modname-multi)),$(warning $(kbuild-file): $*.o is added to multiple modules: $(modname-multi))) +endif + +# Built-in and composite module parts +$(obj)/%.o: $(obj)/%.c $(recordmcount_source) FORCE + $(call if_changed_rule,cc_o_c) + $(call cmd,force_checksrc) + +# 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)/%.mod: FORCE + $(call if_changed,mod) + +quiet_cmd_cc_lst_c = MKLST $@ + cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ + $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ + System.map $(OBJDUMP) > $@ + +$(obj)/%.lst: $(obj)/%.c FORCE + $(call if_changed_dep,cc_lst_c) + +# Compile Rust sources (.rs) +# --------------------------------------------------------------------------- + +# The features in this list are the ones allowed for non-`rust/` code. +# +# - Stable since Rust 1.87.0: `feature(asm_goto)`. +# - Stable since Rust 1.89.0: `feature(generic_arg_infer)`. +# - Expected to become stable: `feature(arbitrary_self_types)`. +# - To be determined: `feature(used_with_arg)`. +# +# Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on +# the unstable features in use. +rust_allowed_features := arbitrary_self_types,asm_goto,generic_arg_infer,used_with_arg + +# `--out-dir` is required to avoid temporaries being created by `rustc` in the +# current working directory, which may be not accessible in the out-of-tree +# modules case. +rust_common_cmd = \ + OBJTREE=$(abspath $(objtree)) \ + RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \ + -Zallow-features=$(rust_allowed_features) \ + -Zcrate-attr=no_std \ + -Zcrate-attr='feature($(rust_allowed_features))' \ + -Zunstable-options --extern pin_init --extern kernel \ + --extern zerocopy --extern zerocopy_derive \ + --crate-type rlib -L $(objtree)/rust/ \ + --sysroot=/dev/null \ + --out-dir $(dir $@) --emit=dep-info=$(depfile) + +# `--emit=obj`, `--emit=asm` and `--emit=llvm-ir` imply a single codegen unit +# will be used. We explicitly request `-Ccodegen-units=1` in any case, and +# the compiler shows a warning if it is not 1. However, if we ever stop +# requesting it explicitly and we start using some other `--emit` that does not +# imply it (and for which codegen is performed), then we would be out of sync, +# i.e. the outputs we would get for the different single targets (e.g. `.ll`) +# would not match each other. + +quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_o_rs = $(rust_common_cmd) --emit=$(if $(CONFIG_RUST_INLINE_HELPERS),llvm-bc=$(patsubst %.o,%.bc,$@),obj=$@) $< \ + $(if $(CONFIG_RUST_INLINE_HELPERS),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \ + $(objtree)/rust/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \ + $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ + $(cmd_ld_single)) \ + $(cmd_objtool) + +define rule_rustc_o_rs + $(call cmd_and_fixdep,rustc_o_rs) + $(call cmd,gen_objtooldep) +endef + +$(obj)/%.o: $(obj)/%.rs FORCE + +$(call if_changed_rule,rustc_o_rs) + +quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_rsi_rs = \ + $(rust_common_cmd) -Zunpretty=expanded $< >$@; \ + command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) --config-path $(srctree)/.rustfmt.toml $@ + +$(obj)/%.rsi: $(obj)/%.rs FORCE + +$(call if_changed_dep,rustc_rsi_rs) + +quiet_cmd_rustc_s_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_s_rs = $(rust_common_cmd) --emit=asm=$@ $< + +$(obj)/%.s: $(obj)/%.rs FORCE + +$(call if_changed_dep,rustc_s_rs) + +quiet_cmd_rustc_ll_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_ll_rs = $(rust_common_cmd) --emit=llvm-ir=$@ $< + +$(obj)/%.ll: $(obj)/%.rs FORCE + +$(call if_changed_dep,rustc_ll_rs) + +quiet_cmd_rustc_rs_rs_S = RSCPP $(quiet_modtag) $@ + cmd_rustc_rs_rs_S = $(CPP) $(c_flags) -xc -C -P $< | sed '1,/^\/\/ Cut here.$$/d' >$@ + +$(obj)/%.rs: $(obj)/%.rs.S FORCE + +$(call if_changed_dep,rustc_rs_rs_S) + +# Compile assembler sources (.S) +# --------------------------------------------------------------------------- + +# .S file exports must have their C prototypes defined in asm/asm-prototypes.h +# or a file that it includes, in order to get versioned symbols. We build a +# dummy C file that includes asm-prototypes and the EXPORT_SYMBOL lines from +# the .S file (with trailing ';'), and run genksyms on that, to extract vers. +# +# This is convoluted. The .S file must first be preprocessed to run guards and +# expand names, then the resulting exports must be constructed into plain +# EXPORT_SYMBOL(symbol); to build our dummy C file, and that gets preprocessed +# to make the genksyms input or compiled into an object for gendwarfksyms. +# +# These mirror gensymtypes_c and co above, keep them in synch. +getasmexports = \ + { echo "\#include <linux/kernel.h>" ; \ + echo "\#include <linux/string.h>" ; \ + echo "\#include <asm/asm-prototypes.h>" ; \ + $(call getexportsymbols,EXPORT_SYMBOL(\1);) ; } + +ifdef CONFIG_GENDWARFKSYMS +cmd_gensymtypes_S = \ + $(getasmexports) | \ + $(CC) $(c_flags) -c -o $(@:.o=.gendwarfksyms.o) -xc -; \ + $(call getexportsymbols,\1) | \ + $(gendwarfksyms) $(@:.o=.gendwarfksyms.o) +else +cmd_gensymtypes_S = \ + $(getasmexports) | \ + $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms) +endif # CONFIG_GENDWARFKSYMS + +quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@ +cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $< + +$(obj)/%.s: $(obj)/%.S FORCE + $(call if_changed_dep,cpp_s_S) + +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_gen_symversions_S = $(call gen_symversions,S) + +endif + +$(obj)/%.o: $(obj)/%.S FORCE + $(call if_changed_rule,as_o_S) + +targets += $(filter-out $(subdir-builtin), $(real-obj-y)) +targets += $(filter-out $(subdir-modorder), $(real-obj-m)) +targets += $(lib-y) $(always-y) + +# Linker scripts preprocessor (.lds.S -> .lds) +# --------------------------------------------------------------------------- +quiet_cmd_cpp_lds_S = LDS $@ + cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \ + -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< + +$(obj)/%.lds: $(src)/%.lds.S FORCE + $(call if_changed_dep,cpp_lds_S) + +# ASN.1 grammar +# --------------------------------------------------------------------------- +quiet_cmd_asn1_compiler = ASN.1 $(basename $@).[ch] + cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \ + $(basename $@).c $(basename $@).h + +$(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler + $(call cmd,asn1_compiler) + +# Build the compiled-in targets +# --------------------------------------------------------------------------- + +# To build objects in subdirs, we need to descend into the directories +$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; +$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; + +# +# 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 $@; \ + $(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_builtin) + +# This is a list of build artifacts from the current Makefile and its +# sub-directories. The timestamp should be updated when any of the member files. + +cmd_gen_order = { $(foreach m, $(real-prereqs), \ + $(if $(filter %/$(notdir $@), $m), cat $m, echo $m);) :; } \ + > $@ + +$(obj)/modules.order: $(obj-m) FORCE + $(call if_changed,gen_order) + +# +# Rule to compile a set of .o files into one .a file (with symbol table) +# + +$(obj)/lib.a: $(lib-y) FORCE + $(call if_changed,ar) + +quiet_cmd_ld_multi_m = LD [M] $@ + cmd_ld_multi_m = $(LD) $(ld_flags) -r -o $@ @$< $(cmd_objtool) + +define rule_ld_multi_m + $(call cmd_and_savecmd,ld_multi_m) + $(call cmd,gen_objtooldep) +endef + +$(multi-obj-m): private objtool-enabled := $(delay-objtool) +$(multi-obj-m): private 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) + +# Add intermediate targets: +# When building objects with specific suffix patterns, add intermediate +# targets that the final targets are derived from. +intermediate_targets = $(foreach sfx, $(2), \ + $(patsubst %$(strip $(1)),%$(sfx), \ + $(filter %$(strip $(1)), $(targets)))) +# %.asn1.o <- %.asn1.[ch] <- %.asn1 +targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) + +# Include additional build rules when necessary +# --------------------------------------------------------------------------- + +# $(sort ...) is used here to remove duplicated words and excessive spaces. +hostprogs := $(sort $(hostprogs)) +ifneq ($(hostprogs),) +include $(srctree)/scripts/Makefile.host +endif + +# $(sort ...) is used here to remove duplicated words and excessive spaces. +userprogs := $(sort $(userprogs)) +ifneq ($(userprogs),) +include $(srctree)/scripts/Makefile.userprogs +endif + +# Single targets +# --------------------------------------------------------------------------- + +single-subdirs := $(foreach d, $(subdir-ym), $(if $(filter $d/%, $(MAKECMDGOALS)), $d)) +single-subdir-goals := $(filter $(addsuffix /%, $(single-subdirs)), $(MAKECMDGOALS)) + +$(single-subdir-goals): $(single-subdirs) + @: + +# Descending +# --------------------------------------------------------------------------- + +PHONY += $(subdir-ym) +$(subdir-ym): + $(Q)$(MAKE) $(build)=$@ \ + need-builtin=$(if $(filter $@/built-in.a, $(subdir-builtin)),1) \ + need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1) \ + $(filter $@/%, $(single-subdir-goals)) + +# Add FORCE to the prerequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE + +FORCE: + +targets += $(filter-out $(single-subdir-goals), $(MAKECMDGOALS)) +targets := $(filter-out $(PHONY), $(targets)) + +# Now that targets is fully known, include dtb rules if needed +ifneq ($(need-dtbslist)$(dtb-y)$(dtb-)$(filter %.dtb %.dtb.o %.dtbo.o,$(targets)),) +include $(srctree)/scripts/Makefile.dtbs +endif + +# Build +# Needs to be after the include of Makefile.dtbs, which updates always-y +# --------------------------------------------------------------------------- + +$(obj)/: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \ + $(if $(KBUILD_MODULES), $(targets-for-modules)) \ + $(subdir-ym) $(always-y) + @: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +# Create directories for object files if they do not exist +obj-dirs := $(sort $(patsubst %/,%, $(dir $(targets)))) +# If targets exist, their directories apparently exist. Skip mkdir. +existing-dirs := $(sort $(patsubst %/,%, $(dir $(existing-targets)))) +obj-dirs := $(strip $(filter-out $(existing-dirs), $(obj-dirs))) +ifneq ($(obj-dirs),) +$(shell mkdir -p $(obj-dirs)) +endif + +.PHONY: $(PHONY) |
