1#
2# Copyright (c) 2023, Google, Inc. All rights reserved
3#
4# Permission is hereby granted, free of charge, to any person obtaining
5# a copy of this software and associated documentation files
6# (the "Software"), to deal in the Software without restriction,
7# including without limitation the rights to use, copy, modify, merge,
8# publish, distribute, sublicense, and/or sell copies of the Software,
9# and to permit persons to whom the Software is furnished to do so,
10# subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be
13# included in all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22#
23
24# Normalize inputs for building Rust modules
25#
26# args:
27# MODULE : name of the module
28# MODULE_SRCS : source files of the module, which should be a single .rs file
29# MODULE_RUST_CRATE_TYPES : list of crate types to build, rlib if not set
30# MODULE_CRATE_NAME : name of the crate, which can differ from module name. this
31# variable's value read outside Make for recursive dependencies, so it must be
32# unconditionally assigned a literal string, e.g. MODULE_CRATE_NAME := foo
33# MODULE_RUST_STEM : The stem of the output .rlib file for this library.
34# 	Defaults to $(MODULE_CRATE_NAME) if left empty.
35# MODULE_RUSTFLAGS : any extra flags to pass to rustc for the module
36# MODULE_RUST_HOST_LIB : whether the module is a host library
37# MODULE_SKIP_DOCS : whether to skip building SDK docs for a module
38#
39# sets:
40# MODULE_RUSTFLAGS
41# MODULE_RUSTDOCFLAGS
42# MODULE_RSOBJS
43# MODULE_RUST_CRATE_TYPES
44# MODULE_RUSTDOC_OBJECT
45# MODULE_EXPORT_RLIBS
46# (for trusted apps):
47# TRUSTY_APP_RUST_MAIN_SRC
48# TRUSTY_APP_RUST_SRCDEPS
49#
50# This file is not intended to be included directly by modules, just used from
51# the library (new) and module (old/kernel) build systems.
52
53ifneq ($(strip $(MODULE_SRCS_FIRST)),)
54$(error $(MODULE) sets MODULE_SRCS_FIRST but is a Rust module, which does not support MODULE_SRCS_FIRST)
55endif
56
57ifneq ($(filter-out %.rs,$(MODULE_SRCS)),)
58$(error $(MODULE) includes both Rust source files and other source files. Rust modules must only contain Rust sources.)
59endif
60
61ifneq ($(words $(filter %.rs,$(MODULE_SRCS))),1)
62$(error $(MODULE) includes more than one Rust file in MODULE_SRCS)
63endif
64
65ifneq ($(filter-out rlib staticlib bin proc-macro,$(MODULE_RUST_CRATE_TYPES)),)
66$(error $(MODULE) contains unrecognized crate type $(filter-out rlib staticlib bin proc-macro,$(MODULE_RUST_CRATE_TYPES)) in MODULE_RUST_CRATE_TYPES)
67endif
68
69ifeq ($(MODULE_CRATE_NAME),)
70$(error $(MODULE) is a Rust module but does not set MODULE_CRATE_NAME)
71endif
72
73# Stem defaults to the crate name
74ifeq ($(MODULE_RUST_STEM),)
75MODULE_RUST_STEM := $(MODULE_CRATE_NAME)
76endif
77
78MODULE_RUSTFLAGS += --crate-name=$(MODULE_CRATE_NAME)
79
80# Throw the module name into the stable crate id so rustc distinguishes
81# between different crates with the same name
82MODULE_RUSTFLAGS += -C metadata=$(MODULE_RUST_STEM)
83
84# Default Rust edition unless otherwise specified
85ifeq ($(MODULE_RUST_EDITION),)
86MODULE_RUST_EDITION := 2021
87endif
88
89MODULE_RUSTFLAGS += --edition $(MODULE_RUST_EDITION)
90
91# Specify paths of dependency libraries because we are not going through Cargo
92MODULE_RUSTFLAGS += $(addprefix --extern ,$(MODULE_RLIBS))
93
94MODULE_RUSTFLAGS_PRELINK := $(MODULE_RUSTFLAGS)
95MODULE_RUSTFLAGS += --emit link
96
97# Allow all lints if the module is in external/. This matches the behavior of
98# soong.
99ifneq ($(filter external/rust/%,$(MODULE_SRCS)),)
100MODULE_RUSTFLAGS += --cap-lints allow
101MODULE_RUSTDOCFLAGS += --cap-lints allow
102endif
103
104MODULE_RSOBJS :=
105
106# default to rlib-only if no crate types specified
107ifeq ($(strip $(MODULE_RUST_CRATE_TYPES)),)
108MODULE_RUST_CRATE_TYPES := rlib
109$(warn MODULE_RUST_CRATE_TYPES defaulting to rlib)
110endif
111
112ifneq ($(filter proc-macro,$(MODULE_RUST_CRATE_TYPES)),)
113MODULE_CRATE_OUTPUT := $(call TOBUILDDIR,lib$(MODULE_RUST_STEM).so)
114MODULE_RSOBJS += $(MODULE_CRATE_OUTPUT)
115$(MODULE_CRATE_OUTPUT): MODULE_RUSTFLAGS := $(MODULE_RUSTFLAGS) \
116	--crate-type=proc-macro --extern proc_macro -C prefer-dynamic
117MODULE_EXPORT_RLIBS += $(MODULE_CRATE_NAME)=$(MODULE_CRATE_OUTPUT)
118
119MODULE_RUSTDOCFLAGS += --crate-type=proc-macro --extern proc_macro
120endif # proc-macro crate
121
122ifneq ($(filter rlib,$(MODULE_RUST_CRATE_TYPES)),)
123MODULE_CRATE_OUTPUT := $(call TOBUILDDIR,lib$(MODULE_RUST_STEM).rlib)
124MODULE_RSOBJS += $(MODULE_CRATE_OUTPUT)
125$(MODULE_CRATE_OUTPUT): MODULE_RUSTFLAGS := $(MODULE_RUSTFLAGS) --crate-type=rlib
126MODULE_EXPORT_RLIBS += $(MODULE_CRATE_NAME)=$(MODULE_CRATE_OUTPUT)
127endif # rlib crate
128
129ifneq ($(filter staticlib,$(MODULE_RUST_CRATE_TYPES)),)
130MODULE_CRATE_OUTPUT := $(call TOBUILDDIR,lib$(MODULE_RUST_STEM).a)
131MODULE_RSOBJS += $(MODULE_CRATE_OUTPUT)
132$(MODULE_CRATE_OUTPUT): MODULE_RUSTFLAGS := $(MODULE_RUSTFLAGS) --crate-type=staticlib
133endif # staticlib crate
134
135ifneq ($(filter bin,$(MODULE_RUST_CRATE_TYPES)),)
136# Used in trusted_app.mk
137TRUSTY_APP_RUST_MAIN_SRC := $(filter %.rs,$(MODULE_SRCS))
138
139TRUSTY_APP_RUST_SRCDEPS := $(MODULE_SRCDEPS)
140endif
141
142ifeq ($(call TOBOOL,$(MODULE_SKIP_DOCS)),false)
143ifneq ($(TRUSTY_SDK_LIB_DIR),)
144MODULE_RUSTDOC_OBJECT := $(TRUSTY_SDK_LIB_DIR)/doc/built/$(MODULE_RUST_STEM)
145endif
146else
147MODULE_RUSTDOC_OBJECT :=
148endif
149
150MODULE_CRATE_OUTPUT :=
151
152ifeq ($(call TOBOOL,$(MODULE_RUST_HOST_LIB)),true)
153# Remove the target-specific flags
154$(MODULE_RSOBJS) $(MODULE_RUSTDOC_OBJECT): ARCH_RUSTFLAGS :=
155$(MODULE_RSOBJS) $(MODULE_RUSTDOC_OBJECT): GLOBAL_RUSTFLAGS := $(GLOBAL_HOST_RUSTFLAGS)
156else
157$(MODULE_RSOBJS) $(MODULE_RUSTDOC_OBJECT): ARCH_RUSTFLAGS := $(ARCH_$(ARCH)_RUSTFLAGS)
158$(MODULE_RSOBJS) $(MODULE_RUSTDOC_OBJECT): MODULE_RUST_ENV := $(MODULE_RUST_ENV)
159# Is module a kernel module? (not an app or using the library build system)
160ifeq ($(call TOBOOL,$(SAVED_MODULE_STACK)$(TRUSTY_NEW_MODULE_SYSTEM)$(TRUSTY_APP)),false)
161$(MODULE_RSOBJS) $(MODULE_RUSTDOC_OBJECT): GLOBAL_RUSTFLAGS := $(GLOBAL_SHARED_RUSTFLAGS) $(GLOBAL_KERNEL_RUSTFLAGS)
162else
163$(MODULE_RSOBJS) $(MODULE_RUSTDOC_OBJECT): GLOBAL_RUSTFLAGS := $(GLOBAL_SHARED_RUSTFLAGS) $(GLOBAL_USER_RUSTFLAGS)
164endif
165endif
166
167$(MODULE_RSOBJS): MODULE_CRATE_NAME := $(MODULE_CRATE_NAME)
168$(MODULE_RSOBJS): MODULE_RUST_STEM := $(MODULE_RUST_STEM)
169
170$(MODULE_RUSTDOC_OBJECT): RUSTDOC := $(RUST_BINDIR)/rustdoc
171$(MODULE_RUSTDOC_OBJECT): MODULE_RUSTDOC_OUT_DIR := $(TRUSTY_SDK_LIB_DIR)/doc
172$(MODULE_RUSTDOC_OBJECT): MODULE_RUSTDOCFLAGS := $(MODULE_RUSTDOCFLAGS)
173$(MODULE_RUSTDOC_OBJECT): MODULE_RUSTFLAGS_PRELINK := $(MODULE_RUSTFLAGS_PRELINK)
174$(MODULE_RUSTDOC_OBJECT): MODULE_CRATE_NAME := $(MODULE_CRATE_NAME)
175