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 external/open-dice \ 113 trusty/kernel/lib/libc-ext \ 114 trusty/kernel/lib/ubsan \ 115 trusty/user/base/interface/hwaes \ 116 trusty/user/base/interface/hwbcc \ 117 trusty/user/base/interface/hwkey \ 118 trusty/user/base/interface/keybox \ 119 trusty/user/base/interface/keymaster \ 120 trusty/user/base/interface/spi \ 121 trusty/user/base/interface/storage \ 122 trusty/user/base/interface/system_state \ 123 trusty/user/base/lib/dlmalloc \ 124 trusty/user/base/lib/googletest \ 125 trusty/user/base/lib/hwaes \ 126 trusty/user/base/lib/hwbcc/client \ 127 trusty/user/base/lib/hwbcc/rust \ 128 trusty/user/base/lib/hwkey \ 129 trusty/user/base/lib/hwkey/rust \ 130 trusty/user/base/lib/keybox/client \ 131 trusty/user/base/lib/keymaster \ 132 trusty/user/base/lib/libc-trusty \ 133 trusty/user/base/lib/libcxxabi-trusty \ 134 trusty/user/base/lib/libstdc++-trusty \ 135 trusty/user/base/lib/line-coverage \ 136 trusty/user/base/lib/rng \ 137 trusty/user/base/lib/spi/client \ 138 trusty/user/base/lib/spi/common \ 139 trusty/user/base/lib/storage \ 140 trusty/user/base/lib/syscall-stubs \ 141 trusty/user/base/lib/system_state \ 142 trusty/user/base/lib/system_state/rust \ 143 trusty/user/base/lib/tipc \ 144 trusty/user/base/lib/tipc/rust \ 145 trusty/user/base/lib/unittest \ 146 trusty/user/base/lib/unittest-rust \ 147 148# scudo does not build on 32-bit yet 149ifeq (false,$(call TOBOOL,$(KERNEL_32BIT))) 150ifeq (false,$(call TOBOOL,$(USER_32BIT))) 151TRUSTY_SDK_MODULES += trusty/user/base/lib/scudo 152endif 153endif 154 155TRUSTY_SDK_MODULES += $(EXTRA_TRUSTY_SDK_MODULES) 156 157ALL_SDK_EXTRA_FILES := 158ALL_SDK_INCLUDES := 159ALL_SDK_LIBS := 160ALL_SDK_LICENSES := 161 162define TOSDKLIBNAME 163$(patsubst lib%,%,$(notdir $(1))) 164endef 165 166GLOBAL_USER_RUSTFLAGS += -L dependency=$(TRUSTY_LIBRARY_BUILDDIR) 167 168# We need the host library dir to pick up recursive dependencies that are proc 169# macros and therefore built in the host build dir. 170GLOBAL_USER_RUSTFLAGS += -L dependency=$(TRUSTY_HOST_LIBRARY_BUILDDIR) 171 172# Save userspace-global variables so we can restore kernel state 173TRUSTY_KERNEL_SAVED_ARCH := $(ARCH) 174TRUSTY_KERNEL_SAVED_ALLOW_FP_USE := $(ALLOW_FP_USE) 175TRUSTY_KERNEL_SAVED_SCS_ENABLED := $(SCS_ENABLED) 176 177# while compiling user space we allow FP support 178ALLOW_FP_USE := true 179 180# tell the arch-specific makefiles to set flags required for SCS if supported 181SCS_ENABLED := $(call TOBOOL,$(USER_SCS_ENABLED)) 182 183# Building trusty userspace 184TRUSTY_USERSPACE := true 185 186# Used by LTO, could be combined with TRUSTY_USERSPACE after this lands 187USER_TASK_MODULE := true 188 189ARCH := $(TRUSTY_USER_ARCH) 190# Re-derive the standard arch name using the new arch. 191$(eval $(call standard_name_for_arch,STANDARD_ARCH_NAME,$(ARCH),$(SUBARCH))) 192 193# Override tools for the userspace arch 194include arch/$(ARCH)/toolchain.mk 195 196include $(TRUSTY_APP_DIR)/arch/$(TRUSTY_USER_ARCH)/rules.mk 197 198# generate list of all user tasks we need to build 199# include the legacy TRUSTY_ALL_USER_TASKS variable for projects that still use 200# it. This will be removed in the future and all projects should use 201# TRUSTY_BUILTIN_USER_TASKS directly. 202TRUSTY_BUILTIN_USER_TASKS := $(TRUSTY_BUILTIN_USER_TASKS) \ 203 $(TRUSTY_ALL_USER_TASKS) \ 204 205 206# Rust crate tests have a -test suffix to their module name to distinguish from 207# the crate itself with the same path. 208ifeq ($(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_RUST)),true) 209RUST_USER_TEST_MODULES := $(addsuffix -test,$(TRUSTY_RUST_USER_TESTS)) 210endif 211 212ifneq (true,$(call TOBOOL,$(UNITTEST_COVERAGE_ENABLED))) 213# Default to including all user tests in the image if the set of builtin tests 214# is not selected. 215TRUSTY_BUILTIN_USER_TESTS ?= $(TRUSTY_USER_TESTS) $(RUST_USER_TEST_MODULES) 216TRUSTY_BUILTIN_USER_TASKS += $(TRUSTY_BUILTIN_USER_TESTS) 217endif 218 219# remove duplicates 220TRUSTY_BUILTIN_USER_TASKS := $(sort $(TRUSTY_BUILTIN_USER_TASKS)) 221 222ALL_USER_TASKS := $(TRUSTY_BUILTIN_USER_TASKS) $(TRUSTY_LOADABLE_USER_TASKS) \ 223 $(TRUSTY_USER_TESTS) $(TRUSTY_LOADABLE_USER_TESTS) $(TRUSTY_RUST_USER_TESTS) 224 225# sort and remove duplicates 226ALL_USER_TASKS := $(sort $(ALL_USER_TASKS)) 227 228# TODO: we could find the runtime like this. 229# TRUSTY_APP_LIBGCC := $(shell $(CC) $(GLOBAL_COMPILEFLAGS) $(ARCH_$(ARCH)_COMPILEFLAGS) $(THUMBCFLAGS) --rtlib=compiler-rt -print-libgcc-file-name) 230# However the compiler currently does not contain non-x86 prebuilts for the 231# linux-gnu ABI. We could either get those prebuilts added to the toolchain or 232# switch to the android ABI. 233# Note there are two copies of compiler-rt in the toolchain - framework and NDK. 234# We're using the NDK version because the path is more stable and the difference 235# should not matter for this library. (The main difference is which version of 236# libcxx they link against, and the builtins do not use C++.) 237TRUSTY_APP_LIBGCC := $(CLANG_BINDIR)/../runtimes_ndk_cxx/libclang_rt.builtins-$(STANDARD_ARCH_NAME)-android.a 238ifeq (true,$(call TOBOOL,$(UNITTEST_COVERAGE_ENABLED))) 239TRUSTY_APP_LIBCOV := -u__llvm_profile_runtime $(CLANG_BINDIR)/../runtimes_ndk_cxx/libclang_rt.profile-aarch64-android.a 240endif 241 242TRUSTY_APP_BASE_LDFLAGS := $(GLOBAL_SHARED_LDFLAGS) -z max-page-size=4096 -z separate-loadable-segments 243TRUSTY_APP_ALIGNMENT := 4096 244TRUSTY_APP_MEMBASE := 245TRUSTY_APP_SYMTAB_ENABLED := $(SYMTAB_ENABLED) 246 247$(info ALL_USER_TASKS: $(ALL_USER_TASKS)) 248 249# GLOBAL_CPPFLAGS comes before GLOBAL_INCLUDES on the compile command-line. This 250# is important because we need libcxx's math.h to be picked up before musl's 251# when building C++. 252GLOBAL_USER_IN_TREE_CPPFLAGS += -I$(TRUSTY_SDK_INCLUDE_DIR)/c++/v1 253GLOBAL_USER_IN_TREE_COMPILEFLAGS += \ 254 --sysroot=$(TRUSTY_SDK_SYSROOT) \ 255 -isystem $(TRUSTY_SDK_INCLUDE_DIR) \ 256 -D_LIBCPP_HAS_THREAD_API_PTHREAD \ 257 258TRUSTY_APP_BASE_LDFLAGS += -L$(TRUSTY_SDK_LIB_DIR) 259 260# Generate build rules for each sdk library, if they have not already been 261# generated. 262# 263# Rules are the first time a library is required, so libraries may already be 264# processed before we get to them in the list of SDK libraries. 265# 266$(call INFO_LOG,Generate build rules for SDK libraries) 267 268$(foreach lib,$(TRUSTY_SDK_MODULES),\ 269 $(if $(_MODULES_$(lib)),,$(eval $(call trusty-build-rule,$(lib))))) 270 271ALL_SDK_LICENSES := 272$(foreach lib,$(TRUSTY_SDK_MODULES),\ 273 $(eval ALL_SDK_LICENSES += $(_MODULES_$(lib)_LICENSES))) 274 275$(TRUSTY_SDK_LICENSE): $(ALL_SDK_LICENSES) 276 @$(MKDIR) 277 @echo Generating SDK license 278 $(NOECHO)rm -f $@.tmp 279 $(NOECHO)cat trusty/user/base/sdk/LICENSE >> $@.tmp; 280 $(NOECHO)for license in $^; do \ 281 printf "\n-------------------------------------------------------------------\n" >> $@.tmp;\ 282 printf "Copied from $$license\n\n\n" >> $@.tmp;\ 283 cat "$$license" >> $@.tmp;\ 284 done 285 $(call TESTANDREPLACEFILE,$@.tmp,$@) 286 287# 288# Generate build rules for each user task 289# 290$(call INFO_LOG,Generate build rules for user tasks) 291 292$(foreach t,$(ALL_USER_TASKS),\ 293 $(eval $(call trusty-build-rule,$(t)))) 294 295# Add any prebuilt apps to the build. 296 297PREBUILT_OBJECTS := $(foreach t,$(TRUSTY_PREBUILT_USER_TASKS),\ 298 $(t)/$(notdir $(t)).manifest $(t)/$(notdir $(t)).elf) 299PREBUILT_OBJECTS_DEST := $(addprefix $(BUILDDIR)/user_tasks/,$(PREBUILT_OBJECTS)) 300$(PREBUILT_OBJECTS_DEST): $(BUILDDIR)/user_tasks/%: % 301 $(MKDIR) 302 cp $^ $(dir $@)/ 303 304define prebuilt-app-build-rule 305$(eval _MODULES_$(1)_TRUSTY_APP_MANIFEST_BIN := $(1)/$(notdir $(1)).manifest)\ 306$(eval _MODULES_$(1)_TRUSTY_APP_ELF := $(1)/$(notdir $(1)).elf) 307endef 308 309# Set up global variables describing each prebuilt app 310$(foreach t,$(TRUSTY_PREBUILT_USER_TASKS),\ 311 $(call prebuilt-app-build-rule,$(t))) 312 313TRUSTY_BUILTIN_USER_TASKS += $(TRUSTY_PREBUILT_USER_TASKS) 314 315# Build the SDK makefile 316$(call INFO_LOG,Build SDK makefile) 317$(eval $(call trusty-build-rule,trusty/user/base/sdk)) 318 319# Ensure that includes and libs are installed 320all:: $(ALL_SDK_INCLUDES) $(ALL_SDK_LIBS) $(ALL_SDK_EXTRA_FILES) $(TRUSTY_SDK_LICENSE) 321 322ifeq (false,$(call TOBOOL,$(TRUSTY_APPLOADER_ENABLED))) 323 324ifneq ($(strip $(TRUSTY_LOADABLE_USER_TASKS) $(TRUSTY_LOADABLE_USER_TESTS)),) 325$(error Loadable apps ($(TRUSTY_LOADABLE_USER_TASKS) $(TRUSTY_LOADABLE_USER_TESTS)) requested but this build does not include the apploader service) 326endif 327 328else # TRUSTY_APPLOADER_ENABLED 329 330# 331# Generate loadable application packages 332# 333$(call INFO_LOG,Generate loadable application packages) 334define loadable-app-build-rule 335$(eval APP_NAME := $(notdir $(1)))\ 336$(eval APP_TOP_MODULE := $(1))\ 337$(eval APP_BUILDDIR := $(BUILDDIR)/user_tasks/$(1))\ 338$(eval include make/loadable_app.mk) 339endef 340 341# Sort and remove duplicates 342TRUSTY_LOADABLE_USER_TASKS := $(sort $(TRUSTY_LOADABLE_USER_TASKS)) 343 344# 345# Generate build rules for each application 346# 347$(call INFO_LOG,Generate loadable apps build rules) 348$(foreach t,$(TRUSTY_LOADABLE_USER_TASKS),\ 349 $(call loadable-app-build-rule,$(t))) 350 351# Clear the list of loadable apps 352LOADABLE_APP_LIST := 353 354# Sort and remove duplicates 355TRUSTY_USER_TESTS := $(sort \ 356 $(TRUSTY_USER_TESTS) \ 357 $(TRUSTY_LOADABLE_USER_TESTS) \ 358 $(RUST_USER_TEST_MODULES) \ 359 ) 360 361# 362# Generate build rules for test application 363# 364$(call INFO_LOG,Generate test apps build rules) 365$(foreach t,$(TRUSTY_USER_TESTS),\ 366 $(call loadable-app-build-rule,$(t))) 367 368# At this point LOADABLE_APP_LIST only contains user tests 369TRUSTY_LOADABLE_TEST_APPS := $(LOADABLE_APP_LIST) 370 371ifneq ($(strip $(TRUSTY_LOADABLE_TEST_APPS)),) 372 373TEST_PACKAGE_ZIP ?= $(BUILDDIR)/trusty_test_package.zip 374TEST_PACKAGE_ZIP_ARGS ?= -q -u -r 375 376$(TEST_PACKAGE_ZIP): BUILDDIR := $(BUILDDIR) 377$(TEST_PACKAGE_ZIP_ARGS): TEST_PACKAGE_ZIP_ARGS := $(TEST_PACKAGE_ZIP_ARGS) 378$(TEST_PACKAGE_ZIP): $(TRUSTY_LOADABLE_TEST_APPS) 379 @$(MKDIR) 380 @$(call ECHO,KERNEL,creating Trusty test archive package,$^) 381 $(NOECHO)rm -f $@ 382 $(NOECHO)(cd $(BUILDDIR) && zip $(TEST_PACKAGE_ZIP_ARGS) $@ $(subst $(BUILDDIR)/,,$^)) 383 @$(call ECHO_DONE_SILENT,KERNEL,creating Trusty test archive package,$^) 384 385EXTRA_BUILDDEPS += $(TEST_PACKAGE_ZIP) 386 387endif 388 389endif # TRUSTY_APPLOADER_ENABLED 390 391include make/rust-project-json.mk 392 393 394# Restore kernel state 395ARCH := $(TRUSTY_KERNEL_SAVED_ARCH) 396ALLOW_FP_USE := $(TRUSTY_KERNEL_SAVED_ALLOW_FP_USE) 397SCS_ENABLED := $(TRUSTY_KERNEL_SAVED_SCS_ENABLED) 398 399# 400# Generate combined user task obj/bin if necessary 401# 402ifneq ($(strip $(TRUSTY_BUILTIN_USER_TASKS)),) 403 404BUILTIN_TASK_MANIFESTS_BINARY := $(foreach t, $(TRUSTY_BUILTIN_USER_TASKS),\ 405 $(_MODULES_$(t)_TRUSTY_APP_MANIFEST_BIN)) 406 407BUILTIN_TASK_ELFS := $(foreach t, $(TRUSTY_BUILTIN_USER_TASKS),\ 408 $(_MODULES_$(t)_TRUSTY_APP_ELF)) 409 410BUILTIN_TASK_OBJS := $(patsubst %.elf,%.o,$(BUILTIN_TASK_ELFS)) 411 412$(BUILTIN_TASK_OBJS): CC := $(CC) 413$(BUILTIN_TASK_OBJS): GLOBAL_COMPILEFLAGS := $(GLOBAL_COMPILEFLAGS) 414$(BUILTIN_TASK_OBJS): ARCH_COMPILEFLAGS := $(ARCH_$(ARCH)_COMPILEFLAGS) 415$(BUILTIN_TASK_OBJS): USER_TASK_OBJ_ASM:=$(TRUSTY_APP_DIR)/appobj.S 416$(BUILTIN_TASK_OBJS): LOG_NAME:=$(TRUSTY_APP_DIR) 417$(BUILTIN_TASK_OBJS): %.o: %.elf %.manifest $(USER_TASK_OBJ_ASM) 418 @$(MKDIR) 419 @$(call ECHO,$(LOG_NAME),converting,$< to $@) 420 $(NOECHO)$(CC) -DUSER_TASK_ELF=\"$<\" -DMANIFEST_DATA=\"$(word 2,$^)\" $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) -c $(USER_TASK_OBJ_ASM) -o $@ 421 @$(call ECHO_DONE_SILENT,$(LOG_NAME),converting,$< to $@) 422 423EXTRA_OBJS += $(BUILTIN_TASK_OBJS) 424 425endif 426 427# Reset app variables 428BUILDDIR := $(TRUSTY_TOP_LEVEL_BUILDDIR) 429TRUSTY_APP := 430TRUSTY_APP_NAME := 431TRUSTY_APP_BASE_LDFLAGS := 432TRUSTY_APP_ARCH := 433TRUSTY_APP_ALIGNMENT := 434TRUSTY_APP_MEMBASE := 435TRUSTY_APP_SYMTAB_ENABLED := 436TRUSTY_APPLOADER_ENABLED := 437TRUSTY_TOP_LEVEL_BUILDDIR := 438TRUSTY_USERSPACE := 439TRUSTY_USERSPACE_SAVED_ARCH := 440TRUSTY_USERSPACE_SAVED_ALLOW_FP_USE := 441TRUSTY_USERSPACE_SAVED_SCS_ENABLED := 442USER_TASK_MODULE := 443LOADABLE_APP_LIST := 444TRUSTY_LOADABLE_USER_TASKS := 445TEST_PACKAGE_ZIP := 446RUST_PROJECT_JSON := 447RUST_PROJECT_JSON_CONTENTS := 448RUST_USER_TEST_MODULES := 449RUST_ANALYZER_CONTENTS := 450GLOBAL_CRATE_COUNT := 451