# Makefile for p4lf — P4 Log Feeder # # Common targets: # make build Build for the current platform (output: bin/p4lf) # make test Run all unit tests # make vet Run go vet # make fmt Run gofmt check (no writes; use fmt-fix to apply) # make fmt-fix Run gofmt and rewrite files # make clean Remove build artifacts # # Cross-compilation targets: # make build-linux Linux amd64 (primary deployment target) # make build-linux-arm64 Linux arm64 # make build-darwin macOS arm64 (Apple Silicon dev machines) # make build-darwin-amd64 macOS Intel # make build-all All of the above # # Install target (Linux only, requires INSTANCE to be set): # make install INSTANCE=1 # # Release: # make release VERSION=0.2.0 Build all platforms, create dist/ tarballs # ── Variables ──────────────────────────────────────────────────────────────── MODULE := workshop.perforce.com/p4lf CMD := ./cmd/p4lf BIN_NAME := p4lf BIN_DIR := bin DIST_DIR := dist # Version: read from version.go (the hand-maintained SemVer var). # Override on the command line to inject a different value at build time: # make build VERSION=1.0.0 VERSION ?= $(shell grep -m1 '^var SemVer' internal/version/version.go | sed 's/.*"\(.*\)".*/\1/') LDFLAGS := -ldflags "-X workshop.perforce.com/p4lf/internal/version.SemVer=$(VERSION) -s -w" # Perforce: capture current default changelist number for release metadata. P4CL := $(shell p4 changes -m1 -s submitted //... 2>/dev/null | awk '{print $$2}' || echo "unknown") # ── Phony targets ───────────────────────────────────────────────────────────── .PHONY: build build-linux build-linux-arm64 build-darwin build-darwin-amd64 \ build-all test vet fmt fmt-fix clean install release help # Default target. all: build # ── Build ───────────────────────────────────────────────────────────────────── ## build: Build p4lf for the current platform → bin/p4lf build: @mkdir -p $(BIN_DIR) go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME) $(CMD) @echo "Built $(BIN_DIR)/$(BIN_NAME) ($(shell uname -s)/$(shell uname -m), v$(VERSION))" ## build-linux: Cross-compile for Linux amd64 → bin/p4lf-linux-amd64 build-linux: @mkdir -p $(BIN_DIR) GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME)-linux-amd64 $(CMD) @echo "Built $(BIN_DIR)/$(BIN_NAME)-linux-amd64 (v$(VERSION))" ## build-linux-arm64: Cross-compile for Linux arm64 → bin/p4lf-linux-arm64 build-linux-arm64: @mkdir -p $(BIN_DIR) GOOS=linux GOARCH=arm64 go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME)-linux-arm64 $(CMD) @echo "Built $(BIN_DIR)/$(BIN_NAME)-linux-arm64 (v$(VERSION))" ## build-darwin: Cross-compile for macOS arm64 (Apple Silicon) → bin/p4lf-darwin-arm64 build-darwin: @mkdir -p $(BIN_DIR) GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME)-darwin-arm64 $(CMD) @echo "Built $(BIN_DIR)/$(BIN_NAME)-darwin-arm64 (v$(VERSION))" ## build-darwin-amd64: Cross-compile for macOS Intel → bin/p4lf-darwin-amd64 build-darwin-amd64: @mkdir -p $(BIN_DIR) GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME)-darwin-amd64 $(CMD) @echo "Built $(BIN_DIR)/$(BIN_NAME)-darwin-amd64 (v$(VERSION))" ## build-all: Build for all platforms build-all: build-linux build-linux-arm64 build-darwin build-darwin-amd64 @echo "All platform builds complete." # ── Test & Quality ──────────────────────────────────────────────────────────── ## test: Run all unit tests with race detector test: go test -race -count=1 ./... ## test-verbose: Run tests with verbose output test-verbose: go test -race -count=1 -v ./... ## vet: Run go vet vet: go vet ./... ## fmt: Check formatting (does not modify files; exits non-zero if changes needed) fmt: @unformatted=$$(gofmt -l .); \ if [ -n "$$unformatted" ]; then \ echo "The following files need gofmt:"; \ echo "$$unformatted"; \ exit 1; \ else \ echo "All files are properly formatted."; \ fi ## fmt-fix: Apply gofmt to all Go source files fmt-fix: gofmt -w . ## check: Run vet + fmt + test check: vet fmt test # ── Install ─────────────────────────────────────────────────────────────────── # Installs to the SDP log_feeder directory on a Linux system. # Requires: INSTANCE variable (SDP instance number, e.g. make install INSTANCE=1) SDP_SITE_DIR := /p4/common/site/log_feeder SYSTEMD_DIR := /etc/systemd/system ## install: Install p4lf binary, config example, and systemd unit (requires root or sudo) install: build-linux @if [ -z "$(INSTANCE)" ]; then \ echo "Error: INSTANCE is required. Usage: make install INSTANCE=1"; \ exit 1; \ fi @echo "Installing p4lf to $(SDP_SITE_DIR)..." install -d $(SDP_SITE_DIR) install -m 0755 $(BIN_DIR)/$(BIN_NAME)-linux-amd64 $(SDP_SITE_DIR)/$(BIN_NAME) @if [ ! -f $(SDP_SITE_DIR)/p4lf.cfg ]; then \ install -m 0640 p4lf.cfg.example $(SDP_SITE_DIR)/p4lf.cfg; \ echo " Installed default config to $(SDP_SITE_DIR)/p4lf.cfg — please review and edit."; \ else \ echo " Config $(SDP_SITE_DIR)/p4lf.cfg already exists; not overwriting."; \ fi @echo "Installing systemd unit..." install -m 0644 p4lf.service $(SYSTEMD_DIR)/p4lf.service systemctl daemon-reload @echo "" @echo "Installation complete. Next steps:" @echo " 1. Edit $(SDP_SITE_DIR)/p4lf.cfg" @echo " 2. systemctl enable p4lf" @echo " 3. systemctl start p4lf" @echo " 4. systemctl status p4lf" # ── Release ─────────────────────────────────────────────────────────────────── ## release: Build all platforms and create dist/ tarballs release: build-all @mkdir -p $(DIST_DIR) @echo "Creating release archives for v$(VERSION) (P4CL=$(P4CL))..." @for platform in linux-amd64 linux-arm64 darwin-arm64 darwin-amd64; do \ archive=$(DIST_DIR)/$(BIN_NAME)-$(VERSION)-$$platform.tar.gz; \ tar -czf $$archive \ -C $(BIN_DIR) $(BIN_NAME)-$$platform \ p4lf.cfg.example \ p4lf.service \ install.sh \ README.md; \ echo " Created $$archive"; \ done @echo "Release archives written to $(DIST_DIR)/" # ── Clean ───────────────────────────────────────────────────────────────────── ## clean: Remove build and release artifacts clean: rm -rf $(BIN_DIR) $(DIST_DIR) @echo "Cleaned." # ── Promote ─────────────────────────────────────────────────────────────────── # Copy-up workflow: dev → main → release stream. # Run these from a //p4lf/main or //p4lf/rX.Y workspace, NOT from dev. # # After testing in dev: # p4 copy //p4lf/dev/... //p4lf/main/... # p4 submit -d "Promote vX.Y.Z from dev to main." # # To cut a release stream (replace rX.Y with the actual stream name): # p4 copy //p4lf/main/... //p4lf/rX.Y/... # # Then in the rX.Y workspace, add platform binaries: # make build-all # p4 add -t binary bin/p4lf-linux-amd64 bin/p4lf-linux-arm64 # p4 add -t binary bin/p4lf-darwin-arm64 bin/p4lf-darwin-amd64 # p4 submit -d "Release vX.Y.Z: add platform binaries." # # The //p4lf/main/bin/ binaries serve as the stable 'latest release' URL: # https://workshop.perforce.com/download/p4lf/main/bin/p4lf-linux-amd64 # # NOTE: Only promote to main code that has been tested in dev. # main should always be safe to rely on as 'latest release'. # ── Help ────────────────────────────────────────────────────────────────────── ## help: Show this help message help: @echo "p4lf Makefile — available targets:" @echo "" @grep -E '^## ' $(MAKEFILE_LIST) | sed 's/## / /' @echo "" @echo "Variables:" @echo " VERSION=$(VERSION) (override: make build VERSION=1.2.3)" @echo " INSTANCE= (required for: make install)"