libpayload: Add a Makefile for in-tree payloads

The new `Makefile.payload` can be included by the Makefiles of pay-
loads for in-tree builds. The basic idea is to use libpayload's
build results without the `make install` step, and to ensure that
incremental builds work. For instance, if libpayload's code changes,
a `make` for the payload would automatically update the libpayload
build and rebuild the payload. But if there are no code changes in
libpayload, only updated files of the payload will be re-built.

The configuration of libpayload is supposed to be automatically
generated from a `defconfig` file. If this `defconfig` changes,
libpayload and the payload will be re-built.

Change-Id: If5319f1bf0bcd09964416237c5cf7f8e59f487a2
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47633
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Nico Huber 2020-11-15 19:18:41 +01:00
parent 30570a7de1
commit 9c8f0424d6
1 changed files with 157 additions and 0 deletions

View File

@ -0,0 +1,157 @@
# 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 = $(GCC_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)),)
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) $(GCC_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 += $(if $(CCACHE),CONFIG_LP_CCACHE=y)
defconfig: lp-defconfig
lp-defconfig: $(LIBPAYLOAD_DOTCONFIG)
$(LIBPAYLOAD_DOTCONFIG): $(LIBPAYLOAD_DEFCONFIG) | $(PAYLOAD_DEPS)
$(MAKE) -C $(LIBPAYLOAD_SRC) $(LIBPAYLOAD_OPTS) \
KBUILD_DEFCONFIG=$(LIBPAYLOAD_DEFCONFIG) defconfig
$(LIBPAYLOAD_CONFIG_H): $(LIBPAYLOAD_DOTCONFIG)
$(MAKE) -C $(LIBPAYLOAD_SRC) $(LIBPAYLOAD_OPTS) $(LIBPAYLOAD_CONFIG_H)
oldconfig: lp-oldconfig
lp-oldconfig:
[ ! -f $(LIBPAYLOAD_DOTCONFIG) ] || \
$(MAKE) -C $(LIBPAYLOAD_SRC) $(LIBPAYLOAD_OPTS) oldconfig
$(LIBPAYLOAD): lp-defconfig | $(LIBPAYLOAD_CONFIG_H)
$(MAKE) -C $(LIBPAYLOAD_SRC) $(LIBPAYLOAD_OPTS)
$(shell mkdir -p $(sort $(dir $(OBJS))))
.PHONY: oldconfig lp-oldconfig defconfig lp-defconfig
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