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 | } |
101 |
Members