diff --git a/go/tools/builders/compilepkg.go b/go/tools/builders/compilepkg.go index deaf82d3fd..e94e924629 100644 --- a/go/tools/builders/compilepkg.go +++ b/go/tools/builders/compilepkg.go @@ -188,19 +188,29 @@ func compileArchive( // We need to run the compiler to create a valid archive, even if there's // nothing in it. GoPack will complain if we try to add assembly or cgo // objects. + // // _empty.go needs to be in a deterministic location (not tmpdir) in order - // to ensure deterministic output - emptyPath := filepath.Join(filepath.Dir(outPath), "_empty.go") + // to ensure deterministic output. The location also needs to be unique + // otherwise platforms without sandbox support may race to create/remove + // the file during parallel compilation. + emptyDir := filepath.Join(filepath.Dir(outPath), sanitizePathForIdentifier(importPath)) + err := os.Mkdir(emptyDir, 0700) + if err != nil { + return err + } + defer os.RemoveAll(emptyDir) + emptyPath := filepath.Join(emptyDir, "_empty.go") if err := ioutil.WriteFile(emptyPath, []byte("package empty\n"), 0666); err != nil { return err } + defer os.Remove(emptyPath) + srcs.goSrcs = append(srcs.goSrcs, fileInfo{ filename: emptyPath, ext: goExt, matched: true, pkg: "empty", }) - defer os.Remove(emptyPath) } packageName := srcs.goSrcs[0].pkg var goSrcs, cgoSrcs []string