1
2
3
4
5 package gccgoimporter
6
7 import (
8 "bufio"
9 "go/types"
10 exec "internal/execabs"
11 "os"
12 "path/filepath"
13 "strings"
14 )
15
16
17 type GccgoInstallation struct {
18
19 GccVersion string
20
21
22 TargetTriple string
23
24
25 LibPaths []string
26 }
27
28
29
30 func (inst *GccgoInstallation) InitFromDriver(gccgoPath string, args ...string) (err error) {
31 argv := append([]string{"-###", "-S", "-x", "go", "-"}, args...)
32 cmd := exec.Command(gccgoPath, argv...)
33 stderr, err := cmd.StderrPipe()
34 if err != nil {
35 return
36 }
37
38 err = cmd.Start()
39 if err != nil {
40 return
41 }
42
43 scanner := bufio.NewScanner(stderr)
44 for scanner.Scan() {
45 line := scanner.Text()
46 switch {
47 case strings.HasPrefix(line, "Target: "):
48 inst.TargetTriple = line[8:]
49
50 case line[0] == ' ':
51 args := strings.Fields(line)
52 for _, arg := range args[1:] {
53 if strings.HasPrefix(arg, "-L") {
54 inst.LibPaths = append(inst.LibPaths, arg[2:])
55 }
56 }
57 }
58 }
59
60 argv = append([]string{"-dumpversion"}, args...)
61 stdout, err := exec.Command(gccgoPath, argv...).Output()
62 if err != nil {
63 return
64 }
65 inst.GccVersion = strings.TrimSpace(string(stdout))
66
67 return
68 }
69
70
71 func (inst *GccgoInstallation) SearchPaths() (paths []string) {
72 for _, lpath := range inst.LibPaths {
73 spath := filepath.Join(lpath, "go", inst.GccVersion)
74 fi, err := os.Stat(spath)
75 if err != nil || !fi.IsDir() {
76 continue
77 }
78 paths = append(paths, spath)
79
80 spath = filepath.Join(spath, inst.TargetTriple)
81 fi, err = os.Stat(spath)
82 if err != nil || !fi.IsDir() {
83 continue
84 }
85 paths = append(paths, spath)
86 }
87
88 paths = append(paths, inst.LibPaths...)
89
90 return
91 }
92
93
94
95 func (inst *GccgoInstallation) GetImporter(incpaths []string, initmap map[*types.Package]InitData) Importer {
96 return GetImporter(append(append(incpaths, inst.SearchPaths()...), "."), initmap)
97 }
98
View as plain text