1# build a top-level wrapper crate as a staticlib to link into lk.elf 2 3# collect paths for proc-macro deps with BUILDDIR for host libs 4WRAPPER_RUST_EXTERN_PATHS := $(foreach stem, $(ALL_KERNEL_HOST_CRATE_STEMS), $(stem)=$(TRUSTY_HOST_LIBRARY_BUILDDIR)/lib$(stem).so) 5 6# change BUILDDIR so RSOBJS for kernel are distinct targets from userspace ones 7OLD_BUILDDIR := $(BUILDDIR) 8BUILDDIR := $(BUILDDIR)/kernellib 9 10WRAPPER_RUSTFLAGS := --crate-type=staticlib 11 12# compute the set of rust module rlibs to depend on 13ALLMODULE_RLIBS := $(foreach stem, $(ALLMODULE_CRATE_STEMS), $(call TOBUILDDIR,lib$(stem).rlib)) 14 15# topologically sort crates based on dependency order. 16 17# first, emit every pair of depender and dependency into $(CRATE_DEPS_FILE) 18CRATE_DEPS_FILE := $(BUILDDIR)/crate-dependencies 19$(CRATE_DEPS_FILE): $(ALLMODULE_RLIBS) 20 @$(MKDIR) 21 : > $(CRATE_DEPS_FILE) 22 $(foreach mod, $(ALLMODULE_CRATE_STEMS), $(foreach dep, $(MODULE_$(mod)_CRATE_DEPS), echo $(mod) $(dep) >> $(CRATE_DEPS_FILE);)) 23 24# process these pairs with tsort to generate an ordering 25SORTED_CRATE_STEMS_FILE := $(BUILDDIR)/crate-dependency-ordering 26$(SORTED_CRATE_STEMS_FILE): $(CRATE_DEPS_FILE) 27 @$(MKDIR) 28 echo -n "ALLMODULE_CRATE_STEMS_SORTED := " > $(SORTED_CRATE_STEMS_FILE) 29 tsort < $(CRATE_DEPS_FILE) | tac | tr "\n" " " >> $(SORTED_CRATE_STEMS_FILE) 30 31# load our ordering in ALLMODULE_CRATE_STEMS_SORTED via include 32include $(SORTED_CRATE_STEMS_FILE) 33 34 35# build "--extern foo=/path/to/foo" flags for rustc 36WRAPPER_RUST_EXTERN_PATHS += $(foreach stem,$(ALLMODULE_CRATE_STEMS_SORTED),$(subst .,_,$(stem))=$(call TOBUILDDIR,lib$(stem).rlib)) 37WRAPPER_RUSTFLAGS += $(addprefix --extern ,$(WRAPPER_RUST_EXTERN_PATHS)) 38 39# generate a .rs source file for the wrapper crate 40# we must not explicitly "extern crate" core or compiler_builtins 41CRATES_TO_IMPORT := $(filter-out core compiler_builtins,$(ALL_KERNEL_HOST_CRATE_STEMS) $(ALLMODULE_CRATE_STEMS_SORTED)) 42RUST_WRAPPER_SRC := \#![no_std] \ 43 $(foreach crate, $(CRATES_TO_IMPORT), extern crate $(subst .,_,$(crate));) 44 45RUST_WRAPPER := $(BUILDDIR)/lk-crates.rs 46 47$(RUST_WRAPPER): RUST_WRAPPER_SRC := $(RUST_WRAPPER_SRC) 48$(RUST_WRAPPER): $(SORTED_CRATE_STEMS_FILE) 49 @$(MKDIR) 50 echo "$(RUST_WRAPPER_SRC)" > "$@" 51 52RUST_WRAPPER_OBJ := $(BUILDDIR)/lk-crates.a 53 54$(RUST_WRAPPER_OBJ): WRAPPER_RUSTFLAGS := $(WRAPPER_RUSTFLAGS) 55$(RUST_WRAPPER_OBJ): ARCH_RUSTFLAGS := $(ARCH_$(ARCH)_RUSTFLAGS) 56 57$(RUST_WRAPPER_OBJ): $(ALLMODULE_RLIBS) $(RUST_WRAPPER) 58 +$(NOECHO)$(RUSTC) $(GLOBAL_KERNEL_RUSTFLAGS) $(GLOBAL_SHARED_RUSTFLAGS) $(ARCH_RUSTFLAGS) $(WRAPPER_RUSTFLAGS) -o $@ $(RUST_WRAPPER) 59 60# if there were no rust crates, don't build the .a 61ifneq ($(ALLMODULE_CRATE_STEMS),) 62EXTRA_OBJS += $(RUST_WRAPPER_OBJ) 63endif 64 65CRATE_COUNT := 0 66 67$(foreach crate,$(ALLMODULE_CRATE_STEMS_SORTED),\ 68 $(eval RUST_TOPLEVEL_$(crate)_CRATE_INDEX := $(CRATE_COUNT))\ 69 $(eval CRATE_COUNT := $(shell echo $$(($(CRATE_COUNT)+1))))\ 70) 71 72define CRATE_CONFIG = 73\t\t{\n 74 \t\t\t"display_name": "$(crate)",\n 75 \t\t\t"root_module": "$(abspath $(filter %.rs,$(MODULE_$(crate)_RUST_SRC)))",\n 76 \t\t\t"edition": "$(MODULE_$(crate)_RUST_EDITION)",\n 77 \t\t\t"deps": [\n 78 $(call STRIP_TRAILING_COMMA,$(foreach dep,$(sort $(MODULE_$(crate)_CRATE_DEPS)),\ 79 \t\t\t\t{\n 80 \t\t\t\t\t"name": "$(dep)"$(COMMA)\n 81 \t\t\t\t\t"crate": $(RUST_TOPLEVEL_$(dep)_CRATE_INDEX)\n 82 \t\t\t\t}$(COMMA)\n)) 83 \t\t\t],\n 84 \t\t\t"cfg": [\n 85 $(call STRIP_TRAILING_COMMA,$(foreach f, $(MODULE_$(crate)_CRATE_CFG),\ 86 \t\t\t\t"$(subst ",\\\\\\\",$(f))"$(COMMA)\n)) 87 \t\t\t]\n 88\t\t},\n 89 90endef 91 92RUST_ANALYZER_CONTENTS := $(foreach crate,$(ALLMODULE_CRATE_STEMS_SORTED),$(CRATE_CONFIG)) 93 94include make/rust-project-json.mk 95 96# restore BUILDDIR 97BUILDDIR := $(OLD_BUILDDIR) 98 99CRATE_COUNT := 100CRATE_CONFIG := 101RUST_ANALYZER_CONTENTS := 102RUST_WRAPPER_SRC := 103WRAPPER_RUSTFLAGS := 104WRAPPER_RUST_EXTERN_PATHS := 105ALLMODULE_CRATE_STEMS_SORTED := 106