github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/internal/goroot/importcfg.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package goroot is a copy of package internal/goroot 6 // in the main GO repot. It provides a utility to produce 7 // an importcfg and import path to package file map mapping 8 // standard library packages to the locations of their export 9 // data files. 10 package goroot 11 12 import ( 13 "bytes" 14 "fmt" 15 "os/exec" 16 "strings" 17 "sync" 18 ) 19 20 // Importcfg returns an importcfg file to be passed to the 21 // Go compiler that contains the cached paths for the .a files for the 22 // standard library. 23 func Importcfg() (string, error) { 24 var icfg bytes.Buffer 25 26 m, err := PkgfileMap() 27 if err != nil { 28 return "", err 29 } 30 fmt.Fprintf(&icfg, "# import config") 31 for importPath, export := range m { 32 fmt.Fprintf(&icfg, "\npackagefile %s=%s", importPath, export) 33 } 34 s := icfg.String() 35 return s, nil 36 } 37 38 var ( 39 stdlibPkgfileMap map[string]string 40 stdlibPkgfileErr error 41 once sync.Once 42 ) 43 44 // PkgfileMap returns a map of package paths to the location on disk 45 // of the .a file for the package. 46 // The caller must not modify the map. 47 func PkgfileMap() (map[string]string, error) { 48 once.Do(func() { 49 m := make(map[string]string) 50 output, err := exec.Command("go", "list", "-export", "-e", "-f", "{{.ImportPath}} {{.Export}}", "std", "cmd").Output() 51 if err != nil { 52 stdlibPkgfileErr = err 53 } 54 for _, line := range strings.Split(string(output), "\n") { 55 if line == "" { 56 continue 57 } 58 sp := strings.SplitN(line, " ", 2) 59 if len(sp) != 2 { 60 err = fmt.Errorf("determining pkgfile map: invalid line in go list output: %q", line) 61 return 62 } 63 importPath, export := sp[0], sp[1] 64 if export != "" { 65 m[importPath] = export 66 } 67 } 68 stdlibPkgfileMap = m 69 }) 70 return stdlibPkgfileMap, stdlibPkgfileErr 71 }