[rust] Add build system support for proc macro crates
Adds build system support for building proc macro crates and their
dependencies for the host system.
Test: build.py
Bug: 229156386
Change-Id: I648064a509a0198b784605e0cc846c0808aa9e37
diff --git a/make/common_flags.mk b/make/common_flags.mk
index 66ba96e..2f39db3 100644
--- a/make/common_flags.mk
+++ b/make/common_flags.mk
@@ -9,15 +9,6 @@
endif
endif
-# Default Rust edition unless otherwise specified
-ifeq ($(call TOBOOL,$(MODULE_IS_RUST)),true)
-ifeq ($(MODULE_RUST_EDITION),)
-MODULE_RUST_EDITION := 2021
-endif
-
-MODULE_RUSTFLAGS += --edition $(MODULE_RUST_EDITION)
-endif
-
# Remaining flags only apply to the trusty userspace, not the test-runner, which
# is also built with the library system.
ifeq (true,$(call TOBOOL,$(TRUSTY_USERSPACE)))
diff --git a/make/library.mk b/make/library.mk
index 9492694..85cd717 100644
--- a/make/library.mk
+++ b/make/library.mk
@@ -106,16 +106,33 @@
# userspace_recurse.mk
TRUSTY_NEW_MODULE_SYSTEM :=
-ifeq ($(call TOBOOL,$(TRUSTY_APP)),false)
-BUILDDIR := $(TRUSTY_LIBRARY_BUILDDIR)
-endif
-
ifneq ($(filter %.rs,$(MODULE_SRCS)$(MODULE_SRCS_FIRST)),)
MODULE_IS_RUST := true
endif
+ifneq ($(filter proc-macro,$(MODULE_RUST_CRATE_TYPES)),)
+
+# proc macros must be host libraries, and all their dependencies are as well.
+# This will be reset after we recursively include all dependencies.
+MODULE_RUST_HOST_LIB := true
+
+ifneq ($(strip $(filter-out proc-macro,$(MODULE_RUST_CRATE_TYPES))),)
+$(error $(MODULE) cannot be built as both a proc-macro and a target crate)
+endif
+endif
+
+ifeq ($(call TOBOOL,$(TRUSTY_APP)),false)
+ifeq ($(call TOBOOL,$(MODULE_RUST_HOST_LIB)),false)
+BUILDDIR := $(TRUSTY_LIBRARY_BUILDDIR)
+else
+BUILDDIR := $(TRUSTY_HOST_LIBRARY_BUILDDIR)
+endif
+endif
+
+ifeq ($(call TOBOOL,$(MODULE_RUST_HOST_LIB)),false)
# Add any common flags to the module
include make/common_flags.mk
+endif
ifneq ($(INCMODULES),)
$(error $(MODULE) should only be included from other userspace modules that use library.mk. One of the following modules needs to be updated to use the new library system: $(LIB_SAVED_MODULE) $(ALLMODULES))
@@ -250,8 +267,8 @@
$(error $(MODULE) includes more than one Rust file in MODULE_SRCS)
endif
-ifneq ($(filter-out rlib staticlib bin,$(MODULE_RUST_CRATE_TYPES)),)
-$(error $(MODULE) contains unrecognized crate type $(filter-out rlib staticlib bin,$(MODULE_RUST_CRATE_TYPES)) in MODULE_RUST_CRATE_TYPES)
+ifneq ($(filter-out rlib staticlib bin proc-macro,$(MODULE_RUST_CRATE_TYPES)),)
+$(error $(MODULE) contains unrecognized crate type $(filter-out rlib staticlib bin proc-macro,$(MODULE_RUST_CRATE_TYPES)) in MODULE_RUST_CRATE_TYPES)
endif
ifeq ($(MODULE_CRATE_NAME),)
@@ -260,6 +277,13 @@
MODULE_RUSTFLAGS += --crate-name=$(MODULE_CRATE_NAME)
+# Default Rust edition unless otherwise specified
+ifeq ($(MODULE_RUST_EDITION),)
+MODULE_RUST_EDITION := 2021
+endif
+
+MODULE_RUSTFLAGS += --edition $(MODULE_RUST_EDITION)
+
ifeq ($(strip $(MODULE_RUST_CRATE_TYPES)),)
MODULE_RUST_CRATE_TYPES := rlib
endif
@@ -270,6 +294,14 @@
MODULE_RSOBJS :=
+ifneq ($(filter proc-macro,$(MODULE_RUST_CRATE_TYPES)),)
+MODULE_CRATE_OUTPUT := $(call TOBUILDDIR,lib$(MODULE_CRATE_NAME).so)
+MODULE_RSOBJS += $(MODULE_CRATE_OUTPUT)
+$(MODULE_CRATE_OUTPUT): MODULE_RUSTFLAGS := $(MODULE_RUSTFLAGS) \
+ --crate-type=proc-macro --extern proc_macro -C prefer-dynamic
+MODULE_EXPORT_RLIBS += $(MODULE_CRATE_NAME)=$(MODULE_CRATE_OUTPUT)
+endif # proc-macro crate
+
ifneq ($(filter rlib,$(MODULE_RUST_CRATE_TYPES)),)
MODULE_CRATE_OUTPUT := $(call TOBUILDDIR,lib$(MODULE_CRATE_NAME).rlib)
MODULE_RSOBJS += $(MODULE_CRATE_OUTPUT)
@@ -323,9 +355,15 @@
ALLMODULE_OBJS :=
MODULE_LIBRARY_DEPS :=
+ifeq ($(call TOBOOL,$(MODULE_RUST_HOST_LIB)),true)
+# Remove the target-specific flags
+$(MODULE_RSOBJS): ARCH_RUSTFLAGS :=
+$(MODULE_RSOBJS): GLOBAL_RUSTFLAGS := $(GLOBAL_HOST_RUSTFLAGS)
+else
$(MODULE_RSOBJS): ARCH_RUSTFLAGS := $(ARCH_$(ARCH)_RUSTFLAGS)
$(MODULE_RSOBJS): GLOBAL_RUSTFLAGS := $(GLOBAL_SHARED_RUSTFLAGS) $(GLOBAL_USER_RUSTFLAGS)
$(MODULE_RSOBJS): MODULE_RUST_ENV := $(MODULE_RUST_ENV)
+endif
include make/module.mk
@@ -351,7 +389,7 @@
$(BUILDDIR)/%.o: ARCH_ASMFLAGS := $(ARCH_$(ARCH)_ASMFLAGS)
ifeq ($(call TOBOOL,$(MODULE_IS_RUST)),true)
-LIBRARY_ARCHIVE := $(filter %.rlib,$(ALLMODULE_OBJS))
+LIBRARY_ARCHIVE := $(filter %.rlib %.so,$(ALLMODULE_OBJS))
else
LIBRARY_ARCHIVE := $(filter %.mod.a,$(ALLMODULE_OBJS))
endif
@@ -390,6 +428,11 @@
MODULE_RSOBJS :=
LIB_SAVED_MODULE :=
LIB_SAVED_ALLMODULE_OBJS :=
+
+ifneq ($(filter proc-macro,$(MODULE_RUST_CRATE_TYPES)),)
+# Reset host build state only once we finish building the proc-macro and its deps
+MODULE_RUST_HOST_LIB :=
+endif
MODULE_RUST_CRATE_TYPES :=
MODULE_RUST_TESTS :=
diff --git a/make/trusted_app.mk b/make/trusted_app.mk
index 21f551d..d66bca8 100644
--- a/make/trusted_app.mk
+++ b/make/trusted_app.mk
@@ -102,8 +102,8 @@
# Link app elf
ifeq ($(call TOBOOL,$(MODULE_IS_RUST)),true)
MODULE_RUSTFLAGS += \
- -Z pre-link-args="$(filter-out %.rlib,$(MODULE_EXTRA_OBJECTS))" \
- -C link-args="$(ALLMODULE_OBJS)" \
+ -Z pre-link-args="$(filter-out %.rlib %.so,$(MODULE_EXTRA_OBJECTS))" \
+ -C link-args="$(filter-out %.rlib %.so,$(ALLMODULE_OBJS))" \
-C link-args="$(TRUSTY_APP_LDFLAGS) $(MODULE_LDFLAGS)" \
$(TRUSTY_APP_SYMS_ELF).d: