github.com/v2fly/tools@v0.100.0/go/internal/gccgoimporter/gccgoinstallation.go (about) 1 // Copyright 2013 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 // Except for this comment, this file is a verbatim copy of the file 6 // with the same name in $GOROOT/src/go/internal/gccgoimporter. 7 8 package gccgoimporter 9 10 import ( 11 "bufio" 12 "go/types" 13 exec "golang.org/x/sys/execabs" 14 "os" 15 "path/filepath" 16 "strings" 17 ) 18 19 // Information about a specific installation of gccgo. 20 type GccgoInstallation struct { 21 // Version of gcc (e.g. 4.8.0). 22 GccVersion string 23 24 // Target triple (e.g. x86_64-unknown-linux-gnu). 25 TargetTriple string 26 27 // Built-in library paths used by this installation. 28 LibPaths []string 29 } 30 31 // Ask the driver at the given path for information for this GccgoInstallation. 32 // The given arguments are passed directly to the call of the driver. 33 func (inst *GccgoInstallation) InitFromDriver(gccgoPath string, args ...string) (err error) { 34 argv := append([]string{"-###", "-S", "-x", "go", "-"}, args...) 35 cmd := exec.Command(gccgoPath, argv...) 36 stderr, err := cmd.StderrPipe() 37 if err != nil { 38 return 39 } 40 41 err = cmd.Start() 42 if err != nil { 43 return 44 } 45 46 scanner := bufio.NewScanner(stderr) 47 for scanner.Scan() { 48 line := scanner.Text() 49 switch { 50 case strings.HasPrefix(line, "Target: "): 51 inst.TargetTriple = line[8:] 52 53 case line[0] == ' ': 54 args := strings.Fields(line) 55 for _, arg := range args[1:] { 56 if strings.HasPrefix(arg, "-L") { 57 inst.LibPaths = append(inst.LibPaths, arg[2:]) 58 } 59 } 60 } 61 } 62 63 argv = append([]string{"-dumpversion"}, args...) 64 stdout, err := exec.Command(gccgoPath, argv...).Output() 65 if err != nil { 66 return 67 } 68 inst.GccVersion = strings.TrimSpace(string(stdout)) 69 70 return 71 } 72 73 // Return the list of export search paths for this GccgoInstallation. 74 func (inst *GccgoInstallation) SearchPaths() (paths []string) { 75 for _, lpath := range inst.LibPaths { 76 spath := filepath.Join(lpath, "go", inst.GccVersion) 77 fi, err := os.Stat(spath) 78 if err != nil || !fi.IsDir() { 79 continue 80 } 81 paths = append(paths, spath) 82 83 spath = filepath.Join(spath, inst.TargetTriple) 84 fi, err = os.Stat(spath) 85 if err != nil || !fi.IsDir() { 86 continue 87 } 88 paths = append(paths, spath) 89 } 90 91 paths = append(paths, inst.LibPaths...) 92 93 return 94 } 95 96 // Return an importer that searches incpaths followed by the gcc installation's 97 // built-in search paths and the current directory. 98 func (inst *GccgoInstallation) GetImporter(incpaths []string, initmap map[*types.Package]InitData) Importer { 99 return GetImporter(append(append(incpaths, inst.SearchPaths()...), "."), initmap) 100 }