github.com/JimmyHuang454/JLS-go@v0.0.0-20230831150107-90d536585ba0/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 6 7 import ( 8 "bytes" 9 "fmt" 10 "os/exec" 11 "strings" 12 "sync" 13 ) 14 15 // Importcfg returns an importcfg file to be passed to the 16 // Go compiler that contains the cached paths for the .a files for the 17 // standard library. 18 func Importcfg() (string, error) { 19 var icfg bytes.Buffer 20 21 m, err := PkgfileMap() 22 if err != nil { 23 return "", err 24 } 25 fmt.Fprintf(&icfg, "# import config") 26 for importPath, export := range m { 27 fmt.Fprintf(&icfg, "\npackagefile %s=%s", importPath, export) 28 } 29 s := icfg.String() 30 return s, nil 31 } 32 33 var ( 34 stdlibPkgfileMap map[string]string 35 stdlibPkgfileErr error 36 once sync.Once 37 ) 38 39 // PkgfileMap returns a map of package paths to the location on disk 40 // of the .a file for the package. 41 // The caller must not modify the map. 42 func PkgfileMap() (map[string]string, error) { 43 once.Do(func() { 44 m := make(map[string]string) 45 output, err := exec.Command("go", "list", "-export", "-e", "-f", "{{.ImportPath}} {{.Export}}", "std", "cmd").Output() 46 if err != nil { 47 stdlibPkgfileErr = err 48 } 49 for _, line := range strings.Split(string(output), "\n") { 50 if line == "" { 51 continue 52 } 53 sp := strings.SplitN(line, " ", 2) 54 if len(sp) != 2 { 55 stdlibPkgfileErr = fmt.Errorf("determining pkgfile map: invalid line in go list output: %q", line) 56 return 57 } 58 importPath, export := sp[0], sp[1] 59 if export != "" { 60 m[importPath] = export 61 } 62 } 63 stdlibPkgfileMap = m 64 }) 65 return stdlibPkgfileMap, stdlibPkgfileErr 66 }