VERSION ?= 0.1.0 # -H windowsgui suppresses the console window that would otherwise sit behind # the tray icon. -s -w strips the symbol table and DWARF; nothing here needs a # Go stack trace off a customer's laptop, and it roughly halves the binary. LDFLAGS := -s -w -H windowsgui -X main.version=$(VERSION) # Go is installed at ~/.local/go on this box and deliberately kept off PATH, so # prefer that toolchain and fall back to whatever `go` is in PATH elsewhere. GO ?= $(shell test -x $(HOME)/.local/go/bin/go && echo $(HOME)/.local/go/bin/go || echo go) # Pinned and run through `go run` so CI needs no separate install step. GOVERSIONINFO ?= $(GO) run github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.1 SYSO := cmd/ipswap/resource_windows.syso .PHONY: build syso test vet check dist sums clean help help: ## List targets @grep -hE '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | awk 'BEGIN{FS=":.*?## "}{printf " %-14s %s\n", $$1, $$2}' # ipswap is pure Go with no cgo anywhere, which is the whole reason the tray is # fyne.io/systray and the dialogs are raw user32 rather than a GUI toolkit: # `GOOS=windows go build` cross-compiles straight from Linux, no Wine, no # mingw, no fyne-cross. build: syso ## Cross-compile bin/ipswap.exe from any host @mkdir -p bin GOOS=windows GOARCH=amd64 $(GO) build -trimpath -ldflags "$(LDFLAGS)" -o bin/ipswap.exe ./cmd/ipswap # The .syso carries the icon, the version resource and — the part that matters # — the manifest that asks for asInvoker and per-monitor DPI. A plain `go # build` with no .syso produces a binary with the generic executable icon and # the default (unaware, asInvoker-by-omission) manifest. # # -64 is not optional: goversioninfo emits a 386 object by default, and linking # that into an amd64 build fails with "unknown relocation type 7". syso: ## Generate the Windows resource object cd cmd/ipswap && $(GOVERSIONINFO) \ -64 \ -o resource_windows.syso \ -platform-specific=false \ versioninfo.json test: ## Run tests $(GO) test ./... vet: ## Run go vet for both targets $(GO) vet ./... GOOS=windows GOARCH=amd64 $(GO) vet ./... # The Windows-only files (netsh, user32, the registry) are the bulk of the # risk, and a Linux `go build` never looks at them. This is the cheap way to # keep them compiling. check: test vet ## Typecheck both targets and run tests GOOS=windows GOARCH=amd64 $(GO) build ./... dist: build sums ## Build the release artifacts into dist/ @echo "dist/ contains:" && ls -1 dist sums: ## Write dist/SHA256SUMS for the built binary @mkdir -p dist @cp bin/ipswap.exe dist/ipswap.exe cd dist && sha256sum ipswap.exe > SHA256SUMS @cat dist/SHA256SUMS clean: ## Remove build artifacts rm -rf bin dist $(SYSO)