package harness import ( "fmt" "os" "os/exec" "path/filepath" "runtime" "sync" ) var ( binOnce sync.Once binPath string binErr error ) // Binary 返回已编译好的 nixmsg 可执行文件路径(整个进程只编译一次)。 func Binary() (string, error) { binOnce.Do(func() { root, err := moduleRoot() if err != nil { binErr = err return } dir, err := os.MkdirTemp("", "nixmsg-harness-bin-*") if err != nil { binErr = err return } name := "nixmsg" if runtime.GOOS == "windows" { name += ".exe" } out := filepath.Join(dir, name) cmd := exec.Command("go", "build", "-o", out, "./cmd/nixmsg") cmd.Dir = root cmd.Env = append(os.Environ(), "CGO_ENABLED=0") if outBytes, runErr := cmd.CombinedOutput(); runErr != nil { binErr = fmt.Errorf("build nixmsg: %w\n%s", runErr, outBytes) return } binPath = out }) return binPath, binErr } func moduleRoot() (string, error) { dir, err := os.Getwd() if err != nil { return "", err } for { if _, statErr := os.Stat(filepath.Join(dir, "go.mod")); statErr == nil { return dir, nil } parent := filepath.Dir(dir) if parent == dir { return "", fmt.Errorf("go.mod not found from %s", dir) } dir = parent } }