180 lines
4.7 KiB
Makefile
180 lines
4.7 KiB
Makefile
|
NAME := $(shell basename $(shell git rev-parse --show-toplevel))
|
||
|
IMAGE := local/$(NAME):latest
|
||
|
ARCH := x86_64
|
||
|
TARGET := $(ARCH)
|
||
|
USER := $(shell id -u):$(shell id -g)
|
||
|
CPUS := $(shell docker run -it debian nproc)
|
||
|
GIT_REF := $(shell git log -1 --format=%H config)
|
||
|
GIT_AUTHOR := $(shell git log -1 --format=%an config)
|
||
|
GIT_KEY := $(shell git log -1 --format=%GP config)
|
||
|
GIT_EPOCH := $(shell git log -1 --format=%at config)
|
||
|
GIT_DATETIME := \
|
||
|
$(shell git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S' config)
|
||
|
ifeq ($(strip $(shell git status --porcelain 2>/dev/null)),)
|
||
|
GIT_STATE=clean
|
||
|
else
|
||
|
GIT_STATE=dirty
|
||
|
endif
|
||
|
VERSION := $(shell TZ=UTC0 git show --quiet --date='format-local:%Y%m%dT%H%M%SZ' --format="%cd")
|
||
|
RELEASE_DIR := release/$(VERSION)
|
||
|
CONFIG_DIR := config
|
||
|
CACHE_DIR := cache
|
||
|
SRC_DIR := src
|
||
|
OUT_DIR := out
|
||
|
docker = docker
|
||
|
|
||
|
include $(CONFIG_DIR)/global.env
|
||
|
export $(shell sed 's/=.*//' $(CONFIG_DIR)/global.env)
|
||
|
|
||
|
## Use env vars from existing release if present
|
||
|
ifneq (,$(wildcard $(RELEASE_DIR)/release.env))
|
||
|
include $(RELEASE_DIR)/release.env
|
||
|
export
|
||
|
endif
|
||
|
|
||
|
executables = $(docker) git patch
|
||
|
|
||
|
.PHONY: toolchain
|
||
|
toolchain: $(CACHE_DIR)/toolchain.tar $(CACHE_DIR)/toolchain.env
|
||
|
|
||
|
# Launch a shell inside the toolchain container
|
||
|
.PHONY: toolchain-shell
|
||
|
toolchain-shell: toolchain
|
||
|
$(call toolchain,$(USER),"bash --norc")
|
||
|
|
||
|
# Pin all packages in toolchain container to latest versions
|
||
|
.PHONY: toolchain-update
|
||
|
toolchain-update:
|
||
|
docker run \
|
||
|
--rm \
|
||
|
--env LOCAL_USER=$(USER) \
|
||
|
--platform=linux/$(ARCH) \
|
||
|
--volume $(PWD)/$(CONFIG_DIR):/config \
|
||
|
--volume $(PWD)/$(SRC_DIR)/toolchain/scripts:/usr/local/bin \
|
||
|
--env ARCH=$(ARCH) \
|
||
|
--interactive \
|
||
|
--tty \
|
||
|
debian@sha256:$(DEBIAN_HASH) \
|
||
|
bash -c /usr/local/bin/packages-update
|
||
|
|
||
|
.PHONY: attest
|
||
|
attest:
|
||
|
rm -rf $(CACHE_DIR) $(OUT_DIR)
|
||
|
$(MAKE)
|
||
|
diff -q $(OUT_DIR)/manifest.txt release/$(VERSION)/manifest.txt;
|
||
|
|
||
|
$(RELEASE_DIR):
|
||
|
mkdir -p $@
|
||
|
|
||
|
$(CACHE_DIR):
|
||
|
mkdir -p $@
|
||
|
|
||
|
$(OUT_DIR):
|
||
|
mkdir -p $@
|
||
|
|
||
|
.ONESHELL:
|
||
|
$(CACHE_DIR)/toolchain.env: $(CACHE_DIR)
|
||
|
cat <<- EOF > $@
|
||
|
HOME=/home/build
|
||
|
PS1=$(NAME)-toolchain
|
||
|
GNUPGHOME=/cache/.gnupg
|
||
|
ARCH=$(ARCH)
|
||
|
TARGET=$(ARCH)
|
||
|
GIT_REF=$(GIT_REF)
|
||
|
GIT_AUTHOR=$(GIT_AUTHOR)
|
||
|
GIT_KEY=$(GIT_KEY)
|
||
|
GIT_DATETIME=$(GIT_DATETIME)
|
||
|
GIT_EPOCH=$(GIT_EPOCH)
|
||
|
FAKETIME_FMT="%s"
|
||
|
FAKETIME="1"
|
||
|
SOURCE_DATE_EPOCH=1
|
||
|
KBUILD_BUILD_TIMESTAMP="1970-01-01 00:00:00 UTC"
|
||
|
KCONFIG_NOTIMESTAMP=1
|
||
|
KBUILD_BUILD_USER=root
|
||
|
KBUILD_BUILD_HOST=$(NAME)
|
||
|
KBUILD_BUILD_VERSION=1
|
||
|
UID=$(shell id -u)
|
||
|
GID=$(shell id -g)
|
||
|
RELEASE_DIR=release/$(VERSION)
|
||
|
CONFIG_DIR=/home/build/$(CONFIG_DIR)
|
||
|
CACHE_DIR=/home/build/$(CACHE_DIR)
|
||
|
SRC_DIR=/home/build/$(SRC_DIR)
|
||
|
OUT_DIR=/home/build/$(OUT_DIR)
|
||
|
EOF
|
||
|
|
||
|
$(CACHE_DIR)/toolchain.tar:
|
||
|
mkdir -p $(CACHE_DIR)
|
||
|
DOCKER_BUILDKIT=1 \
|
||
|
docker build \
|
||
|
--tag $(IMAGE) \
|
||
|
--build-arg DEBIAN_HASH=$(DEBIAN_HASH) \
|
||
|
--build-arg CONFIG_DIR=$(CONFIG_DIR) \
|
||
|
--build-arg SCRIPTS_DIR=$(SRC_DIR)/toolchain/scripts \
|
||
|
--platform=linux/$(ARCH) \
|
||
|
-f $(SRC_DIR)/toolchain/Dockerfile \
|
||
|
.
|
||
|
docker save "$(IMAGE)" -o "$@"
|
||
|
|
||
|
$(RELEASE_DIR)/release.env: \
|
||
|
$(RELEASE_DIR) \
|
||
|
$(OUT_DIR)/release.env
|
||
|
cp $(OUT_DIR)/release.env $(RELEASE_DIR)/release.env
|
||
|
|
||
|
$(RELEASE_DIR)/manifest.txt: \
|
||
|
$(RELEASE_DIR) \
|
||
|
$(OUT_DIR)/manifest.txt
|
||
|
cp $(OUT_DIR)/manifest.txt $(RELEASE_DIR)/manifest.txt
|
||
|
|
||
|
$(OUT_DIR)/release.env: | $(OUT_DIR)
|
||
|
echo 'VERSION=$(VERSION)' > $(OUT_DIR)/release.env
|
||
|
echo 'GIT_REF=$(GIT_REF)' >> $(OUT_DIR)/release.env
|
||
|
echo 'GIT_AUTHOR=$(GIT_AUTHOR)' >> $(OUT_DIR)/release.env
|
||
|
echo 'GIT_KEY=$(GIT_KEY)' >> $(OUT_DIR)/release.env
|
||
|
echo 'GIT_DATETIME=$(GIT_DATETIME)' >> $(OUT_DIR)/release.env
|
||
|
|
||
|
$(OUT_DIR)/manifest.txt: | $(OUT_DIR)
|
||
|
find $(OUT_DIR) \
|
||
|
-type f \
|
||
|
-not -path "$(OUT_DIR)/manifest.txt" \
|
||
|
-exec openssl sha256 -r {} \; \
|
||
|
| sed -e 's/ \*/ /g' -e 's/ \.\// /g' \
|
||
|
| LC_ALL=C sort -k2 \
|
||
|
> $@
|
||
|
|
||
|
check_executables := $(foreach exec,$(executables),\$(if \
|
||
|
$(shell which $(exec)),some string,$(error "No $(exec) in PATH")))
|
||
|
|
||
|
define git_clone
|
||
|
[ -d $(CACHE_DIR)/$(1) ] || git clone $(2) $(CACHE_DIR)/$(1)
|
||
|
git -C $(CACHE_DIR)/$(1) checkout $(3)
|
||
|
git -C $(CACHE_DIR)/$(1) rev-parse --verify HEAD | grep -q $(3) || { \
|
||
|
echo 'Error: Git ref/branch collision.'; exit 1; \
|
||
|
};
|
||
|
endef
|
||
|
|
||
|
define apply_patches
|
||
|
[ -d $(2) ] && $(call toolchain,$(USER)," \
|
||
|
cd $(1); \
|
||
|
git restore .; \
|
||
|
find /$(2) -type f -iname '*.patch' -print0 \
|
||
|
| xargs -t -0 -n 1 patch -p1 --no-backup-if-mismatch -i ; \
|
||
|
")
|
||
|
endef
|
||
|
|
||
|
define toolchain
|
||
|
docker load -i $(CACHE_DIR)/toolchain.tar
|
||
|
docker run \
|
||
|
--rm \
|
||
|
--tty \
|
||
|
--interactive \
|
||
|
--user=$(1) \
|
||
|
--platform=linux/$(ARCH) \
|
||
|
--cpus $(CPUS) \
|
||
|
--volume $(PWD):/home/build \
|
||
|
--workdir /home/build \
|
||
|
--env-file=$(CONFIG_DIR)/global.env \
|
||
|
--env-file=$(CACHE_DIR)/toolchain.env \
|
||
|
$(IMAGE) \
|
||
|
bash -c $(2)
|
||
|
endef
|