# Copyright 2020 Authors of Cilium # SPDX-License-Identifier: Apache-2.0 ifdef DOCKER_BUILDKIT BUILD_DIR := _build # Export with value expected by docker export DOCKER_BUILDKIT=1 # Clean the build directory and cache clean-build: -$(QUIET) rm -rf _build -$(QUIET) docker builder prune --filter type=exec.cachemount -f veryclean: clean-build BUILDKIT_DOCKERFILE_FILTER := | sed -e "1s|^\#.*|\# syntax = docker/dockerfile:experimental|" -e "s|^RUN\(.*\)make|RUN --mount=type=cache,target=/root/.cache/go-build\1make|" # Check that files needed for git-less build are up-to-date build-context-update: GIT_VERSION # Generic rule for augmented .dockerignore files. For 'Dockerfile' the stem ('%') matches just the 'D'. # '.git' can not be ignored in the top level '.dockerignore' as builds directly from the Dockerfiles # (e.g., on Docker hub and Quay) depend on '.git' for the git SHA. .PRECIOUS: _build/%ockerfile.dockerignore GIT_IGNORE_FILES := $(shell find . -not -path "./_build*" -not -path "./vendor*" -name .gitignore -print) _build/%ockerfile.dockerignore: $(GIT_IGNORE_FILES) Makefile.buildkit @-mkdir -p $(dir $@) @echo "/hack" > $@ @echo ".git" >> $@ echo $(dir $(GIT_IGNORE_FILES)) | tr ' ' '\n' | xargs -P1 -n1 -I {DIR} sed \ -e '# Remove lines with white space, comments and files that must be passed to docker, "$$" due to make. #' \ -e '/^[[:space:]]*$$/d' -e '/^#/d' -e '/GIT_VERSION/d' \ -e '# Apply pattern in all directories if it contains no "/", keep "!" up front. #' \ -e '/^[^!/][^/]*$$/s<^<**/<' -e '/^![^/]*$$/s<^!> $@ # Generic rule for Dockerfiles. For 'Dockerfile' the stem ('%') matches just the 'D'. _build/%ockerfile: %ockerfile _build/%ockerfile.dockerignore force @-mkdir -p $(dir $@) @cat $< $(BUILDKIT_DOCKERFILE_FILTER) > $@ @-grep "^FROM " $@ | cut -d ' ' -f2 | grep -v -e "scratch" -e "[$$_{}]" | xargs -P4 -n1 docker pull # # Optionally make a shallow clone of the repo to explicitly exclude # all files not in git from the build. # ifdef BUILD_ONLY_COMMITTED DOCKER_BUILD_DIR := $(BUILD_DIR)/context # _build/.git is a shallow bare clone of the main repo # - mkdir can fail if the directory exists already # - git clone will fail if _build.git already exists. # In this case the following 'build-context-update' will update it # If the _build directory gets into bad shape 'make veryclean' will nuke it. _build/.git: -mkdir -p _build -git clone --bare --no-local --depth 1 . _build/.git && cd _build && git remote set-url origin .. # # Create _build context: # _build/context/.git will be a file (rather than directory) that contains git specific # symbolic link to _build/.git (--separate-git-dir) # _build/context: _build/.git git init --separate-git-dir=$< $@ @echo "gitdir: ../.git" > _build/context/.git # # Update the docker build context by: # 1. shallow fetch from the main repo to _build/.git # 2. check out FETCH_HEAD into _build/context. Hard reset seems to be a best way of doing this. # 3. remove the .git file from _build/context/.git so that make running in docker knows this is # no a git repo (as _build/.git is NOT part of the docker context) # # Dependencies: # - check that git status is clean # - make sure docker build context exists # - update GIT_VERSION in the build context if needed # build-context-update: check-status _build/context _build/context/GIT_VERSION cd _build && git fetch --depth=1 --no-tags cd _build/context && git reset --hard FETCH_HEAD && git clean -fd # # Docker build context does not contain the actual git repo, so we need to pass # GIT_VERSION to the build context separately. # _build/context/GIT_VERSION: GIT_VERSION _build/context cp $< $@ check-status: @if [ -n "`git status --porcelain`" ] ; then git status && echo "These changes will not be included in build, aborting. Define IGNORE_GIT_STATUS to build anyway." && test $(IGNORE_GIT_STATUS); fi endif endif