1#
2# Copyright (c) 2014-2018, 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#
25# Input variables
26#
27#   ALLHOSTMODULES             - list of all host modules (e.g. Rust proc-macros) to be built
28#   TRUSTY_BUILTIN_USER_TASKS  - list of compiled from source user tasks to be included into final image
29#   TRUSTY_PREBUILT_USER_TASKS - list of precompiled user tasks to be included into final image
30#   	These prebuilt task modules must include a manifest binary and app elf binary, e.g.:
31#   		TRUSTY_PREBUILT_USER_TASKS += trusty/app/some_prebuilt_app
32#
33#			Add the following files from the pre-compiled app:
34#			- trusty/app/some_prebuilt_app/some_prebuilt_app.elf
35#			- trusty/app/some_prebuilt_app/some_prebuilt_app.manifest
36#	TRUSTY_BUILTIN_USER_TESTS - list of user test to include in the final image.
37#                               These tests must also be included in
38#                               TRUSTY_USER_TESTS or TRUSTY_RUST_USER_TESTS to
39#                               be built. If not set, defaults to including all
40#                               built tests in the image. Projects may set this
41#                               variable to a subset of the available tests, but
42#                               this should be done with the ?= assignment to
43#                               still allow overriding via environment variable.
44#
45
46$(call INFO_LOG,Include Trusty user tasks support)
47
48TRUSTY_APP_DIR := $(GET_LOCAL_DIR)
49
50# generate trusty app or library build rules:
51# $(1): path to app source dir (module name)
52#
53# Note: this function must be eval'd after calling it
54#
55# Other input variables, shared across all apps
56# TRUSTY_APP_BASE_LDFLAGS: LDFLAGS for the app
57# ARCH: Architecture of the app
58# TRUSTY_APP_ALIGNMENT: Alignment of app image (defaults to 1)
59# TRUSTY_APP_MEMBASE: App base address, if fixed
60# TRUSTY_APP_SYMTAB_ENABLED: If true do not strip symbols from the
61# 		resulting app binary
62# TRUSTY_USERSPACE: Boolean indicating that the app should be built for the
63# 		trusty userspace
64#
65define trusty-build-rule
66# MODULE should be set to the parent module when including userspace_recurse.mk.
67# In this case we are trying to build a top-level app or library, and need to
68# isolate this build from the kernel build. In order to isolate the top level
69# library (or app) module from the kernel build system, we save the kernel
70# module flags (to a synthetic parent module, KERNEL), clear those flags, then
71# include the library via DEPENDENCY_MODULE. After finishing with the rules for
72# the library, we will restore the kernel flags from their saved values.
73DEPENDENCY_MODULE := $(1)
74MODULE := KERNEL
75include make/userspace_recurse.mk
76endef
77
78# Strip out flags not applicable to SDK
79define prepare-sdk-flags
80$(patsubst -fsanitize-blacklist=%,,\
81	$(patsubst -include $(BUILDDIR)/config.h,,$(1)))
82endef
83
84TRUSTY_TOP_LEVEL_BUILDDIR := $(BUILDDIR)
85TRUSTY_APP_BUILDDIR := $(BUILDDIR)/user_tasks
86TRUSTY_SDK_DIR := $(BUILDDIR)/sdk
87TRUSTY_SDK_SYSROOT := $(TRUSTY_SDK_DIR)/sysroot/
88TRUSTY_SDK_INCLUDE_DIR := $(TRUSTY_SDK_SYSROOT)/usr/include
89TRUSTY_SDK_LIB_DIR := $(TRUSTY_SDK_SYSROOT)/usr/lib
90TRUSTY_SDK_LICENSE_DIR := $(TRUSTY_SDK_DIR)/licenses
91TRUSTY_SDK_LICENSE := $(TRUSTY_SDK_DIR)/LICENSE
92TRUSTY_LIBRARY_BUILDDIR := $(BUILDDIR)/lib
93
94GLOBAL_CRATE_COUNT := 0
95RUST_ANALYZER_CONTENTS :=
96
97# Host modules required by userspace are built in passing as needed, as the
98# userspace build system respects MODULE_RUST_HOST_LIB. But the kernel may also
99# need some host modules, e.g. for proc-macro crates. So we explicitly iterate
100# over the set of host modules required by the kernel, generating their build
101# rules with the userspace build system.
102$(foreach lib,$(ALLHOSTMODULES),\
103	$(eval $(call trusty-build-rule,$(lib))))
104
105
106# The license file construction assumes that all projects will contain the same
107# set of SDK modules and thus the same set of respective license files. If this
108# ever changes, SDK zip construction in build.py will need to be adjusted to
109# account for differing licenses across projects.
110TRUSTY_SDK_MODULES := \
111	external/boringssl \
112	trusty/kernel/lib/libc-ext \
113	trusty/kernel/lib/ubsan \
114	trusty/user/base/interface/hwaes \
115	trusty/user/base/interface/hwkey \
116	trusty/user/base/interface/keymaster \
117	trusty/user/base/interface/spi \
118	trusty/user/base/interface/storage \
119	trusty/user/base/interface/system_state \
120	trusty/user/base/lib/dlmalloc \
121	trusty/user/base/lib/googletest \
122	trusty/user/base/lib/hwaes \
123	trusty/user/base/lib/hwbcc/rust \
124	trusty/user/base/lib/hwkey \
125	trusty/user/base/lib/hwkey/rust \
126	trusty/user/base/lib/keymaster \
127	trusty/user/base/lib/libc-trusty \
128	trusty/user/base/lib/libcxxabi-trusty \
129	trusty/user/base/lib/libstdc++-trusty \
130	trusty/user/base/lib/line-coverage \
131	trusty/user/base/lib/rng \
132	trusty/user/base/lib/spi/client \
133	trusty/user/base/lib/spi/common \
134	trusty/user/base/lib/storage \
135	trusty/user/base/lib/syscall-stubs \
136	trusty/user/base/lib/system_state \
137	trusty/user/base/lib/system_state/rust \
138	trusty/user/base/lib/tipc \
139	trusty/user/base/lib/tipc/rust \
140	trusty/user/base/lib/unittest \
141	trusty/user/base/lib/unittest-rust \
142
143# scudo does not build on 32-bit yet
144ifeq (false,$(call TOBOOL,$(KERNEL_32BIT)))
145ifeq (false,$(call TOBOOL,$(USER_32BIT)))
146TRUSTY_SDK_MODULES += trusty/user/base/lib/scudo
147endif
148endif
149
150TRUSTY_SDK_MODULES += $(EXTRA_TRUSTY_SDK_MODULES)
151
152ALL_SDK_EXTRA_FILES :=
153ALL_SDK_INCLUDES :=
154ALL_SDK_LIBS :=
155ALL_SDK_LICENSES :=
156
157define TOSDKLIBNAME
158$(patsubst lib%,%,$(notdir $(1)))
159endef
160
161GLOBAL_USER_RUSTFLAGS += -L dependency=$(TRUSTY_LIBRARY_BUILDDIR)
162
163# We need the host library dir to pick up recursive dependencies that are proc
164# macros and therefore built in the host build dir.
165GLOBAL_USER_RUSTFLAGS += -L dependency=$(TRUSTY_HOST_LIBRARY_BUILDDIR)
166
167# Save userspace-global variables so we can restore kernel state
168TRUSTY_KERNEL_SAVED_ARCH := $(ARCH)
169TRUSTY_KERNEL_SAVED_ALLOW_FP_USE := $(ALLOW_FP_USE)
170TRUSTY_KERNEL_SAVED_SCS_ENABLED := $(SCS_ENABLED)
171
172# while compiling user space we allow FP support
173ALLOW_FP_USE := true
174
175# tell the arch-specific makefiles to set flags required for SCS if supported
176SCS_ENABLED := $(call TOBOOL,$(USER_SCS_ENABLED))
177
178# Building trusty userspace
179TRUSTY_USERSPACE := true
180
181# Used by LTO, could be combined with TRUSTY_USERSPACE after this lands
182USER_TASK_MODULE := true
183
184ARCH := $(TRUSTY_USER_ARCH)
185# Re-derive the standard arch name using the new arch.
186$(eval $(call standard_name_for_arch,STANDARD_ARCH_NAME,$(ARCH),$(SUBARCH)))
187
188# Override tools for the userspace arch
189include arch/$(ARCH)/toolchain.mk
190
191include $(TRUSTY_APP_DIR)/arch/$(TRUSTY_USER_ARCH)/rules.mk
192
193# generate list of all user tasks we need to build
194# include the legacy TRUSTY_ALL_USER_TASKS variable for projects that still use
195# it. This will be removed in the future and all projects should use
196# TRUSTY_BUILTIN_USER_TASKS directly.
197TRUSTY_BUILTIN_USER_TASKS := $(TRUSTY_BUILTIN_USER_TASKS) \
198                             $(TRUSTY_ALL_USER_TASKS) \
199
200
201# Rust crate tests have a -test suffix to their module name to distinguish from
202# the crate itself with the same path.
203ifeq ($(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_RUST)),true)
204RUST_USER_TEST_MODULES := $(addsuffix -test,$(TRUSTY_RUST_USER_TESTS))
205endif
206
207ifneq (true,$(call TOBOOL,$(UNITTEST_COVERAGE_ENABLED)))
208# Default to including all user tests in the image if the set of builtin tests
209# is not selected.
210TRUSTY_BUILTIN_USER_TESTS ?= $(TRUSTY_USER_TESTS) $(RUST_USER_TEST_MODULES)
211TRUSTY_BUILTIN_USER_TASKS += $(TRUSTY_BUILTIN_USER_TESTS)
212endif
213
214# remove duplicates
215TRUSTY_BUILTIN_USER_TASKS := $(sort $(TRUSTY_BUILTIN_USER_TASKS))
216
217ALL_USER_TASKS := $(TRUSTY_BUILTIN_USER_TASKS) $(TRUSTY_LOADABLE_USER_TASKS)  \
218		  $(TRUSTY_USER_TESTS) $(TRUSTY_LOADABLE_USER_TESTS) $(TRUSTY_RUST_USER_TESTS)
219
220# sort and remove duplicates
221ALL_USER_TASKS := $(sort $(ALL_USER_TASKS))
222
223# TODO: we could find the runtime like this.
224# TRUSTY_APP_LIBGCC := $(shell $(CC) $(GLOBAL_COMPILEFLAGS) $(ARCH_$(ARCH)_COMPILEFLAGS) $(THUMBCFLAGS) --rtlib=compiler-rt -print-libgcc-file-name)
225# However the compiler currently does not contain non-x86 prebuilts for the
226# linux-gnu ABI. We could either get those prebuilts added to the toolchain or
227# switch to the android ABI.
228# Note there are two copies of compiler-rt in the toolchain - framework and NDK.
229# We're using the NDK version because the path is more stable and the difference
230# should not matter for this library. (The main difference is which version of
231# libcxx they link against, and the builtins do not use C++.)
232TRUSTY_APP_LIBGCC := $(CLANG_BINDIR)/../runtimes_ndk_cxx/libclang_rt.builtins-$(STANDARD_ARCH_NAME)-android.a
233ifeq (true,$(call TOBOOL,$(UNITTEST_COVERAGE_ENABLED)))
234TRUSTY_APP_LIBCOV := -u__llvm_profile_runtime $(CLANG_BINDIR)/../runtimes_ndk_cxx/libclang_rt.profile-aarch64-android.a
235endif
236
237TRUSTY_APP_BASE_LDFLAGS := $(GLOBAL_SHARED_LDFLAGS) -z max-page-size=4096 -z separate-loadable-segments
238TRUSTY_APP_ALIGNMENT := 4096
239TRUSTY_APP_MEMBASE :=
240TRUSTY_APP_SYMTAB_ENABLED := $(SYMTAB_ENABLED)
241
242$(info ALL_USER_TASKS: $(ALL_USER_TASKS))
243
244# GLOBAL_CPPFLAGS comes before GLOBAL_INCLUDES on the compile command-line. This
245# is important because we need libcxx's math.h to be picked up before musl's
246# when building C++.
247GLOBAL_USER_IN_TREE_CPPFLAGS += -I$(TRUSTY_SDK_INCLUDE_DIR)/c++/v1
248GLOBAL_USER_IN_TREE_COMPILEFLAGS += \
249	--sysroot=$(TRUSTY_SDK_SYSROOT) \
250	-isystem $(TRUSTY_SDK_INCLUDE_DIR) \
251	-D_LIBCPP_HAS_THREAD_API_PTHREAD \
252
253TRUSTY_APP_BASE_LDFLAGS += -L$(TRUSTY_SDK_LIB_DIR)
254
255# Generate build rules for each sdk library, if they have not already been
256# generated.
257#
258# Rules are the first time a library is required, so libraries may already be
259# processed before we get to them in the list of SDK libraries.
260#
261$(call INFO_LOG,Generate build rules for SDK libraries)
262
263$(foreach lib,$(TRUSTY_SDK_MODULES),\
264	$(if $(_MODULES_$(lib)),,$(eval $(call trusty-build-rule,$(lib)))))
265
266ALL_SDK_LICENSES :=
267$(foreach lib,$(TRUSTY_SDK_MODULES),\
268	$(eval ALL_SDK_LICENSES += $(_MODULES_$(lib)_LICENSES)))
269
270$(TRUSTY_SDK_LICENSE): $(ALL_SDK_LICENSES)
271	@$(MKDIR)
272	@echo Generating SDK license
273	$(NOECHO)rm -f $@.tmp
274	$(NOECHO)cat trusty/user/base/sdk/LICENSE >> $@.tmp;
275	$(NOECHO)for license in $^; do \
276		printf "\n-------------------------------------------------------------------\n" >> $@.tmp;\
277		printf "Copied from $$license\n\n\n" >> $@.tmp;\
278		cat "$$license" >> $@.tmp;\
279		done
280	$(call TESTANDREPLACEFILE,$@.tmp,$@)
281
282#
283# Generate build rules for each user task
284#
285$(call INFO_LOG,Generate build rules for user tasks)
286
287$(foreach t,$(ALL_USER_TASKS),\
288   $(eval $(call trusty-build-rule,$(t))))
289
290# Add any prebuilt apps to the build.
291
292PREBUILT_OBJECTS := $(foreach t,$(TRUSTY_PREBUILT_USER_TASKS),\
293	$(t)/$(notdir $(t)).manifest $(t)/$(notdir $(t)).elf)
294PREBUILT_OBJECTS_DEST := $(addprefix $(BUILDDIR)/user_tasks/,$(PREBUILT_OBJECTS))
295$(PREBUILT_OBJECTS_DEST): $(BUILDDIR)/user_tasks/%: %
296	$(MKDIR)
297	cp $^ $(dir $@)/
298
299define prebuilt-app-build-rule
300$(eval _MODULES_$(1)_TRUSTY_APP_MANIFEST_BIN := $(1)/$(notdir $(1)).manifest)\
301$(eval _MODULES_$(1)_TRUSTY_APP_ELF := $(1)/$(notdir $(1)).elf)
302endef
303
304# Set up global variables describing each prebuilt app
305$(foreach t,$(TRUSTY_PREBUILT_USER_TASKS),\
306	$(call prebuilt-app-build-rule,$(t)))
307
308TRUSTY_BUILTIN_USER_TASKS += $(TRUSTY_PREBUILT_USER_TASKS)
309
310# Build the SDK makefile
311$(call INFO_LOG,Build SDK makefile)
312$(eval $(call trusty-build-rule,trusty/user/base/sdk))
313
314# Ensure that includes and libs are installed
315all:: $(ALL_SDK_INCLUDES) $(ALL_SDK_LIBS) $(ALL_SDK_EXTRA_FILES) $(TRUSTY_SDK_LICENSE)
316
317ifeq (false,$(call TOBOOL,$(TRUSTY_APPLOADER_ENABLED)))
318
319ifneq ($(strip $(TRUSTY_LOADABLE_USER_TASKS) $(TRUSTY_LOADABLE_USER_TESTS)),)
320$(error Loadable apps ($(TRUSTY_LOADABLE_USER_TASKS) $(TRUSTY_LOADABLE_USER_TESTS)) requested but this build does not include the apploader service)
321endif
322
323else # TRUSTY_APPLOADER_ENABLED
324
325#
326# Generate loadable application packages
327#
328$(call INFO_LOG,Generate loadable application packages)
329define loadable-app-build-rule
330$(eval APP_NAME := $(notdir $(1)))\
331$(eval APP_TOP_MODULE := $(1))\
332$(eval APP_BUILDDIR := $(BUILDDIR)/user_tasks/$(1))\
333$(eval include make/loadable_app.mk)
334endef
335
336# Sort and remove duplicates
337TRUSTY_LOADABLE_USER_TASKS := $(sort $(TRUSTY_LOADABLE_USER_TASKS))
338
339#
340# Generate build rules for each application
341#
342$(call INFO_LOG,Generate loadable apps build rules)
343$(foreach t,$(TRUSTY_LOADABLE_USER_TASKS),\
344   $(call loadable-app-build-rule,$(t)))
345
346# Clear the list of loadable apps
347LOADABLE_APP_LIST :=
348
349# Sort and remove duplicates
350TRUSTY_USER_TESTS := $(sort \
351                       $(TRUSTY_USER_TESTS) \
352                       $(TRUSTY_LOADABLE_USER_TESTS) \
353                       $(RUST_USER_TEST_MODULES) \
354                     )
355
356#
357# Generate build rules for test application
358#
359$(call INFO_LOG,Generate test apps build rules)
360$(foreach t,$(TRUSTY_USER_TESTS),\
361   $(call loadable-app-build-rule,$(t)))
362
363# At this point LOADABLE_APP_LIST only contains user tests
364TRUSTY_LOADABLE_TEST_APPS := $(LOADABLE_APP_LIST)
365
366ifneq ($(strip $(TRUSTY_LOADABLE_TEST_APPS)),)
367
368TEST_PACKAGE_ZIP ?= $(BUILDDIR)/trusty_test_package.zip
369TEST_PACKAGE_ZIP_ARGS ?= -q -u -r
370
371$(TEST_PACKAGE_ZIP): BUILDDIR := $(BUILDDIR)
372$(TEST_PACKAGE_ZIP_ARGS): TEST_PACKAGE_ZIP_ARGS := $(TEST_PACKAGE_ZIP_ARGS)
373$(TEST_PACKAGE_ZIP): $(TRUSTY_LOADABLE_TEST_APPS)
374	@$(MKDIR)
375	@$(call ECHO,KERNEL,creating Trusty test archive package,$^)
376	$(NOECHO)rm -f $@
377	$(NOECHO)(cd $(BUILDDIR) && zip $(TEST_PACKAGE_ZIP_ARGS)  $@ $(subst $(BUILDDIR)/,,$^))
378	@$(call ECHO_DONE_SILENT,KERNEL,creating Trusty test archive package,$^)
379
380EXTRA_BUILDDEPS += $(TEST_PACKAGE_ZIP)
381
382endif
383
384endif # TRUSTY_APPLOADER_ENABLED
385
386include make/rust-project-json.mk
387
388
389# Restore kernel state
390ARCH := $(TRUSTY_KERNEL_SAVED_ARCH)
391ALLOW_FP_USE := $(TRUSTY_KERNEL_SAVED_ALLOW_FP_USE)
392SCS_ENABLED := $(TRUSTY_KERNEL_SAVED_SCS_ENABLED)
393
394#
395# Generate combined user task obj/bin if necessary
396#
397ifneq ($(strip $(TRUSTY_BUILTIN_USER_TASKS)),)
398
399BUILTIN_TASK_MANIFESTS_BINARY := $(foreach t, $(TRUSTY_BUILTIN_USER_TASKS),\
400   $(_MODULES_$(t)_TRUSTY_APP_MANIFEST_BIN))
401
402BUILTIN_TASK_ELFS := $(foreach t, $(TRUSTY_BUILTIN_USER_TASKS),\
403   $(_MODULES_$(t)_TRUSTY_APP_ELF))
404
405BUILTIN_TASK_OBJS := $(patsubst %.elf,%.o,$(BUILTIN_TASK_ELFS))
406
407$(BUILTIN_TASK_OBJS): CC := $(CC)
408$(BUILTIN_TASK_OBJS): GLOBAL_COMPILEFLAGS := $(GLOBAL_COMPILEFLAGS)
409$(BUILTIN_TASK_OBJS): ARCH_COMPILEFLAGS := $(ARCH_$(ARCH)_COMPILEFLAGS)
410$(BUILTIN_TASK_OBJS): USER_TASK_OBJ_ASM:=$(TRUSTY_APP_DIR)/appobj.S
411$(BUILTIN_TASK_OBJS): LOG_NAME:=$(TRUSTY_APP_DIR)
412$(BUILTIN_TASK_OBJS): %.o: %.elf %.manifest $(USER_TASK_OBJ_ASM)
413	@$(MKDIR)
414	@$(call ECHO,$(LOG_NAME),converting,$< to $@)
415	$(NOECHO)$(CC) -DUSER_TASK_ELF=\"$<\" -DMANIFEST_DATA=\"$(word 2,$^)\" $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) -c $(USER_TASK_OBJ_ASM) -o $@
416	@$(call ECHO_DONE_SILENT,$(LOG_NAME),converting,$< to $@)
417
418EXTRA_OBJS += $(BUILTIN_TASK_OBJS)
419
420endif
421
422# Reset app variables
423BUILDDIR := $(TRUSTY_TOP_LEVEL_BUILDDIR)
424TRUSTY_APP :=
425TRUSTY_APP_NAME :=
426TRUSTY_APP_BASE_LDFLAGS :=
427TRUSTY_APP_ARCH :=
428TRUSTY_APP_ALIGNMENT :=
429TRUSTY_APP_MEMBASE :=
430TRUSTY_APP_SYMTAB_ENABLED :=
431TRUSTY_APPLOADER_ENABLED :=
432TRUSTY_TOP_LEVEL_BUILDDIR :=
433TRUSTY_USERSPACE :=
434TRUSTY_USERSPACE_SAVED_ARCH :=
435TRUSTY_USERSPACE_SAVED_ALLOW_FP_USE :=
436TRUSTY_USERSPACE_SAVED_SCS_ENABLED :=
437USER_TASK_MODULE :=
438LOADABLE_APP_LIST :=
439TRUSTY_LOADABLE_USER_TASKS :=
440TEST_PACKAGE_ZIP :=
441RUST_PROJECT_JSON :=
442RUST_PROJECT_JSON_CONTENTS :=
443RUST_USER_TEST_MODULES :=
444RUST_ANALYZER_CONTENTS :=
445GLOBAL_CRATE_COUNT :=
446