.PHONY: all relay client client-windows release clean test docker docker-run docker-multiarch

GOOS ?= linux
GOARCH ?= amd64
LDFLAGS := -s -w

all: relay client

relay:
	CGO_ENABLED=0 go build -ldflags="$(LDFLAGS)" -o bin/usb-relay ./cmd/usb-relay/

client:
	CGO_ENABLED=0 go build -ldflags="$(LDFLAGS)" -o bin/usb-client ./cmd/usb-client/

client-windows:
	CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="$(LDFLAGS)" -o bin/usb-client.exe ./cmd/usb-client/

test:
	go test ./...

# Cross-compiled builds. The Linux client works unchanged on every
# architecture below: sharing goes through usbdevfs and receiving through
# vhci-hcd, and neither is architecture specific.
#
#   amd64    ordinary PCs, Intel-based Synology models
#   arm64    Raspberry Pi 3/4/5 (64-bit OS), ARM Synology models, Android
#   arm      Raspberry Pi with a 32-bit OS, older ARM boards
#   386      old 32-bit x86 machines
#   mips64le, mipsle   several NAS and router platforms
#
# The relay additionally builds for macOS and Windows; it needs no USB access
# at all, so it runs anywhere Go runs.
CLIENT_TARGETS := \
	linux/amd64 \
	linux/arm64 \
	linux/arm \
	linux/386 \
	linux/mips64le \
	linux/mipsle \
	linux/riscv64 \
	windows/amd64 \
	windows/arm64

RELAY_TARGETS := \
	linux/amd64 \
	linux/arm64 \
	linux/arm \
	darwin/amd64 \
	darwin/arm64 \
	windows/amd64

release: clean
	@mkdir -p bin/release
	@for target in $(CLIENT_TARGETS); do \
		os=$${target%/*}; arch=$${target#*/}; \
		ext=""; [ "$$os" = "windows" ] && ext=".exe"; \
		echo "  client  $$os/$$arch"; \
		CGO_ENABLED=0 GOOS=$$os GOARCH=$$arch go build -ldflags="$(LDFLAGS)" \
			-o bin/release/usb-client-$$os-$$arch$$ext ./cmd/usb-client/ || exit 1; \
	done
	@for target in $(RELAY_TARGETS); do \
		os=$${target%/*}; arch=$${target#*/}; \
		ext=""; [ "$$os" = "windows" ] && ext=".exe"; \
		echo "  relay   $$os/$$arch"; \
		CGO_ENABLED=0 GOOS=$$os GOARCH=$$arch go build -ldflags="$(LDFLAGS)" \
			-o bin/release/usb-relay-$$os-$$arch$$ext ./cmd/usb-relay/ || exit 1; \
	done
	@echo "Binaries in bin/release/"

docker:
	docker compose build

docker-run:
	docker compose up -d

clean:
	rm -rf bin/

# Multi-architecture images. Needs "docker buildx create --use" once.
docker-multiarch:
	docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 \
		-f Dockerfile -t usb-server-relay:latest --load .
	docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 \
		-f Dockerfile.client -t usb-server-client:latest --load .
