feat(build): add Windows platform support to Makefile

- Add Windows detection for Git Bash, MSYS2, and Cygwin environments
- Introduce EXE variable for platform-specific executable extensions (.exe on Windows)
- Update build targets to conditionally set GOOS=windows GOARCH=amd64 for Windows builds
- Replace symlinks with file copies for Windows compatibility in build and build-launcher targets
- Update binary path references throughout Makefile to include EXE extension
- Ensure install and uninstall targets handle Windows executable extensions correctly
- Improve cross-platform build consistency and Windows developer experience
This commit is contained in:
H-H1 2026-03-26 19:58:19 +08:00
parent 4d7a629b79
commit e52225bba9

View file

@ -57,12 +57,21 @@ WORKSPACE_SKILLS_DIR=$(WORKSPACE_DIR)/skills
BUILTIN_SKILLS_DIR=$(CURDIR)/skills BUILTIN_SKILLS_DIR=$(CURDIR)/skills
# OS detection # OS detection
# Git Bash on Windows reports MINGW64_NT-* or MSYS_NT-*
UNAME_S:=$(shell uname -s) UNAME_S:=$(shell uname -s)
UNAME_M:=$(shell uname -m) UNAME_M:=$(shell uname -m)
# Detect Windows (Git Bash / MSYS2)
IS_WINDOWS:=$(if $(findstring MINGW,$(UNAME_S)),yes,$(if $(findstring MSYS,$(UNAME_S)),yes,$(if $(findstring CYGWIN,$(UNAME_S)),yes,no)))
# Platform-specific settings # Platform-specific settings
ifeq ($(UNAME_S),Linux) ifeq ($(IS_WINDOWS),yes)
PLATFORM=windows
ARCH=amd64
EXE=.exe
else ifeq ($(UNAME_S),Linux)
PLATFORM=linux PLATFORM=linux
EXE=
ifeq ($(UNAME_M),x86_64) ifeq ($(UNAME_M),x86_64)
ARCH=amd64 ARCH=amd64
else ifeq ($(UNAME_M),aarch64) else ifeq ($(UNAME_M),aarch64)
@ -80,6 +89,7 @@ ifeq ($(UNAME_S),Linux)
endif endif
else ifeq ($(UNAME_S),Darwin) else ifeq ($(UNAME_S),Darwin)
PLATFORM=darwin PLATFORM=darwin
EXE=
WEB_GO=CGO_ENABLED=1 go WEB_GO=CGO_ENABLED=1 go
ifeq ($(UNAME_M),x86_64) ifeq ($(UNAME_M),x86_64)
ARCH=amd64 ARCH=amd64
@ -91,9 +101,10 @@ else ifeq ($(UNAME_S),Darwin)
else else
PLATFORM=$(UNAME_S) PLATFORM=$(UNAME_S)
ARCH=$(UNAME_M) ARCH=$(UNAME_M)
EXE=
endif endif
BINARY_PATH=$(BUILD_DIR)/$(BINARY_NAME)-$(PLATFORM)-$(ARCH) BINARY_PATH=$(BUILD_DIR)/$(BINARY_NAME)-$(PLATFORM)-$(ARCH)$(EXE)
# Default target # Default target
all: build all: build
@ -109,9 +120,14 @@ generate:
build: generate build: generate
@echo "Building $(BINARY_NAME) for $(PLATFORM)/$(ARCH)..." @echo "Building $(BINARY_NAME) for $(PLATFORM)/$(ARCH)..."
@mkdir -p $(BUILD_DIR) @mkdir -p $(BUILD_DIR)
ifeq ($(IS_WINDOWS),yes)
@GOOS=windows GOARCH=amd64 $(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $(BINARY_PATH) ./$(CMD_DIR)
@cp $(BINARY_PATH) $(BUILD_DIR)/$(BINARY_NAME)$(EXE)
else
@$(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $(BINARY_PATH) ./$(CMD_DIR) @$(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $(BINARY_PATH) ./$(CMD_DIR)
@ln -sf $(BINARY_NAME)-$(PLATFORM)-$(ARCH)$(EXE) $(BUILD_DIR)/$(BINARY_NAME)$(EXE)
endif
@echo "Build complete: $(BINARY_PATH)" @echo "Build complete: $(BINARY_PATH)"
@ln -sf $(BINARY_NAME)-$(PLATFORM)-$(ARCH) $(BUILD_DIR)/$(BINARY_NAME)
## build-launcher: Build the picoclaw-launcher (web console) binary ## build-launcher: Build the picoclaw-launcher (web console) binary
build-launcher: build-launcher:
@ -121,9 +137,14 @@ build-launcher:
echo "Building frontend..."; \ echo "Building frontend..."; \
cd web/frontend && pnpm install && pnpm build:backend; \ cd web/frontend && pnpm install && pnpm build:backend; \
fi fi
@$(WEB_GO) build $(GOFLAGS) -o $(BUILD_DIR)/picoclaw-launcher-$(PLATFORM)-$(ARCH) ./web/backend ifeq ($(IS_WINDOWS),yes)
@ln -sf picoclaw-launcher-$(PLATFORM)-$(ARCH) $(BUILD_DIR)/picoclaw-launcher @GOOS=windows GOARCH=amd64 $(WEB_GO) build $(GOFLAGS) -o $(BUILD_DIR)/picoclaw-launcher-$(PLATFORM)-$(ARCH)$(EXE) ./web/backend
@echo "Build complete: $(BUILD_DIR)/picoclaw-launcher" @cp $(BUILD_DIR)/picoclaw-launcher-$(PLATFORM)-$(ARCH)$(EXE) $(BUILD_DIR)/picoclaw-launcher$(EXE)
else
@$(WEB_GO) build $(GOFLAGS) -o $(BUILD_DIR)/picoclaw-launcher-$(PLATFORM)-$(ARCH)$(EXE) ./web/backend
@ln -sf picoclaw-launcher-$(PLATFORM)-$(ARCH)$(EXE) $(BUILD_DIR)/picoclaw-launcher$(EXE)
endif
@echo "Build complete: $(BUILD_DIR)/picoclaw-launcher$(EXE)"
## build-whatsapp-native: Build with WhatsApp native (whatsmeow) support; larger binary ## build-whatsapp-native: Build with WhatsApp native (whatsmeow) support; larger binary
build-whatsapp-native: generate build-whatsapp-native: generate
@ -192,17 +213,17 @@ install: build
@echo "Installing $(BINARY_NAME)..." @echo "Installing $(BINARY_NAME)..."
@mkdir -p $(INSTALL_BIN_DIR) @mkdir -p $(INSTALL_BIN_DIR)
# Copy binary with temporary suffix to ensure atomic update # Copy binary with temporary suffix to ensure atomic update
@cp $(BUILD_DIR)/$(BINARY_NAME) $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX) @cp $(BUILD_DIR)/$(BINARY_NAME)$(EXE) $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX)$(EXE)
@chmod +x $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX) @chmod +x $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX)$(EXE)
@mv -f $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX) $(INSTALL_BIN_DIR)/$(BINARY_NAME) @mv -f $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX)$(EXE) $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(EXE)
@echo "Installed binary to $(INSTALL_BIN_DIR)/$(BINARY_NAME)" @echo "Installed binary to $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(EXE)"
@echo "Installation complete!" @echo "Installation complete!"
## uninstall: Remove picoclaw from system ## uninstall: Remove picoclaw from system
uninstall: uninstall:
@echo "Uninstalling $(BINARY_NAME)..." @echo "Uninstalling $(BINARY_NAME)..."
@rm -f $(INSTALL_BIN_DIR)/$(BINARY_NAME) @rm -f $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(EXE)
@echo "Removed binary from $(INSTALL_BIN_DIR)/$(BINARY_NAME)" @echo "Removed binary from $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(EXE)"
@echo "Note: Only the executable file has been deleted." @echo "Note: Only the executable file has been deleted."
@echo "If you need to delete all configurations (config.json, workspace, etc.), run 'make uninstall-all'" @echo "If you need to delete all configurations (config.json, workspace, etc.), run 'make uninstall-all'"
@ -257,7 +278,7 @@ check: deps fmt vet test
## run: Build and run picoclaw ## run: Build and run picoclaw
run: build run: build
@$(BUILD_DIR)/$(BINARY_NAME) $(ARGS) @$(BUILD_DIR)/$(BINARY_NAME)$(EXE) $(ARGS)
## docker-build: Build Docker image (minimal Alpine-based) ## docker-build: Build Docker image (minimal Alpine-based)
docker-build: docker-build: