Loading...
# SPDX-License-Identifier: GPL-2.0+
#
# Common build rules for ulib example programs.
#
# Re-links U-Boot with example objects providing main(). The example .o
# files are compiled via kbuild (examples/ulib/Kbuild). This re-links
# u-boot with those objects so the example's strong main() overrides the
# weak one in board_r.c, using the shared u-boot-link helper.
#
# Required variables (set by arch Makefile before including):
#   EXAMPLE_ARCH        - architecture name (x86, arm, riscv, ...)
#
# Optional variables:
#   EXAMPLE_APPEND_DTB  - set to y to append DTB to the binary
#   EXAMPLE_POST_LINK   - extra recipe line run after linking the ELF

INPUTS-$(CONFIG_ULIB) += examples_$(EXAMPLE_ARCH)
PHONY += examples_$(EXAMPLE_ARCH)

ULIB_EXAMPLES := demo

# --- Rust examples ---
RUSTC := rustc
RUST_TARGET_x86 := i686-unknown-linux-gnu
RUST_TARGET_x86_64 := x86_64-unknown-none
RUST_FLAGS_x86 := -C panic=abort -C relocation-model=static
RUST_FLAGS_x86_64 :=
RUST_TARGET_arm := aarch64-unknown-none
RUST_FLAGS_arm :=
RUST_TARGET_riscv := riscv64gc-unknown-none-elf
RUST_FLAGS_riscv :=

ifdef CONFIG_X86_64
RUST_TARGET := $(RUST_TARGET_$(EXAMPLE_ARCH)_64)
RUST_FLAGS := $(RUST_FLAGS_$(EXAMPLE_ARCH)_64)
else
RUST_TARGET := $(RUST_TARGET_$(EXAMPLE_ARCH))
RUST_FLAGS := $(RUST_FLAGS_$(EXAMPLE_ARCH))
endif

ifeq ($(CONFIG_RUST_EXAMPLES),y)
ULIB_EXAMPLES += rust-demo
endif

quiet_cmd_u-boot-example = LD      $@
      cmd_u-boot-example = $(call u-boot-link,$(example-objs),$@.map)

quiet_cmd_rustc_obj = RUSTC   $@
      cmd_rustc_obj = \
	mkdir -p $(dir $@) && \
	MAKEFLAGS= $(RUSTC) --edition 2021 --emit=obj -o $@ \
	--target=$(RUST_TARGET) $(RUST_FLAGS) $<

examples/ulib/rust_demo.o: examples/ulib/rust_demo.rs FORCE
	$(call if_changed,rustc_obj)

# Per-example object lists (matches examples/ulib/Kbuild)
example-demo-objs := examples/ulib/demo.o examples/ulib/demo_helper.o
example-rust-demo-objs := examples/ulib/rust_demo.o examples/ulib/demo_helper.o

# Generate link rule for each example
define example_link_rule
examples/ulib/$(1): $$(example-$(1)-objs) u-boot FORCE
	$$(eval example-objs := $$(example-$(1)-objs))
	$$(call if_changed,u-boot-example)
	$$(EXAMPLE_POST_LINK)
endef

$(foreach e,$(ULIB_EXAMPLES),$(eval $(call example_link_rule,$(e))))

ifeq ($(CONFIG_EFI_APP),y)
# EFI: embed DTB and convert to PE binary
$(foreach e,$(ULIB_EXAMPLES),\
  $(eval OBJCOPYFLAGS_$(e)-app.efi := $$(OBJCOPYFLAGS_EFI)))

define example_efi_rule
examples/ulib/$(1)-app.efi: examples/ulib/$(1) __KEEPMAKEFILEDTB__B.dtb FORCE
	$$(if $$(CONFIG_OF_SEPARATE),$$(call if_changed,embeddtb))
	$$(call if_changed,zobjcopy)
endef

$(foreach e,$(ULIB_EXAMPLES),$(eval $(call example_efi_rule,$(e))))

examples_$(EXAMPLE_ARCH): \
		$(foreach e,$(ULIB_EXAMPLES),examples/ulib/$(e)-app.efi) FORCE
	@:
else
# Binary target (without DTB)
$(foreach e,$(ULIB_EXAMPLES),\
  $(eval OBJCOPYFLAGS_$(e)-nodtb.bin = $$(OBJCOPYFLAGS_u-boot-nodtb.bin)))

define example_nodtb_rule
examples/ulib/$(1)-nodtb.bin: examples/ulib/$(1) FORCE
	$$(call if_changed,objcopy)
endef

$(foreach e,$(ULIB_EXAMPLES),$(eval $(call example_nodtb_rule,$(e))))

ifeq ($(EXAMPLE_APPEND_DTB),y)
# Binary with DTB appended
define example_bin_rule
examples/ulib/$(1).bin: examples/ulib/$(1)-nodtb.bin __KEEPMAKEFILEDTB__C.dtb FORCE
	$$(call if_changed,cat)
endef

$(foreach e,$(ULIB_EXAMPLES),$(eval $(call example_bin_rule,$(e))))

examples_$(EXAMPLE_ARCH): \
		$(foreach e,$(ULIB_EXAMPLES),examples/ulib/$(e).bin) FORCE
	@:
else
examples_$(EXAMPLE_ARCH): \
		$(foreach e,$(ULIB_EXAMPLES),examples/ulib/$(e)-nodtb.bin) FORCE
	@:
endif
endif # CONFIG_EFI_APP