From 745a68a771aaf9745f54dd9cdfde5f97d1f75346 Mon Sep 17 00:00:00 2001 From: liqianjie <3745983@qq.com> Date: Tue, 24 Mar 2026 17:26:47 +0800 Subject: [PATCH] feat: add Android build target and improve Android compatibility - Makefile: add build-android target to compile picoclaw and picoclaw-launcher for Android ARM64 - Makefile: output both binaries and copy as .so files for Android integration - dns_noresolv: change default DNS servers to Alibaba (223.5.5.5) and Tencent (119.29.29.29) - agent: skip exec tool initialization on Android (no shell available) --- Makefile | 17 +++++++++++++++++ cmd/picoclaw/dns_noresolv.go | 3 ++- pkg/agent/instance.go | 22 +++++++++++++++++----- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 411cd9dc5..3988d30cd 100644 --- a/Makefile +++ b/Makefile @@ -165,6 +165,23 @@ build-linux-mipsle: generate $(call PATCH_MIPS_FLAGS,$(BUILD_DIR)/$(BINARY_NAME)-linux-mipsle) @echo "Build complete: $(BUILD_DIR)/$(BINARY_NAME)-linux-mipsle" +## build-android: Build picoclaw + picoclaw-launcher for Android (ARM64) +build-android: generate + @echo "Building $(BINARY_NAME) for Android (linux/arm64)..." + @mkdir -p $(BUILD_DIR) + GOOS=linux GOARCH=arm64 $(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 ./$(CMD_DIR) + @cp $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 $(BUILD_DIR)/libpicoclaw.so + @echo "Build complete: $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 -> libpicoclaw.so" + @echo "" + @echo "Building picoclaw-launcher for Android (linux/arm64)..." + @if [ ! -f web/backend/dist/index.html ]; then \ + echo "Building frontend..."; \ + cd web/frontend && pnpm install && pnpm build:backend; \ + fi + GOOS=linux GOARCH=arm64 $(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/picoclaw-launcher-linux-arm64 ./web/backend + @cp $(BUILD_DIR)/picoclaw-launcher-linux-arm64 $(BUILD_DIR)/libpicoclaw-web.so + @echo "Build complete: $(BUILD_DIR)/picoclaw-launcher-linux-arm64 -> libpicoclaw-web.so" + ## build-pi-zero: Build for Raspberry Pi Zero 2 W (32-bit and 64-bit) build-pi-zero: build-linux-arm build-linux-arm64 @echo "Pi Zero 2 W builds: $(BUILD_DIR)/$(BINARY_NAME)-linux-arm (32-bit), $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 (64-bit)" diff --git a/cmd/picoclaw/dns_noresolv.go b/cmd/picoclaw/dns_noresolv.go index ba4ae1f4f..970aec0b4 100644 --- a/cmd/picoclaw/dns_noresolv.go +++ b/cmd/picoclaw/dns_noresolv.go @@ -20,7 +20,8 @@ func init() { // 例如: PICOCLAW_DNS_SERVER="8.8.8.8:53;1.1.1.1:53;223.5.5.5:53" dnsEnv := os.Getenv("PICOCLAW_DNS_SERVER") if dnsEnv == "" { - dnsEnv = "8.8.8.8:53;1.1.1.1:53" + // 默认使用阿里 DNS 和腾讯 DNS + dnsEnv = "223.5.5.5:53;119.29.29.29:53" } var dnsServers []string diff --git a/pkg/agent/instance.go b/pkg/agent/instance.go index 34d401186..0fa6a724e 100644 --- a/pkg/agent/instance.go +++ b/pkg/agent/instance.go @@ -83,12 +83,16 @@ func NewAgentInstance( toolsRegistry.Register(tools.NewListDirTool(workspace, readRestrict, allowReadPaths)) } if cfg.Tools.IsToolEnabled("exec") { - execTool, err := tools.NewExecToolWithConfig(workspace, restrict, cfg, allowReadPaths) - if err != nil { - logger.ErrorCF("agent", "Failed to initialize exec tool; continuing without exec", - map[string]any{"error": err.Error()}) + if isAndroid() { + logger.InfoCF("agent", "Skipping exec tool on Android (no shell available)", nil) } else { - toolsRegistry.Register(execTool) + execTool, err := tools.NewExecToolWithConfig(workspace, restrict, cfg, allowReadPaths) + if err != nil { + logger.ErrorCF("agent", "Failed to initialize exec tool; continuing without exec", + map[string]any{"error": err.Error()}) + } else { + toolsRegistry.Register(execTool) + } } } @@ -321,3 +325,11 @@ func expandHome(path string) string { } return path } + +// isAndroid 检测当前是否运行在 Android 环境中。 +// Android 上 GOOS=linux,无法通过 runtime.GOOS 区分, +// 因此通过检查 Android 特有的 /system/build.prop 文件来判断。 +func isAndroid() bool { + _, err := os.Stat("/system/build.prop") + return err == nil +}