Source file src/go/internal/gccgoimporter/gccgoinstallation.go

     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  package gccgoimporter
     6  
     7  import (
     8  	"bufio"
     9  	"go/types"
    10  	exec "internal/execabs"
    11  	"os"
    12  	"path/filepath"
    13  	"strings"
    14  )
    15  
    16  // Information about a specific installation of gccgo.
    17  type GccgoInstallation struct {
    18  	// Version of gcc (e.g. 4.8.0).
    19  	GccVersion string
    20  
    21  	// Target triple (e.g. x86_64-unknown-linux-gnu).
    22  	TargetTriple string
    23  
    24  	// Built-in library paths used by this installation.
    25  	LibPaths []string
    26  }
    27  
    28  // Ask the driver at the given path for information for this GccgoInstallation.
    29  // The given arguments are passed directly to the call of the driver.
    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  // Return the list of export search paths for this GccgoInstallation.
    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  // Return an importer that searches incpaths followed by the gcc installation's
    94  // built-in search paths and the current directory.
    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