...
1
2
3
4
5
6
7
8 package gccgoimporter
9
10 import (
11 "bufio"
12 "go/types"
13 "os"
14 "os/exec"
15 "path/filepath"
16 "strings"
17 )
18
19
20 type GccgoInstallation struct {
21
22 GccVersion string
23
24
25 TargetTriple string
26
27
28 LibPaths []string
29 }
30
31
32
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
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
97
98 func (inst *GccgoInstallation) GetImporter(incpaths []string, initmap map[*types.Package]InitData) Importer {
99 return GetImporter(append(append(incpaths, inst.SearchPaths()...), "."), initmap)
100 }
101
View as plain text