github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/internal/gc/mkbuiltin.go (about) 1 // Copyright 2009 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 // +build ignore 6 7 // Generate builtin.go from $* (runtime.go and unsafe.go). 8 // Run this after changing runtime.go and unsafe.go 9 // or after changing the export metadata format in the compiler. 10 // Either way, you need to have a working compiler binary first. 11 package main 12 13 import ( 14 "bufio" 15 "fmt" 16 "go/build" 17 "io" 18 "log" 19 "os" 20 "os/exec" 21 "runtime" 22 "strings" 23 ) 24 25 func main() { 26 gochar, err := build.ArchChar(runtime.GOARCH) 27 if err != nil { 28 log.Fatal(err) 29 } 30 31 f, err := os.Create("builtin.go") 32 if err != nil { 33 log.Fatal(err) 34 } 35 defer f.Close() 36 w := bufio.NewWriter(f) 37 38 fmt.Fprintln(w, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT") 39 fmt.Fprintln(w, "") 40 fmt.Fprintln(w, "package gc") 41 42 for _, name := range os.Args[1:] { 43 mkbuiltin(w, gochar, name) 44 } 45 46 if err := w.Flush(); err != nil { 47 log.Fatal(err) 48 } 49 } 50 51 // Compile .go file, import data from .6 file, and write Go string version. 52 func mkbuiltin(w io.Writer, gochar string, name string) { 53 if err := exec.Command("go", "tool", gochar+"g", "-A", "builtin/"+name+".go").Run(); err != nil { 54 log.Fatal(err) 55 } 56 obj := fmt.Sprintf("%s.%s", name, gochar) 57 defer os.Remove(obj) 58 59 r, err := os.Open(obj) 60 if err != nil { 61 log.Fatal(err) 62 } 63 defer r.Close() 64 scanner := bufio.NewScanner(r) 65 66 // Look for $$ that introduces imports. 67 for scanner.Scan() { 68 if strings.Contains(scanner.Text(), "$$") { 69 goto Begin 70 } 71 } 72 log.Fatal("did not find beginning of imports") 73 74 Begin: 75 initfunc := fmt.Sprintf("init_%s_function", name) 76 77 fmt.Fprintf(w, "\nconst %simport = \"\" +\n", name) 78 79 // sys.go claims to be in package PACKAGE to avoid 80 // conflicts during "6g sys.go". Rename PACKAGE to $2. 81 replacer := strings.NewReplacer("PACKAGE", name) 82 83 // Process imports, stopping at $$ that closes them. 84 for scanner.Scan() { 85 p := scanner.Text() 86 if strings.Contains(p, "$$") { 87 goto End 88 } 89 90 // Chop leading white space. 91 p = strings.TrimLeft(p, " \t") 92 93 // Cut out decl of init_$1_function - it doesn't exist. 94 if strings.Contains(p, initfunc) { 95 continue 96 } 97 98 fmt.Fprintf(w, "\t%q +\n", replacer.Replace(p)+"\n") 99 } 100 log.Fatal("did not find end of imports") 101 102 End: 103 fmt.Fprintf(w, "\t\"$$\\n\"\n") 104 }