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  }