SHELL := /usr/bin/env bash GO ?= go GOFMT ?= gofmt INSTALL ?= install PREFIX ?= $(HOME)/.local BINDIR ?= $(PREFIX)/bin LIBDIR ?= $(PREFIX)/lib DESTDIR ?= BUILD_DIR ?= build BUILD_BIN_DIR ?= $(BUILD_DIR)/bin BUILD_MANUAL_DIR ?= $(BUILD_DIR)/manual BANGER_BIN ?= $(BUILD_BIN_DIR)/banger BANGERD_BIN ?= $(BUILD_BIN_DIR)/bangerd VSOCK_AGENT_BIN ?= $(BUILD_BIN_DIR)/banger-vsock-agent BINARIES := $(BANGER_BIN) $(BANGERD_BIN) $(VSOCK_AGENT_BIN) GO_SOURCES := $(shell find cmd internal -type f -name '*.go' | sort) # BUILD_INPUTS is everything that can change a binary's bytes: Go sources # plus embedded assets (catalog.json, future static files). Listing # everything is cheaper than missing a rebuild — go's own cache absorbs # any redundant invocations. BUILD_INPUTS := $(shell find cmd internal -type f | sort) SHELL_SOURCES := $(shell find scripts -type f -name '*.sh' | sort) VOID_IMAGE_NAME ?= void VOID_VM_NAME ?= void-dev ALPINE_RELEASE ?= 3.23.3 ALPINE_IMAGE_NAME ?= alpine ALPINE_VM_NAME ?= alpine-dev VERSION ?= $(shell git describe --tags --exact-match 2>/dev/null || echo dev) COMMIT ?= $(shell git rev-parse --verify HEAD 2>/dev/null || echo unknown) BUILT_AT ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ) GO_LDFLAGS := -X banger/internal/buildinfo.Version=$(VERSION) -X banger/internal/buildinfo.Commit=$(COMMIT) -X banger/internal/buildinfo.BuiltAt=$(BUILT_AT) .DEFAULT_GOAL := help .PHONY: help build banger bangerd test fmt tidy clean rootfs rootfs-void void-kernel void-register void-vm verify-void alpine-kernel rootfs-alpine alpine-register alpine-vm verify-alpine install bench-create lint lint-go lint-shell help: @printf '%s\n' \ 'Targets:' \ ' make build Build ./build/bin/banger, ./build/bin/bangerd, and ./build/bin/banger-vsock-agent' \ ' make bench-create Benchmark vm create and SSH readiness with scripts/bench-create.sh' \ ' make install Build and install banger, bangerd, and the companion vsock helper' \ ' make test Run go test ./...' \ ' make lint Run gofmt + go vet + shellcheck (errors)' \ ' make fmt Format Go sources under cmd/ and internal/' \ ' make tidy Run go mod tidy' \ ' make clean Remove built Go binaries' \ ' make rootfs Rebuild the manual Debian rootfs image in ./build/manual' \ ' make void-kernel Download and stage a Void kernel, initramfs, and modules under ./build/manual/void-kernel' \ ' make rootfs-void Build an experimental Void Linux rootfs and work-seed in ./build/manual' \ ' make void-register Register or update the experimental Void image as $(VOID_IMAGE_NAME)' \ ' make void-vm Register the experimental Void image and create a VM named $(VOID_VM_NAME)' \ ' make verify-void Register the experimental Void image and run scripts/verify.sh against it' \ ' make alpine-kernel Download and stage an Alpine virt kernel, initramfs, and modules under ./build/manual/alpine-kernel' \ ' make rootfs-alpine Build an experimental Alpine Linux rootfs and work-seed in ./build/manual' \ ' make alpine-register Register or update the experimental Alpine image as $(ALPINE_IMAGE_NAME)' \ ' make alpine-vm Register the experimental Alpine image and create a VM named $(ALPINE_VM_NAME)' \ ' make verify-alpine Register the experimental Alpine image and run scripts/verify.sh against it' build: $(BINARIES) $(BANGER_BIN): $(BUILD_INPUTS) go.mod go.sum mkdir -p "$(BUILD_BIN_DIR)" $(GO) build -ldflags '$(GO_LDFLAGS)' -o "$(BANGER_BIN)" ./cmd/banger $(BANGERD_BIN): $(BUILD_INPUTS) go.mod go.sum mkdir -p "$(BUILD_BIN_DIR)" $(GO) build -ldflags '$(GO_LDFLAGS)' -o "$(BANGERD_BIN)" ./cmd/bangerd $(VSOCK_AGENT_BIN): $(BUILD_INPUTS) go.mod go.sum mkdir -p "$(BUILD_BIN_DIR)" CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build -ldflags '$(GO_LDFLAGS)' -o "$(VSOCK_AGENT_BIN)" ./cmd/banger-vsock-agent test: $(GO) test ./... lint: lint-go lint-shell lint-go: @unformatted="$$($(GOFMT) -l $(GO_SOURCES))"; \ if [ -n "$$unformatted" ]; then \ printf 'gofmt: the following files are not formatted:\n%s\n' "$$unformatted" >&2; \ exit 1; \ fi $(GO) vet ./... lint-shell: @command -v shellcheck >/dev/null 2>&1 || { echo 'shellcheck is required for make lint-shell' >&2; exit 1; } shellcheck --severity=error $(SHELL_SOURCES) fmt: $(GOFMT) -w $(GO_SOURCES) tidy: $(GO) mod tidy clean: rm -rf "$(BUILD_BIN_DIR)" bench-create: build BANGER_BIN="$(abspath $(BANGER_BIN))" bash ./scripts/bench-create.sh $(ARGS) install: build mkdir -p "$(DESTDIR)$(BINDIR)" mkdir -p "$(DESTDIR)$(LIBDIR)/banger" $(INSTALL) -m 0755 "$(BANGER_BIN)" "$(DESTDIR)$(BINDIR)/banger" $(INSTALL) -m 0755 "$(BANGERD_BIN)" "$(DESTDIR)$(BINDIR)/bangerd" $(INSTALL) -m 0755 "$(VSOCK_AGENT_BIN)" "$(DESTDIR)$(LIBDIR)/banger/banger-vsock-agent" rootfs: BANGER_MANUAL_DIR="$(abspath $(BUILD_MANUAL_DIR))" BANGER_BIN="$(abspath $(BANGER_BIN))" ./scripts/make-rootfs.sh $(ARGS) void-kernel: BANGER_MANUAL_DIR="$(abspath $(BUILD_MANUAL_DIR))" ./scripts/make-void-kernel.sh $(ARGS) rootfs-void: BANGER_MANUAL_DIR="$(abspath $(BUILD_MANUAL_DIR))" BANGER_BIN="$(abspath $(BANGER_BIN))" ./scripts/make-rootfs-void.sh $(ARGS) void-register: build BANGER_MANUAL_DIR="$(abspath $(BUILD_MANUAL_DIR))" VOID_IMAGE_NAME="$(VOID_IMAGE_NAME)" BANGER_BIN="$(abspath $(BANGER_BIN))" ./scripts/register-void-image.sh void-vm: void-register "$(abspath $(BANGER_BIN))" vm create --image "$(VOID_IMAGE_NAME)" --name "$(VOID_VM_NAME)" verify-void: void-register BANGER_BIN="$(abspath $(BANGER_BIN))" ./scripts/verify.sh --image "$(VOID_IMAGE_NAME)" alpine-kernel: BANGER_MANUAL_DIR="$(abspath $(BUILD_MANUAL_DIR))" ALPINE_RELEASE="$(ALPINE_RELEASE)" ./scripts/make-alpine-kernel.sh $(ARGS) rootfs-alpine: BANGER_MANUAL_DIR="$(abspath $(BUILD_MANUAL_DIR))" ALPINE_RELEASE="$(ALPINE_RELEASE)" BANGER_BIN="$(abspath $(BANGER_BIN))" ./scripts/make-rootfs-alpine.sh $(ARGS) alpine-register: build BANGER_MANUAL_DIR="$(abspath $(BUILD_MANUAL_DIR))" ALPINE_IMAGE_NAME="$(ALPINE_IMAGE_NAME)" BANGER_BIN="$(abspath $(BANGER_BIN))" ./scripts/register-alpine-image.sh alpine-vm: alpine-register "$(abspath $(BANGER_BIN))" vm create --image "$(ALPINE_IMAGE_NAME)" --name "$(ALPINE_VM_NAME)" verify-alpine: alpine-register BANGER_BIN="$(abspath $(BANGER_BIN))" ./scripts/verify.sh --image "$(ALPINE_IMAGE_NAME)"