]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add -importcfg to specify import resolution
authorRuss Cox <rsc@golang.org>
Wed, 31 May 2017 15:19:54 +0000 (11:19 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 6 Jun 2017 19:49:56 +0000 (19:49 +0000)
Allows reading -importmap options from a file instead of putting
them all on the command line, and adds the ability to specify the
file location of specific packages. In effect, -importcfg is a generalization
of and supersedes -importmap, -importsuffix, and -I.
Of course, those flags will continue to be supported,
for compatibility with other tools.

Having this flag in Go 1.9 will let us try some experiments involving
package management without needing guinea pigs to build a
custom Go toolchain.

This flag also helps with #14271 at some later point.

For #20579.

Change-Id: If005dbc2b01d8fd16cbfd3687dfbe82499f4bc56
Reviewed-on: https://go-review.googlesource.com/44850
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/compile/internal/gc/main.go

index d8d061136ed8fa2bee2b76e7b42dab8cd52c761f..e123648d7f2a690f54c10e5d8fff164af5c2883f 100644 (file)
@@ -18,6 +18,7 @@ import (
        "flag"
        "fmt"
        "io"
+       "io/ioutil"
        "log"
        "os"
        "path"
@@ -195,6 +196,7 @@ func Main(archInit func(*Arch)) {
        objabi.Flagcount("h", "halt on error", &Debug['h'])
        objabi.Flagcount("i", "debug line number stack", &Debug['i'])
        objabi.Flagfn1("importmap", "add `definition` of the form source=actual to import map", addImportMap)
+       objabi.Flagfn1("importcfg", "read import configuration from `file`", readImportCfg)
        flag.StringVar(&flag_installsuffix, "installsuffix", "", "set pkg directory `suffix`")
        objabi.Flagcount("j", "debug runtime-initialized variables", &Debug['j'])
        objabi.Flagcount("l", "disable inlining", &Debug['l'])
@@ -671,7 +673,10 @@ func writebench(filename string) error {
        return f.Close()
 }
 
-var importMap = map[string]string{}
+var (
+       importMap   = map[string]string{}
+       packageFile map[string]string // nil means not in use
+)
 
 func addImportMap(s string) {
        if strings.Count(s, "=") != 1 {
@@ -685,6 +690,47 @@ func addImportMap(s string) {
        importMap[source] = actual
 }
 
+func readImportCfg(file string) {
+       packageFile = map[string]string{}
+       data, err := ioutil.ReadFile(file)
+       if err != nil {
+               log.Fatalf("-importcfg: %v", err)
+       }
+
+       for lineNum, line := range strings.Split(string(data), "\n") {
+               lineNum++ // 1-based
+               line = strings.TrimSpace(line)
+               if line == "" || strings.HasPrefix(line, "#") {
+                       continue
+               }
+
+               var verb, args string
+               if i := strings.Index(line, " "); i < 0 {
+                       verb = line
+               } else {
+                       verb, args = line[:i], strings.TrimSpace(line[i+1:])
+               }
+               var before, after string
+               if i := strings.Index(args, "="); i >= 0 {
+                       before, after = args[:i], args[i+1:]
+               }
+               switch verb {
+               default:
+                       log.Fatalf("%s:%d: unknown directive %q", file, lineNum, verb)
+               case "importmap":
+                       if before == "" || after == "" {
+                               log.Fatalf(`%s:%d: invalid importmap: syntax is "importmap old=new"`, file, lineNum)
+                       }
+                       importMap[before] = after
+               case "packagefile":
+                       if before == "" || after == "" {
+                               log.Fatalf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)
+                       }
+                       packageFile[before] = after
+               }
+       }
+}
+
 func saveerrors() {
        nsavederrors += nerrors
        nerrors = 0
@@ -745,6 +791,11 @@ func findpkg(name string) (file string, ok bool) {
                        return "", false
                }
 
+               if packageFile != nil {
+                       file, ok = packageFile[name]
+                       return file, ok
+               }
+
                // try .a before .6.  important for building libraries:
                // if there is an array.6 in the array.a library,
                // want to find all of array.a, not just array.6.
@@ -767,6 +818,11 @@ func findpkg(name string) (file string, ok bool) {
                return "", false
        }
 
+       if packageFile != nil {
+               file, ok = packageFile[name]
+               return file, ok
+       }
+
        for _, dir := range idirs {
                file = fmt.Sprintf("%s/%s.a", dir, name)
                if _, err := os.Stat(file); err == nil {
@@ -969,8 +1025,13 @@ func importfile(f *Val) *types.Pkg {
        }
 
        // assume files move (get installed) so don't record the full path
-       // (e.g., for file "/Users/foo/go/pkg/darwin_amd64/math.a" record "math.a")
-       Ctxt.AddImport(file[len(file)-len(path_)-len(pkgSuffix):])
+       if packageFile != nil {
+               // If using a packageFile map, assume path_ can be recorded directly.
+               Ctxt.AddImport(path_)
+       } else {
+               // For file "/Users/foo/go/pkg/darwin_amd64/math.a" record "math.a".
+               Ctxt.AddImport(file[len(file)-len(path_)-len(pkgSuffix):])
+       }
 
        // In the importfile, if we find:
        // $$\n  (textual format): not supported anymore