diff --git a/go/private/actions/stdlib.bzl b/go/private/actions/stdlib.bzl index 1011404e7c..abacbc8079 100644 --- a/go/private/actions/stdlib.bzl +++ b/go/private/actions/stdlib.bzl @@ -65,9 +65,11 @@ def _should_use_sdk_stdlib(go): def _build_stdlib_list_json(go): out = go.declare_file(go, "stdlib.pkg.json") + cache_dir = go.declare_directory(go, "gocache") args = go.builder_args(go, "stdliblist") args.add("-sdk", go.sdk.root_file.dirname) args.add("-out", out) + args.add("-cache", cache_dir.path) inputs = go.sdk_files if not go.mode.pure: @@ -75,7 +77,7 @@ def _build_stdlib_list_json(go): go.actions.run( inputs = inputs, - outputs = [out], + outputs = [out, cache_dir], mnemonic = "GoStdlibList", executable = go.toolchain._builder, arguments = [args], diff --git a/go/tools/builders/stdliblist.go b/go/tools/builders/stdliblist.go index f6a614427b..32f217f36f 100644 --- a/go/tools/builders/stdliblist.go +++ b/go/tools/builders/stdliblist.go @@ -139,18 +139,18 @@ func absoluteSourcesPaths(cloneBase, pkgDir string, srcs []string) []string { // extension (which are from the cache). This is a work around for // https://golang.org/issue/28749: cmd/go puts assembly, C, and C++ files in // CompiledGoFiles. -func filterGoFiles(srcs []string) []string { +func filterGoFiles(srcs []string, pathReplaceFn func(p string) string) []string { ret := make([]string, 0, len(srcs)) for _, f := range srcs { if ext := filepath.Ext(f); ext == ".go" || ext == "" { - ret = append(ret, f) + ret = append(ret, pathReplaceFn(f)) } } return ret } -func flatPackageForStd(cloneBase string, pkg *goListPackage) *flatPackage { +func flatPackageForStd(cloneBase string, pkg *goListPackage, pathReplaceFn func(p string) string) *flatPackage { goFiles := absoluteSourcesPaths(cloneBase, pkg.Dir, pkg.GoFiles) compiledGoFiles := absoluteSourcesPaths(cloneBase, pkg.Dir, pkg.CompiledGoFiles) @@ -162,7 +162,7 @@ func flatPackageForStd(cloneBase string, pkg *goListPackage) *flatPackage { Imports: map[string]string{}, Standard: pkg.Standard, GoFiles: goFiles, - CompiledGoFiles: filterGoFiles(compiledGoFiles), + CompiledGoFiles: filterGoFiles(compiledGoFiles, pathReplaceFn), } // imports @@ -194,6 +194,7 @@ func stdliblist(args []string) error { flags := flag.NewFlagSet("stdliblist", flag.ExitOnError) goenv := envFlags(flags) out := flags.String("out", "", "Path to output go list json") + cachePath := flags.String("cache", "", "Path to use for GOCACHE") if err := flags.Parse(args); err != nil { return err } @@ -250,10 +251,10 @@ func stdliblist(args []string) error { os.Setenv("CC", quotePathIfNeeded(abs(ccEnv))) // We want to keep the cache around so that the processed files can be used by other tools. - cachePath := abs(*out + ".gocache") - os.Setenv("GOCACHE", cachePath) - os.Setenv("GOMODCACHE", cachePath) - os.Setenv("GOPATH", cachePath) + absCachePath := abs(*cachePath) + os.Setenv("GOCACHE", absCachePath) + os.Setenv("GOMODCACHE", absCachePath) + os.Setenv("GOPATH", absCachePath) listArgs := goenv.goCmd("list") if len(build.Default.BuildTags) > 0 { @@ -279,12 +280,19 @@ func stdliblist(args []string) error { encoder := json.NewEncoder(jsonFile) decoder := json.NewDecoder(jsonData) + pathReplaceFn := func (s string) string { + if strings.HasPrefix(s, absCachePath) { + return strings.Replace(s, absCachePath, filepath.Join("__BAZEL_EXECROOT__", *cachePath), 1) + } + + return s + } for decoder.More() { var pkg *goListPackage if err := decoder.Decode(&pkg); err != nil { return err } - if err := encoder.Encode(flatPackageForStd(cloneBase, pkg)); err != nil { + if err := encoder.Encode(flatPackageForStd(cloneBase, pkg, pathReplaceFn)); err != nil { return err } }