• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2# modules
3#
4# args:
5# MODULE : module name (required)
6# MODULE_SRCS : list of source files, local path (required)
7# MODULE_DEPS : other modules that this one depends on
8# MODULE_DEFINES : #defines local to this module
9# MODULE_OPTFLAGS : OPTFLAGS local to this module
10# MODULE_COMPILEFLAGS : COMPILEFLAGS local to this module
11# MODULE_CFLAGS : CFLAGS local to this module
12# MODULE_CPPFLAGS : CPPFLAGS local to this module
13# MODULE_ASMFLAGS : ASMFLAGS local to this module
14# MODULE_RUSTFLAGS : RUSTFLAGS local to this module
15# MODULE_RUSTDOCFLAGS : RUSTDOCFLAGS local to this module
16# MODULE_RUSTDOC_OBJECT : marker file to use as target when building Rust docs
17# MODULE_INCLUDES : include directories local to this module
18# MODULE_SRCDEPS : extra dependencies that all of this module's files depend on
19# MODULE_EXTRA_ARCHIVES : extra .a files that should be linked with the module
20# MODULE_EXTRA_OBJS : extra .o files that should be linked with the module
21# MODULE_DISABLE_LTO : disable LTO for this module
22# MODULE_DISABLE_CFI : disable CFI for this module
23# MODULE_DISABLE_STACK_PROTECTOR : disable stack protector for this module
24# MODULE_DISABLE_SCS : disable shadow call stack for this module
25# MODULE_SKIP_DOCS : skip generating docs for this module
26
27# MODULE_ARM_OVERRIDE_SRCS : list of source files, local path that should be force compiled with ARM (if applicable)
28
29# the minimum module rules.mk file is as follows:
30#
31# LOCAL_DIR := $(GET_LOCAL_DIR)
32# MODULE := $(LOCAL_DIR)
33#
34# MODULE_SRCS := $(LOCAL_DIR)/at_least_one_source_file.c
35#
36# include make/module.mk
37
38# if QUERY_MODULE is set, the rules.mk that included us was itself included not
39# to define a module's make targets but to query the variables it sets for the
40# rest of the build. in this case, skip all further processing
41ifeq ($(QUERY_MODULE),)
42
43# test for old style rules.mk
44ifneq ($(MODULE_OBJS),)
45$(warning MODULE_OBJS = $(MODULE_OBJS))
46$(error MODULE $(MODULE) is setting MODULE_OBJS, change to MODULE_SRCS)
47endif
48ifneq ($(OBJS),)
49$(warning OBJS = $(OBJS))
50$(error MODULE $(MODULE) is probably setting OBJS, change to MODULE_SRCS)
51endif
52
53ifeq ($(call TOBOOL,$(TRUSTY_NEW_MODULE_SYSTEM)),true)
54$(error MODULE $(MODULE) was included through the new module system and therefore must include library.mk or trusted_app.mk)
55endif
56
57MODULE_SRCDIR := $(MODULE)
58MODULE_BUILDDIR := $(call TOBUILDDIR,$(MODULE_SRCDIR))
59
60# add a local include dir to the global include path
61GLOBAL_INCLUDES += $(MODULE_SRCDIR)/include
62
63$(foreach MOD,$(MODULE_DEPS), $(if $(call FIND_MODULE,$(MOD)),,$(error Module doesn't exist: $(MOD) (included from $(MODULE)))))
64
65# add the listed module deps to the global list
66MODULES += $(MODULE_DEPS)
67
68#$(info module $(MODULE))
69#$(info MODULE_SRCDIR $(MODULE_SRCDIR))
70#$(info MODULE_BUILDDIR $(MODULE_BUILDDIR))
71#$(info MODULE_DEPS $(MODULE_DEPS))
72#$(info MODULE_SRCS $(MODULE_SRCS))
73
74# Turn spaces into underscores and escape quotes for the module_config.h header
75define clean_defines
76$(subst $(SPACE),_,$(subst \",\\\\\",$(subst $(BUILDROOT),__BUILDROOT__,$(1))))
77endef
78
79MODULE_DEFINES += MODULE_COMPILEFLAGS=\"$(call clean_defines,$(MODULE_COMPILEFLAGS))\"
80MODULE_DEFINES += MODULE_CFLAGS=\"$(call clean_defines,$(MODULE_CFLAGS))\"
81MODULE_DEFINES += MODULE_CPPFLAGS=\"$(call clean_defines,$(MODULE_CPPFLAGS))\"
82MODULE_DEFINES += MODULE_ASMFLAGS=\"$(call clean_defines,$(MODULE_ASMFLAGS))\"
83MODULE_DEFINES += MODULE_RUSTFLAGS=\"$(call clean_defines,$(MODULE_RUSTFLAGS))\"
84MODULE_DEFINES += MODULE_RUSTDOCFLAGS=\"$(call clean_defines,$(MODULE_RUSTDOCFLAGS))\"
85MODULE_DEFINES += MODULE_RUST_ENV=\"$(call clean_defines,$(MODULE_RUST_ENV))\"
86MODULE_DEFINES += MODULE_LDFLAGS=\"$(call clean_defines,$(MODULE_LDFLAGS))\"
87MODULE_DEFINES += MODULE_OPTFLAGS=\"$(call clean_defines,$(MODULE_OPTFLAGS))\"
88MODULE_DEFINES += MODULE_INCLUDES=\"$(call clean_defines,$(MODULE_INCLUDES))\"
89MODULE_DEFINES += MODULE_SRCDEPS=\"$(call clean_defines,$(MODULE_SRCDEPS))\"
90MODULE_DEFINES += MODULE_DEPS=\"$(call clean_defines,$(MODULE_DEPS))\"
91MODULE_DEFINES += MODULE_SRCS=\"$(call clean_defines,$(MODULE_SRCS))\"
92
93# Handle common kernel module flags. Common userspace flags are found in
94# user/base/make/common_flags.mk
95ifneq (true,$(call TOBOOL,$(USER_TASK_MODULE)))
96
97# LTO
98ifneq (true,$(call TOBOOL,$(MODULE_DISABLE_LTO)))
99ifeq (true,$(call TOBOOL,$(KERNEL_LTO_ENABLED)))
100MODULE_COMPILEFLAGS += $(GLOBAL_LTO_COMPILEFLAGS)
101
102# CFI
103MODULE_CFI_ENABLED := false
104ifneq (true,$(call TOBOOL,$(MODULE_DISABLE_CFI)))
105ifeq (true,$(call TOBOOL,$(CFI_ENABLED)))
106MODULE_CFI_ENABLED := true
107endif
108
109ifdef KERNEL_CFI_ENABLED
110MODULE_CFI_ENABLED := $(call TOBOOL,$(KERNEL_CFI_ENABLED))
111endif
112
113endif
114
115ifeq (true,$(call TOBOOL,$(MODULE_CFI_ENABLED)))
116MODULE_COMPILEFLAGS += \
117	-fsanitize-blacklist=trusty/kernel/lib/ubsan/exemptlist \
118	-fsanitize=cfi \
119	-fsanitize-cfi-icall-experimental-normalize-integers \
120	-DCFI_ENABLED
121
122ifeq (true,$(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_RUST_CFI)))
123# CFI rust <-> C cfi
124MODULE_RUSTFLAGS += -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
125endif
126
127MODULES += trusty/kernel/lib/ubsan
128
129ifeq (true,$(call TOBOOL,$(CFI_DIAGNOSTICS)))
130MODULE_COMPILEFLAGS += -fno-sanitize-trap=cfi
131endif
132endif
133
134endif
135endif
136
137# Branch Target Identification
138ifeq (true,$(call TOBOOL,$(KERNEL_BTI_ENABLED)))
139MODULE_COMPILEFLAGS += -DKERNEL_BTI_ENABLED \
140                       -DBTI_ENABLED
141endif
142
143# Pointer Authentication Codes
144ifeq (true,$(call TOBOOL,$(KERNEL_PAC_ENABLED)))
145ifeq (true,$(call TOBOOL,$(SCS_ENABLED)))
146# See https://github.com/llvm/llvm-project/issues/63457
147$(error Error: Kernel shadow call stack is not supported when Kernel PAC is enabled)
148endif
149
150MODULE_COMPILEFLAGS += -DKERNEL_PAC_ENABLED
151endif
152
153# Decide on the branch protection scheme
154ifeq (true,$(call TOBOOL,$(KERNEL_BTI_ENABLED)))
155ifeq (true,$(call TOBOOL,$(KERNEL_PAC_ENABLED)))
156MODULE_COMPILEFLAGS += -mbranch-protection=bti+pac-ret
157else
158MODULE_COMPILEFLAGS += -mbranch-protection=bti
159endif
160else # !KERNEL_BTI_ENABLED
161ifeq (true,$(call TOBOOL,$(KERNEL_PAC_ENABLED)))
162MODULE_COMPILEFLAGS += -mbranch-protection=pac-ret
163endif
164endif
165
166# Shadow call stack
167ifeq (true,$(call TOBOOL,$(SCS_ENABLED)))
168# set in arch/$(ARCH)/toolchain.mk iff shadow call stack is supported
169ifeq (false,$(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_SCS)))
170$(error Error: Shadow call stack is not supported for $(ARCH))
171endif
172
173ifeq (false,$(call TOBOOL,$(MODULE_DISABLE_SCS)))
174# architectures that support SCS should set the flag that reserves
175# a register for the shadow call stack in their toolchain.mk file
176MODULE_COMPILEFLAGS += \
177	-fsanitize=shadow-call-stack \
178
179endif
180endif
181
182endif
183
184# Initialize all automatic var to 0 if not initialized
185MODULE_COMPILEFLAGS += -ftrivial-auto-var-init=zero
186
187# Rebuild every module if the toolchain changes
188MODULE_SRCDEPS += $(TOOLCHAIN_CONFIG)
189
190MODULE_IS_RUST := $(if $(filter %.rs,$(MODULE_SRCS)),true,false)
191
192# generate a per-module config.h file
193ifeq ($(MODULE_IS_RUST),false)
194MODULE_CONFIG := $(MODULE_BUILDDIR)/module_config.h
195
196$(MODULE_CONFIG): MODULE_DEFINES:=$(MODULE_DEFINES)
197$(MODULE_CONFIG): MODULE:=$(MODULE)
198$(MODULE_CONFIG): configheader
199	@$(call INFO_DONE,$(MODULE),generating config header, $@)
200	@$(call MAKECONFIGHEADER,$@,MODULE_DEFINES)
201
202GENERATED += $(MODULE_CONFIG)
203
204MODULE_COMPILEFLAGS += --include=$(MODULE_CONFIG)
205
206MODULE_SRCDEPS += $(MODULE_CONFIG)
207
208MODULE_INCLUDES := $(addprefix -I,$(MODULE_INCLUDES))
209endif
210
211# include the rules to compile the module's object files
212include make/compile.mk
213
214# MODULE_OBJS is passed back from compile.mk
215#$(info MODULE_OBJS = $(MODULE_OBJS))
216
217ifeq ($(MODULE_IS_RUST),true)
218
219# ensure that proc-macro libraries are considered host libraries. userspace does
220# this in library.mk, but we also compile proc-macro crates for the kernel here
221ifeq ($(MODULE_RUST_CRATE_TYPES),proc-macro)
222MODULE_RUST_HOST_LIB := true
223endif
224
225MODULE_IS_KERNEL :=
226# is module using old module system? (using module.mk directly)
227ifeq ($(TRUSTY_USERSPACE),)
228ifeq ($(call TOBOOL,$(MODULE_RUST_HOST_LIB)),false)
229MODULE_IS_KERNEL := true
230endif
231endif
232
233# is module being built as kernel code?
234ifeq ($(call TOBOOL,$(MODULE_IS_KERNEL)),true)
235
236# validate crate name
237ifeq ($(MODULE_CRATE_NAME),)
238$(error rust module $(MODULE) does not set MODULE_CRATE_NAME)
239endif
240
241# Generate Rust bindings with bindgen if requested
242ifneq ($(strip $(MODULE_BINDGEN_SRC_HEADER)),)
243include make/bindgen.mk
244endif
245
246# library and module deps are set mutually exclusively, so it's safe to simply
247# concatenate them to use whichever is set
248MODULE_ALL_DEPS := $(MODULE_LIBRARY_DEPS) $(MODULE_LIBRARY_EXPORTED_DEPS) $(MODULE_DEPS)
249
250ifeq ($(call TOBOOL,$(MODULE_ADD_IMPLICIT_DEPS)),true)
251
252# In userspace, MODULE_ADD_IMPLICIT_DEPS adds std.
253# In the kernel, it adds core, compiler_builtins and
254# lib/rust_support (except for external crates).
255MODULE_ALL_DEPS += \
256	trusty/user/base/lib/libcore-rust \
257	trusty/user/base/lib/libcompiler_builtins-rust \
258
259# rust_support depends on some external crates. We cannot
260# add it as an implicit dependency to any of them because
261# that would create a circular dependency. External crates
262# are either under external/rust/crates or in the monorepo
263# external/rust/android-crates-io/crates.
264ifeq ($(filter external/rust/crates/%,$(MODULE)),)
265ifeq ($(filter external/rust/android-crates-io/crates/%,$(MODULE)),)
266ifeq ($(filter external/rust/android-crates-io/extra_versions/crates/%,$(MODULE)),)
267MODULE_ALL_DEPS += $(LKROOT)/lib/rust_support
268endif
269endif
270endif
271
272endif
273
274define READ_CRATE_INFO
275QUERY_MODULE := $1
276QUERY_VARIABLES := MODULE_CRATE_NAME MODULE_RUST_STEM MODULE_RUST_CRATE_TYPES
277$$(eval include make/query.mk)
278
279# assign queried variables for later use
280MODULE_$(1)_CRATE_NAME := $$(QUERY_MODULE_CRATE_NAME)
281MODULE_$(1)_CRATE_STEM := $$(if $$(QUERY_MODULE_RUST_STEM),$$(QUERY_MODULE_RUST_STEM),$$(QUERY_MODULE_CRATE_NAME))
282MODULE_$(1)_RUST_CRATE_TYPES := $$(if $$(QUERY_MODULE_RUST_CRATE_TYPES),$$(QUERY_MODULE_RUST_CRATE_TYPES),rlib)
283endef
284
285# ensure that MODULE_..._CRATE_NAME, _CRATE_STEM, and _RUST_CRATE_TYPES are populated
286$(foreach rust_dep,$(MODULE_ALL_DEPS),$(eval $(call READ_CRATE_INFO,$(rust_dep))))
287
288MODULE_RUST_DEPS := $(foreach dep, $(MODULE_ALL_DEPS), $(if $(MODULE_$(dep)_CRATE_NAME),$(dep),))
289
290# split deps into proc-macro and non- because the former are built for the host
291KERNEL_RUST_DEPS := $(foreach dep, $(MODULE_RUST_DEPS), $(if $(filter proc-macro,$(MODULE_$(dep)_RUST_CRATE_TYPES)),,$(dep)))
292
293HOST_RUST_DEPS := $(foreach dep, $(MODULE_RUST_DEPS), $(if $(filter proc-macro,$(MODULE_$(dep)_RUST_CRATE_TYPES)),$(dep),))
294
295# add kernel rust deps to the set of modules
296MODULES += $(KERNEL_RUST_DEPS)
297HOST_MODULES += $(HOST_RUST_DEPS)
298
299# determine crate names of dependency modules so we can depend on their rlibs.
300# because of ordering, we cannot simply e.g. set/read MODULE_$(dep)_CRATE_NAME,
301# so we must manually read the variable value from the Makefile
302DEP_CRATE_NAMES := $(foreach dep, $(KERNEL_RUST_DEPS), $(MODULE_$(dep)_CRATE_NAME))
303DEP_CRATE_STEMS := $(foreach dep, $(KERNEL_RUST_DEPS), $(MODULE_$(dep)_CRATE_STEM))
304
305# compute paths of host (proc-macro) dependencies
306HOST_DEP_CRATE_NAMES := $(foreach dep, $(HOST_RUST_DEPS), $(MODULE_$(dep)_CRATE_NAME))
307HOST_DEP_CRATE_STEMS := $(foreach dep, $(HOST_RUST_DEPS), $(MODULE_$(dep)_CRATE_STEM))
308MODULE_KERNEL_RUST_HOST_LIBS := $(foreach stem, $(HOST_DEP_CRATE_STEMS), $(TRUSTY_HOST_LIBRARY_BUILDDIR)/lib$(stem).so)
309gen_host_rlib_assignment = $(1)=$(TRUSTY_HOST_LIBRARY_BUILDDIR)/lib$(2).so
310MODULE_RLIBS += $(call pairmap,gen_host_rlib_assignment,$(HOST_DEP_CRATE_NAMES),$(HOST_DEP_CRATE_STEMS))
311
312# Stem defaults to the crate name
313ifeq ($(MODULE_RUST_STEM),)
314MODULE_RUST_STEM := $(MODULE_CRATE_NAME)
315endif
316
317# save dep crate names so we can topologically sort them for top-level rust build
318MODULE_$(MODULE_RUST_STEM)_CRATE_DEPS := $(DEP_CRATE_STEMS)
319ALL_KERNEL_HOST_CRATE_NAMES := $(ALL_KERNEL_HOST_CRATE_NAMES) $(HOST_DEP_CRATE_NAMES)
320ALL_KERNEL_HOST_CRATE_STEMS := $(ALL_KERNEL_HOST_CRATE_STEMS) $(HOST_DEP_CRATE_STEMS)
321
322# save all --cfg RUSTFLAGS so they can be included in rust-project.json
323MODULE_$(MODULE_RUST_STEM)_CRATE_CFG := $(patsubst --cfg=%,%,$(filter --cfg=%,$(subst --cfg ,--cfg=,$(GLOBAL_RUSTFLAGS) $(ARCH_RUSTFLAGS) $(MODULE_RUSTFLAGS))))
324
325# change BUILDDIR so RSOBJS for kernel are distinct targets from userspace ones
326OLD_BUILDDIR := $(BUILDDIR)
327BUILDDIR := $(TRUSTY_KERNEL_LIBRARY_BUILDDIR)
328
329# compute paths of dependencies
330MODULE_KERNEL_RUST_LIBS := $(foreach dep, $(DEP_CRATE_STEMS), $(call TOBUILDDIR,lib$(dep).rlib))
331gen_rlib_assignment = $(1)=$(call TOBUILDDIR,lib$(2).rlib)
332MODULE_RLIBS += $(call pairmap,gen_rlib_assignment,$(DEP_CRATE_NAMES),$(DEP_CRATE_STEMS))
333
334# include rust lib deps in lib deps
335MODULE_LIBRARIES += $(MODULE_KERNEL_RUST_LIBS) $(MODULE_KERNEL_RUST_HOST_LIBS)
336
337# determine MODULE_RSOBJS and MODULE_RUST_CRATE_TYPES for rust kernel modules
338include make/rust.mk
339
340# save extra information for constructing kernel rust-project.json in rust-toplevel.mk
341MODULE_$(MODULE_RUST_STEM)_RUST_SRC := $(filter %.rs,$(MODULE_SRCS))
342MODULE_$(MODULE_RUST_STEM)_RUST_EDITION := $(MODULE_RUST_EDITION)
343
344# only allow rlibs because we build rlibs, then link them all into one .a
345ifneq ($(MODULE_RUST_CRATE_TYPES),rlib)
346$(error rust crates for the kernel must be built as rlibs only, but $(MODULE) builds $(MODULE_RUST_CRATE_TYPES))
347endif
348
349# accumulate list of all crates we built (for linking, so skip proc-macro crates)
350ALLMODULE_CRATE_STEMS := $(MODULE_RUST_STEM) $(ALLMODULE_CRATE_STEMS)
351
352# reset BUILDDIR
353BUILDDIR := $(OLD_BUILDDIR)
354
355else # userspace rust
356
357MODULE_OBJECT := $(MODULE_RSOBJS)
358
359# make the rest of the build depend on our output
360ALLMODULE_OBJS := $(MODULE_INIT_OBJS) $(ALLMODULE_OBJS) $(MODULE_OBJECT) $(MODULE_EXTRA_ARCHIVES)
361
362endif # kernel/userspace rust
363
364# trigger rebuild with any of the rust compiler flags change
365MODULE_RUSTFLAGS_CONFIG := $(MODULE_BUILDDIR)/rustflags.config
366
367# TODO(b/383631031): properly include $(GLOBAL_RUSTFLAGS) as set in rust.mk in MODULE_RUSTFLAGS
368$(MODULE_RUSTFLAGS_CONFIG): MODULE_RUSTFLAGS:=$(ARCH_$(ARCH)_RUSTFLAGS) $(MODULE_RUSTFLAGS)
369$(MODULE_RUSTFLAGS_CONFIG): MODULE:=$(MODULE)
370$(MODULE_RUSTFLAGS_CONFIG): configheader
371	@$(call INFO_DONE,$(MODULE),generating module rustflags.config, $@)
372	@$(call MAKECONFIGHEADER,$@,MODULE_RUSTFLAGS)
373
374GENERATED += $(MODULE_RUSTFLAGS_CONFIG)
375$(MODULE_RSOBJS): $(MODULE_RUSTFLAGS_CONFIG)
376
377# Build Rust sources
378$(addsuffix .d,$(MODULE_RSOBJS)):
379
380MODULE_RSSRC := $(filter %.rs,$(MODULE_SRCS))
381$(MODULE_RSOBJS): MODULE := $(MODULE)
382$(MODULE_RSOBJS): $(MODULE_RSSRC) $(MODULE_SRCDEPS) $(MODULE_EXTRA_OBJECTS) $(MODULE_LIBRARIES) $(addsuffix .d,$(MODULE_RSOBJS))
383	@$(MKDIR)
384	@$(call ECHO,$(MODULE),compiling rust module,$<)
385ifeq ($(call TOBOOL,$(MODULE_RUST_USE_CLIPPY)),true)
386	+$(NOECHO) set -e ; \
387		TEMP_CLIPPY_DIR=$$(mktemp -d) ;\
388		mkdir -p $(dir $$TEMP_CLIPPY_DIR/$@) ;\
389		$(MODULE_RUST_ENV) $(CLIPPY_DRIVER) $(GLOBAL_RUSTFLAGS) $(ARCH_RUSTFLAGS) $(MODULE_RUSTFLAGS) $< -o $$TEMP_CLIPPY_DIR/$@ ;\
390		rm -rf $$TEMP_CLIPPY_DIR
391endif
392	+$(NOECHO)$(MODULE_RUST_ENV) $(RUSTC) $(GLOBAL_RUSTFLAGS) $(ARCH_RUSTFLAGS) $(MODULE_RUSTFLAGS) $< --emit "dep-info=$@.d" -o $@
393	@$(call ECHO_DONE_SILENT,$(MODULE),compiling rust module,$<)
394
395ifneq ($(call TOBOOL,$(MODULE_SKIP_DOCS)),true)
396
397# Pass rustdoc the same flags as rustc such that the generated documentation
398# matches the code that gets compiled and run. Note: $(GLOBAL_RUSTFLAGS) adds
399# $(TRUSTY_HOST_LIBRARY_BUILDDIR) to the library search path. This is necessary
400# to pick up dependencies that are proc macros and thus built in the host dir.
401$(MODULE_RUSTDOC_OBJECT): $(MODULE_RSSRC) | $(MODULE_RSOBJS)
402	@$(MKDIR)
403	@$(call ECHO,rustdoc,generating documentation,for $(MODULE_CRATE_NAME))
404	+$(NOECHO)$(MODULE_RUST_ENV) $(RUSTDOC) $(GLOBAL_RUSTFLAGS) $(ARCH_RUSTFLAGS) $(MODULE_RUSTFLAGS_PRELINK) $(MODULE_RUSTDOCFLAGS) -L $(TRUSTY_LIBRARY_BUILDDIR) --out-dir $(MODULE_RUSTDOC_OUT_DIR) $<
405	@touch $@
406	@$(call ECHO_DONE_SILENT,rustdoc,generating documentation,for $(MODULE_CRATE_NAME))
407
408EXTRA_BUILDDEPS += $(MODULE_RUSTDOC_OBJECT)
409
410endif
411
412-include $(addsuffix .d,$(MODULE_RSOBJS))
413
414# track the module rlib for make clean
415GENERATED += $(MODULE_RSOBJS)
416
417
418else # not rust
419# Archive the module's object files into a static library.
420MODULE_OBJECT := $(call TOBUILDDIR,$(MODULE_SRCDIR).mod.a)
421$(MODULE_OBJECT): MODULE := $(MODULE)
422$(MODULE_OBJECT): $(MODULE_OBJS) $(MODULE_EXTRA_OBJS)
423	@$(MKDIR)
424	@$(call ECHO,$(MODULE),creating,$@)
425	$(NOECHO)rm -f $@
426	$(NOECHO)$(AR) rcs $@ $^
427	@$(call ECHO_DONE_SILENT,$(MODULE),creating,$@)
428
429# track the module object for make clean
430GENERATED += $(MODULE_OBJECT)
431
432# make the rest of the build depend on our output
433ALLMODULE_OBJS := $(MODULE_INIT_OBJS) $(ALLMODULE_OBJS) $(MODULE_OBJECT) $(MODULE_EXTRA_ARCHIVES)
434
435endif # rust or not
436
437# track all of the source files compiled
438ALLSRCS += $(MODULE_SRCS_FIRST) $(MODULE_SRCS)
439
440# track all the objects built
441ALLOBJS += $(MODULE_INIT_OBJS) $(MODULE_OBJS)
442
443# empty out any vars set here
444MODULE :=
445MODULE_SRCDIR :=
446MODULE_BUILDDIR :=
447MODULE_DEPS :=
448MODULE_SRCS :=
449MODULE_OBJS :=
450MODULE_DEFINES :=
451MODULE_OPTFLAGS :=
452MODULE_COMPILEFLAGS :=
453MODULE_CFLAGS :=
454MODULE_CPPFLAGS :=
455MODULE_ASMFLAGS :=
456MODULE_RUSTFLAGS :=
457MODULE_RUSTDOCFLAGS :=
458MODULE_SRCDEPS :=
459MODULE_INCLUDES :=
460MODULE_EXTRA_ARCHIVES :=
461MODULE_EXTRA_OBJS :=
462MODULE_CONFIG :=
463MODULE_OBJECT :=
464MODULE_ARM_OVERRIDE_SRCS :=
465MODULE_SRCS_FIRST :=
466MODULE_INIT_OBJS :=
467MODULE_DISABLE_LTO :=
468MODULE_LTO_ENABLED :=
469MODULE_DISABLE_CFI :=
470MODULE_DISABLE_STACK_PROTECTOR :=
471MODULE_DISABLE_SCS :=
472MODULE_RSSRC :=
473MODULE_IS_RUST :=
474MODULE_RUST_USE_CLIPPY :=
475MODULE_RSOBJS :=
476MODULE_RUST_EDITION :=
477MODULE_RUSTDOC_OBJECT :=
478MODULE_RUSTDOCFLAGS :=
479MODULE_ALL_DEPS :=
480MODULE_RUST_DEPS :=
481MODULE_RUST_STEM :=
482MODULE_SKIP_DOCS :=
483MODULE_ADD_IMPLICIT_DEPS := true
484MODULE_RUSTFLAGS_CONFIG :=
485
486endif # QUERY_MODULE (this line should stay after all other processing)
487