// Copyright 2013 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package gccgoimporter import ( "bufio" "go/types" "os" "os/exec" "path/filepath" "strings" ) // Information about a specific installation of gccgo. type GccgoInstallation struct { // Version of gcc (e.g. 4.8.0). GccVersion string // Target triple (e.g. x86_64-unknown-linux-gnu). TargetTriple string // Built-in library paths used by this installation. LibPaths []string } // Ask the driver at the given path for information for this GccgoInstallation. // The given arguments are passed directly to the call of the driver. func (inst *GccgoInstallation) InitFromDriver(gccgoPath string, args ...string) (err error) { argv := append([]string{"-###", "-S", "-x", "go", "-"}, args...) cmd := exec.Command(gccgoPath, argv...) stderr, err := cmd.StderrPipe() if err != nil { return } err = cmd.Start() if err != nil { return } scanner := bufio.NewScanner(stderr) for scanner.Scan() { line := scanner.Text() switch { case strings.HasPrefix(line, "Target: "): inst.TargetTriple = line[8:] case line[0] == ' ': args := strings.Fields(line) for _, arg := range args[1:] { if strings.HasPrefix(arg, "-L") { inst.LibPaths = append(inst.LibPaths, arg[2:]) } } } } argv = append([]string{"-dumpversion"}, args...) stdout, err := exec.Command(gccgoPath, argv...).Output() if err != nil { return } inst.GccVersion = strings.TrimSpace(string(stdout)) return } // Return the list of export search paths for this GccgoInstallation. func (inst *GccgoInstallation) SearchPaths() (paths []string) { for _, lpath := range inst.LibPaths { spath := filepath.Join(lpath, "go", inst.GccVersion) fi, err := os.Stat(spath) if err != nil || !fi.IsDir() { continue } paths = append(paths, spath) spath = filepath.Join(spath, inst.TargetTriple) fi, err = os.Stat(spath) if err != nil || !fi.IsDir() { continue } paths = append(paths, spath) } paths = append(paths, inst.LibPaths...) return } // Return an importer that searches incpaths followed by the gcc installation's // built-in search paths and the current directory. func (inst *GccgoInstallation) GetImporter(incpaths []string, initmap map[*types.Package]InitData) Importer { return GetImporter(append(append(incpaths, inst.SearchPaths()...), "."), initmap) }