# SPDX-License-Identifier: BSD-3-Clause # # This file is meant to be included by in-tree payloads # to provide default targets for incremental builds. # # Variables with file names and directory overrides have # to be defined in advance for proper dependency tracking. # Then, include this file. e.g # # obj := output # OBJS := $(obj)/payload.o # TARGET := $(obj)/payload.elf # include ../path/to/libpayload/Makefile.payload # # Find relative path to libpayload (where this Makefile resides). LIBPAYLOAD_SRC := $(dir $(lastword $(MAKEFILE_LIST))) LIBPAYLOAD_SRC := $(patsubst %/,%,$(LIBPAYLOAD_SRC)) # Build dir and config for libpayload. Need absolute # paths to pass to libpayload's sub-make. LIBPAYLOAD_OBJ ?= $(CURDIR)/libpayload LIBPAYLOAD := $(LIBPAYLOAD_OBJ)/libpayload.a LIBPAYLOAD_CONFIG_H := $(LIBPAYLOAD_OBJ)/libpayload-config.h LIBPAYLOAD_DOTCONFIG ?= $(CURDIR)/.lp.config LIBPAYLOAD_DEFCONFIG ?= $(CURDIR)/$(LIBPAYLOAD_SRC)/configs/defconfig # Some default dependencies for all targets: DEFAULT_DEPS := Makefile $(lastword $(MAKEFILE_LIST)) DEFAULT_DEPS += $(PAYLOAD_DEPS) obj ?= build ARCH ?= OBJS ?= CCACHE ?= CFLAGS = $(CFLAGS_$(ARCH)) CFLAGS += -Os -ffreestanding CFLAGS += -Wall -Wextra -Wmissing-prototypes -Wvla -Werror STRIP ?= debug $(TARGET): # Make is silent per default, but `make V=1` will show all calls. Q:=@ ifneq ($(V),1) ifneq ($(Q),) .SILENT: MAKEFLAGS += -s endif endif export V ifeq ($(filter %clean,$(MAKECMDGOALS)),) -include $(LIBPAYLOAD_DOTCONFIG) xcompile := $(obj)/xcompile xcompile_script := $(LIBPAYLOAD_SRC)/../../util/xcompile/xcompile # In addition to the dependency below, create the file if it doesn't exist # to silence warnings about a file that would be generated anyway. $(if $(wildcard $(xcompile)),,$(shell \ mkdir -p $(dir $(xcompile)) && \ $(xcompile_script) $(XGCCPATH) > $(xcompile) || rm -f $(xcompile))) $(xcompile): $(xcompile_script) $< $(XGCCPATH) > $@ include $(xcompile) ifneq ($(XCOMPILE_COMPLETE),1) $(shell rm -f $(XCOMPILE_COMPLETE)) $(error $(xcompile) deleted because it's invalid. \ Restarting the build should fix that, or explain the problem.) endif # `lpgcc` in in-tree mode: LPGCC = CC="$(CCACHE) $(CC_$(ARCH))" LPGCC += _OBJ="$(LIBPAYLOAD_OBJ)" LPGCC += $(LIBPAYLOAD_SRC)/bin/lpgcc LPAS = AS="$(AS_$(ARCH))" LPAS += $(LIBPAYLOAD_SRC)/bin/lpas OBJCOPY = $(OBJCOPY_$(ARCH)) $(obj)/%.bin: $(OBJS) $(LIBPAYLOAD) $(DEFAULT_DEPS) @printf " LPGCC $(subst $(obj)/,,$@)\n" $(LPGCC) $(CFLAGS) -o $@ $(OBJS) $(obj)/%.map: $(obj)/%.bin @printf " SYMS $(subst $(obj)/,,$@)\n" $(NM_$(ARCH)) -n $< > $@ $(obj)/%.debug: $(obj)/%.bin @printf " DEBUG $(subst $(obj)/,,$@)\n" $(OBJCOPY) --only-keep-debug $< $@ .PRECIOUS: $(obj)/%.debug $(obj)/%.elf: $(obj)/%.bin $(obj)/%.debug @printf " STRIP $(subst $(obj)/,,$@)\n" $(OBJCOPY) --strip-$(STRIP) $< $@ $(OBJCOPY) --add-gnu-debuglink=$(obj)/$*.debug $@ $(obj)/%.o: %.c $(LIBPAYLOAD_CONFIG_H) $(DEFAULT_DEPS) @printf " LPGCC $(subst $(obj)/,,$@)\n" $(LPGCC) -MMD $(CFLAGS) -c $< -o $@ $(obj)/%.S.o: %.S $(LIBPAYLOAD_CONFIG_H) $(DEFAULT_DEPS) @printf " LPAS $(subst $(obj)/,,$@)\n" $(LPAS) $< -o $@ -include $(OBJS:.o=.d) .PRECIOUS: $(OBJS) LIBPAYLOAD_OPTS := obj="$(LIBPAYLOAD_OBJ)" LIBPAYLOAD_OPTS += DOTCONFIG="$(LIBPAYLOAD_DOTCONFIG)" LIBPAYLOAD_OPTS += CONFIG_=CONFIG_LP_ LIBPAYLOAD_OPTS += $(if $(CCACHE),CONFIG_LP_CCACHE=y) ifneq ($(LIBPAYLOAD_DEFCONFIG),) $(LIBPAYLOAD_DOTCONFIG): $(LIBPAYLOAD_DEFCONFIG) $(MAKE) -C $(LIBPAYLOAD_SRC) $(LIBPAYLOAD_OPTS) \ KBUILD_DEFCONFIG=$(LIBPAYLOAD_DEFCONFIG) defconfig endif $(LIBPAYLOAD_CONFIG_H): $(LIBPAYLOAD_DOTCONFIG) $(MAKE) -C $(LIBPAYLOAD_SRC) $(LIBPAYLOAD_OPTS) $(LIBPAYLOAD_CONFIG_H) force-relay: lp-%: force-relay $(MAKE) -C $(LIBPAYLOAD_SRC) $(LIBPAYLOAD_OPTS) $* $(LIBPAYLOAD): force-relay | $(LIBPAYLOAD_CONFIG_H) $(MAKE) -C $(LIBPAYLOAD_SRC) $(LIBPAYLOAD_OPTS) $(shell mkdir -p $(sort $(dir $(OBJS)))) .PHONY: force-relay else # %clean,$(MAKECMDGOALS) default-payload-clean: rm -rf $(obj) $(LIBPAYLOAD_OBJ) clean: default-payload-clean default-payload-distclean: clean rm -f $(LIBPAYLOAD_DOTCONFIG) $(LIBPAYLOAD_DOTCONFIG).old distclean: default-payload-distclean .PHONY: default-payload-clean clean default-payload-distclean distclean endif