BINARY := latchd SRC_DIR := src CMD_DIR := $(SRC_DIR) BUILD_DIR := build PREFIX ?= /usr BINDIR := $(DESTDIR)$(PREFIX)/bin CONFDIR := $(DESTDIR)/etc/$(BINARY) SYSTEMD := $(DESTDIR)/usr/lib/systemd/system VERSION ?= 0.1.0 COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") BUILDDATE := $(shell date -u '+%Y-%m-%d_%H:%M:%S') LDFLAGS := -s -w \ -X main.Version=$(VERSION) \ -X main.Commit=$(COMMIT) \ -X main.BuildTime=$(BUILDDATE) GO := go GOFLAGS := -trimpath -ldflags="$(LDFLAGS)" ## ansi helpers BOLD := \033[1m DIM := \033[2m RED := \033[31m GREEN := \033[32m YELLOW := \033[33m BLUE := \033[34m CYAN := \033[36m WHITE := \033[37m RST := \033[0m ## ─── targets ──────────────────────────────────────────────── .PHONY: all deps build install uninstall clean test lint fmt vet \ run-preview release enable update help deps: ## install system dependencies @printf " $(BLUE)%-10s$(RST) checking dependencies...\n" "DEPS" @if ! dpkg -s libpam0g-dev >/dev/null 2>&1; then \ printf " $(YELLOW)%-10s$(RST) sudo apt install -y libpam0g-dev\n" ""; \ sudo apt install -y libpam0g-dev; \ fi @if ! dpkg -s build-essential >/dev/null 2>&1; then \ printf " $(YELLOW)%-10s$(RST) sudo apt install -y build-essential\n" ""; \ sudo apt install -y build-essential; \ fi @if ! command -v go >/dev/null 2>&1; then \ printf " $(RED)%-10s$(RST) go not found — install go 1.22+\n" ""; \ exit 1; \ fi @printf " $(GREEN)%-10s$(RST) dependencies ok\n" "DEPS" all: build ## build the release binary build: $(BUILD_DIR)/$(BINARY) ## compile latchd $(BUILD_DIR)/$(BINARY): $(shell find $(SRC_DIR) -name '*.go') @printf " $(CYAN)%-10s$(RST) %s\n" "GO" "$@" @mkdir -p $(BUILD_DIR) @cd $(SRC_DIR) && $(GO) build $(GOFLAGS) -o ../$@ . install: build ## install to $(PREFIX) @printf " $(GREEN)%-10s$(RST) %s\n" "INSTALL" "$(BINDIR)/$(BINARY)" @install -Dm755 $(BUILD_DIR)/$(BINARY) $(BINDIR)/$(BINARY) @install -Dm644 extra/config.toml $(CONFDIR)/config.toml @install -Dm755 extra/xsetup.sh $(CONFDIR)/xsetup.sh @install -Dm644 extra/lemurs.pam $(DESTDIR)/etc/pam.d/$(BINARY) @install -Dm644 extra/lemurs.service $(SYSTEMD)/$(BINARY).service @mkdir -p $(CONFDIR)/wms $(CONFDIR)/wayland @printf " $(GREEN)%-10s$(RST) done — run 'systemctl enable $(BINARY)' to activate\n" "INSTALL" uninstall: ## remove installed files @printf " $(RED)%-10s$(RST) %s\n" "RM" "$(BINDIR)/$(BINARY)" @rm -f $(BINDIR)/$(BINARY) @rm -rf $(CONFDIR) @rm -f $(DESTDIR)/etc/pam.d/$(BINARY) @rm -f $(SYSTEMD)/$(BINARY).service clean: ## remove build artifacts @printf " $(RED)%-10s$(RST) %s\n" "RM" "$(BUILD_DIR)" @rm -rf $(BUILD_DIR) test: ## run tests @printf " $(YELLOW)%-10s$(RST) running tests...\n" "TEST" @cd $(SRC_DIR) && $(GO) test ./... lint: ## run linter @printf " $(YELLOW)%-10s$(RST) linting...\n" "LINT" @golangci-lint run $(SRC_DIR)/... 2>/dev/null || printf " $(DIM)%-10s$(RST) golangci-lint not found; skipping\n" "" fmt: ## format source @printf " $(BLUE)%-10s$(RST) formatting...\n" "FMT" @cd $(SRC_DIR) && $(GO) fmt ./... vet: ## run go vet @printf " $(YELLOW)%-10s$(RST) vetting...\n" "VET" @cd $(SRC_DIR) && $(GO) vet ./... run-preview: build ## launch preview mode @printf " $(GREEN)%-10s$(RST) starting preview...\n" "RUN" @./$(BUILD_DIR)/$(BINARY) --preview --no-log release: clean ## build with version info @printf " $(BOLD)$(CYAN)╔══════════════════════════════════════╗$(RST)\n" @printf " $(BOLD)$(CYAN)║ latchd $(VERSION) — release build ║$(RST)\n" @printf " $(BOLD)$(CYAN)╚══════════════════════════════════════╝$(RST)\n" @printf "\n" @printf " $(DIM)commit$(RST) $(COMMIT)\n" @printf " $(DIM)built$(RST) $(BUILDDATE)\n" @printf "\n" @$(MAKE) build enable: ## disable other DM + enable latchd @printf " $(YELLOW)%-10s$(RST) switching to latchd...\n" "ENABLE" @if systemctl is-active display-manager.service >/dev/null 2>&1; then \ printf " $(DIM)%-10s$(RST) stopping current display manager\n" ""; \ sudo systemctl stop display-manager.service; \ fi @if [ -L /etc/systemd/system/display-manager.service ] \ && ! readlink /etc/systemd/system/display-manager.service | grep -q $(BINARY); then \ printf " $(DIM)%-10s$(RST) disabling aliased display manager\n" ""; \ sudo systemctl disable display-manager.service; \ fi @sudo systemctl enable $(BINARY).service @printf " $(GREEN)%-10s$(RST) latchd enabled — reboot or run 'sudo systemctl start latchd'\n" "ENABLE" update: ## uninstall → git pull → rebuild → reinstall @printf " $(YELLOW)%-10s$(RST) removing previous install...\n" "UPDATE" @sudo $(MAKE) uninstall @printf " $(CYAN)%-10s$(RST) pulling latest...\n" "UPDATE" @git pull @printf " $(BLUE)%-10s$(RST) rebuilding...\n" "UPDATE" @sudo $(MAKE) install @printf " $(GREEN)%-10s$(RST) updated — run 'sudo make enable' to switch DMs\n" "UPDATE" help: ## print this help @printf " $(BOLD)latchd$(RST) — tui display manager\n" @printf " $(DIM)version $(VERSION) commit $(COMMIT)$(RST)\n" @printf "\n" @printf " $(WHITE)targets:$(RST)\n" @awk -F ':|##' '/^[a-zA-Z].*:.*##/ { \ printf " $(CYAN)%-16s$(RST) %s\n", $$1, $$NF }' $(MAKEFILE_LIST) \ | sort @printf "\n"