# SPDX-License-Identifier: GPL-3.0-or-later # Works with GNU make and BSD make. DESTDIR ?= PREFIX ?= $(HOME)/.local BINDIR = $(DESTDIR)$(PREFIX)/bin SHAREDIR = $(DESTDIR)$(PREFIX)/share MANDIR = $(SHAREDIR)/man DOCDIR = $(SHAREDIR)/doc/krino BIN = krino VERSION != git describe --tags --always --dirty 2>/dev/null || echo dev LDFLAGS = -s -w -X main.version=$(VERSION) CROSS_PLATFORMS = linux/amd64 linux/arm64 freebsd/amd64 openbsd/amd64 .PHONY: all help build install uninstall test vet fmt lint ci bench cross dist release deps install-hooks clean all: build help: ## show this help @grep -E '^[a-z-]+:.*## ' Makefile | \ awk 'BEGIN {FS = ":.*## "}; {printf " %-10s %s\n", $$1, $$2}' @echo " version: $(VERSION) prefix: $(PREFIX)" build: ## build ./krino; Go fetches module dependencies itself; reports missing optional extractors CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN) ./cmd/krino @missing=""; \ for t in pdftotext antiword catdoc xls2csv catppt; do \ command -v "$$t" >/dev/null 2>&1 || missing="$$missing $$t"; \ done; \ if [ -n "$$missing" ]; then \ echo "optional extractors not found:$$missing (needed for some content rules; run 'make deps' or install by hand)"; \ else \ echo "all optional extractors found: pdftotext antiword catdoc xls2csv catppt"; \ fi install: build ## install binary, man pages and examples under $(PREFIX) mkdir -p $(BINDIR) $(MANDIR)/man1 $(MANDIR)/man5 $(DOCDIR)/examples rm -f $(BINDIR)/$(BIN) install -m 755 $(BIN) $(BINDIR)/$(BIN) install -m 644 man/krino.1 $(MANDIR)/man1/krino.1 install -m 644 man/krino.conf.5 $(MANDIR)/man5/krino.conf.5 install -m 644 examples/*.conf $(DOCDIR)/examples/ install -m 644 docs/sexp-primer.md $(DOCDIR)/sexp-primer.md uninstall: ## remove everything install placed, and nothing else rm -f $(BINDIR)/$(BIN) rm -f $(MANDIR)/man1/krino.1 rm -f $(MANDIR)/man5/krino.conf.5 rm -f $(DOCDIR)/sexp-primer.md for f in examples/*.conf; do \ rm -f $(DOCDIR)/examples/$$(basename "$$f"); \ done -rmdir $(DOCDIR)/examples $(DOCDIR) 2>/dev/null test: ## run the tests go test ./... vet: ## go vet go vet ./... fmt: ## gofmt the tree gofmt -w . lint: ## lint the man pages scripts/man-lint ci: ## the gate: gofmt, vet, tests, dependencies, no personal data staged, man page lint @test -z "$$(gofmt -l .)" || { echo "gofmt needed:"; gofmt -l .; exit 1; } go vet ./... GOOS=freebsd CGO_ENABLED=0 go vet ./... GOOS=openbsd CGO_ENABLED=0 go vet ./... go test ./... @deps=$$(go list -deps ./... | grep -E '^[a-z0-9-]+\.[a-z]+/' | grep -vE '^golang\.org/x/(term|text|sys)(/|$$)' || true); \ test -z "$$deps" || { echo "unexpected dependencies:"; echo "$$deps"; exit 1; } @scripts/leak-check @scripts/man-lint @echo "ci ok" bench: ## run the Go benchmarks on generated trees go test -run '^$$' -bench . -benchmem ./... cross: ## cross-compile linux/amd64, linux/arm64, freebsd/amd64, openbsd/amd64 into dist/krino-$(VERSION)--/ @case '$(VERSION)' in \ ''|*[!A-Za-z0-9._+-]*) \ echo "refusing: VERSION must contain only letters, digits, and the characters . - _ +" >&2; \ exit 1 ;; \ esac @for t in $(CROSS_PLATFORMS); do \ os=$${t%/*}; arch=$${t#*/}; \ dir=dist/krino-$(VERSION)-$$os-$$arch; \ case "$$dir" in \ dist/krino-*) rm -rf "$$dir" ;; \ *) echo "refusing to remove unexpected path: $$dir" >&2; exit 1 ;; \ esac; \ mkdir -p "$$dir"; \ echo "cross: $$os/$$arch -> $$dir/$(BIN)"; \ CGO_ENABLED=0 GOOS=$$os GOARCH=$$arch go build -trimpath -ldflags "$(LDFLAGS)" -o "$$dir/$(BIN)" ./cmd/krino || exit 1; \ for f in README.md LICENSE CHANGELOG.md man/krino.1 man/krino.conf.5 docs/sexp-primer.md; do \ test -f "$$f" && cp "$$f" "$$dir/$$(basename "$$f")"; \ done; \ test -d examples && cp -r examples "$$dir/examples"; \ done # dist: cross plus tarballs and SHA256SUMS, no tag. Undocumented plumbing so # `make release` is verifiable without tagging; deliberately absent from # `make help` (no `## ` comment). dist: cross @command -v sha256sum >/dev/null 2>&1 && SUM=sha256sum || SUM="sha256 -r"; \ tarballs=""; \ cd dist && \ for t in $(CROSS_PLATFORMS); do \ os=$${t%/*}; arch=$${t#*/}; \ name=krino-$(VERSION)-$$os-$$arch; \ tar czf "$$name.tar.gz" "$$name" || exit 1; \ tarballs="$$tarballs $$name.tar.gz"; \ done && \ $$SUM $$tarballs > SHA256SUMS release: ## make cross + tarballs + SHA256SUMS in dist/, then tag v$(VERSION) (annotated; never pushes) - usage: make release VERSION=0.0.1 @case '$(VERSION)' in \ ''|*[!A-Za-z0-9._+-]*) \ echo "refusing: VERSION must contain only letters, digits, and the characters . - _ +" >&2; \ exit 1 ;; \ esac @default_version=$$(git describe --tags --always --dirty 2>/dev/null || echo dev); \ test -n "$(VERSION)" && test "$(VERSION)" != "$$default_version" || \ { echo "refusing: pass an explicit VERSION, e.g. make release VERSION=0.0.1"; exit 1; } @test -z "$$(git status --porcelain)" || \ { echo "refusing: working tree is not clean (git status --porcelain)"; exit 1; } @git rev-parse -q --verify refs/tags/v$(VERSION) >/dev/null 2>&1 && \ { echo "refusing: tag v$(VERSION) already exists"; exit 1; } || true @test -f README.md || \ { echo "refusing: README.md is missing"; exit 1; } $(MAKE) ci $(MAKE) dist VERSION=$(VERSION) git tag -a "v$(VERSION)" -m "krino v$(VERSION)" @echo "release v$(VERSION) built in dist/; tag v$(VERSION) created, not pushed" deps: ## install the optional content extractors; may ask for privileges scripts/deps install-hooks: ## install the pre-commit hook that runs the leak check install -m 755 scripts/hooks/pre-commit "$$(git rev-parse --git-path hooks)/pre-commit" clean: ## remove build output rm -f $(BIN)